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

Go to the SVN repository for this file.

1 /* $Id: phylo_tree_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: Vladimir Tereshkov
27  *
28  * File Description:
29  *
30  */
31 
32 #include <ncbi_pch.hpp>
34 
35 #include <corelib/ncbitime.hpp>
37 
38 #include <gui/opengl/glfont.hpp>
39 #include <gui/types.hpp>
40 #include <gui/utils/view_event.hpp>
45 #include "save_tree_pdf_dlg.hpp"
47 
53 
60 
61 #include <gui/opengl/glresmgr.hpp>
62 #include <gui/opengl/irender.hpp>
70 
76 
83 #include <objects/biotree/Node.hpp>
84 
85 #include <util/image/image.hpp>
86 #include <util/image/image_io.hpp>
87 
88 #include <wx/settings.h>
89 #include <wx/msgdlg.h>
90 #include <wx/filedlg.h>
91 #include <wx/textctrl.h>
92 #include <wx/tglbtn.h>
93 #include <wx/printdlg.h>
94 #include <wx/cmndata.h>
95 
96 #include <list>
97 
98 #include <wx/menu.h>
99 
101 
102 
103 //static const char* kLayout = "Layout";
104 //static const char* kScrollMode = "Scroll Mode";
105 //static const char* kPhyloTree = ".PhyloTree";
106 
107 
108 ////////////////////////////////////////////////////////////////////////////////
109 /// class CPhyloTreeWidget
111  wxFileArtProvider& /* provider */)
112 {
113  static bool initialized = false;
114  if (initialized)
115  return;
116  initialized = true;
117 
118  cmd_reg.RegisterCommand(eCmdEditLabel, "Edit Label", "Edit Label", "", "");
119  cmd_reg.RegisterCommand(eCmdEditNode, "Properties", "Properties", "", "");
120 
121  cmd_reg.RegisterCommand(eCmdNodeCut, "Cut", "Cut", "", "");
122  cmd_reg.RegisterCommand(eCmdNodePaste, "Paste", "Paste", "", "");
123  cmd_reg.RegisterCommand(eCmdMoveUp, "Move Up", "Move Up", "", "");
124  cmd_reg.RegisterCommand(eCmdMoveDown, "Move Down", "Move Down", "", "");
125 
126  cmd_reg.RegisterCommand(eCmdNodeNewChild, "New Child", "New Child", "", "");
127  cmd_reg.RegisterCommand(eCmdNodeNewParent, "New Parent", "New Parent", "", "");
128 
129  cmd_reg.RegisterCommand(eCmdRemoveSubtree, "Subtree", "Subtree", "", "");
130  cmd_reg.RegisterCommand(eCmdRemoveSelected, "Selected", "Selected", "", "");
131  cmd_reg.RegisterCommand(eCmdRemoveNode, "Node", "Node", "", "");
132 
133  cmd_reg.RegisterCommand(eCmdExportSelected, "Save Selected to Newick file...", "Save Selected to Newick file...", "", "");
134  cmd_reg.RegisterCommand(eCmdFilter, "Display the subtree", "Display the subtree", "", "");
135  cmd_reg.RegisterCommand(eCmdSubtreeFromSelected, "Create Subtree from Selected Nodes", "Create Subtree from Selected Nodes", "", "");
136  cmd_reg.RegisterCommand(eCmdSort, "Sort by Number of Children", "Sort by Number of Children", "", "");
137  cmd_reg.RegisterCommand(eCmdSortDist, "Sort by Distance", "Sort by Distance", "", "");
138  cmd_reg.RegisterCommand(eCmdSortLabel, "Sort by Label", "Sort by Label", "", "");
139  cmd_reg.RegisterCommand(eCmdSortLabelRange, "Sort by Subtree Labels", "Sort by Subtree Labels", "", "");
140  cmd_reg.RegisterCommand(eCmdSortAscending, "Sort in Ascending Order", "Sort in Ascending Order", "", "", "", "", wxITEM_CHECK);
141 
143  "Rectangle Cladogram", "Rectangle Cladogram", "", "", "", "", wxITEM_RADIO);
145  "Slanted Cladogram", "Slanted Cladogram", "", "", "", "", wxITEM_RADIO);
147  "Radial Tree", "Radial Tree", "", "", "", "", wxITEM_RADIO);
149  "Force Layout", "Force Layout", "", "", "", "", wxITEM_RADIO);
151  "Circular Layout", "Circular Layout", "", "", "", "", wxITEM_RADIO);
153  "Rotate Labels", "Rotate Labels", "", "", "", "", wxITEM_CHECK);
155  "Stop Layout", "Stop Layout", "", "", "", "", wxITEM_NORMAL);
157  "Use Distances", "Use Distances", "", "", "", "", wxITEM_CHECK);
158 
159  cmd_reg.RegisterCommand(eCmdZoomXY,
160  "Proportional", "Proportional", "", "", "", "", wxITEM_RADIO);
161  cmd_reg.RegisterCommand(eCmdZoomY,
162  "Vertical", "Vertical", "", "", "", "", wxITEM_RADIO);
163  cmd_reg.RegisterCommand(eCmdZoomX,
164  "Horizontal", "Horizontal", "", "", "", "", wxITEM_RADIO);
165 
166  cmd_reg.RegisterCommand(eCmdRerootTree, "Make this Root", "Make this Root", "", "");
167  cmd_reg.RegisterCommand(eCmdRerootTreeAtEdge, "Place Root at Middle of Branch", "Place Root at Middle of Branch", "", "");
168  cmd_reg.RegisterCommand(eCmdMidpointRoot, "Set Midpoint Root", "Set Midpoint Root", "", "");
170  "Re-root and show only child nodes", "Re-root and show only child nodes", "menu::zoom_all", "");
171 
172 
174  "For Leaves Only", "For Leaves Only", "", "", "", "", wxITEM_RADIO);
176  "Show All", "Show All", "", "", "", "", wxITEM_RADIO);
178  "Hide All", "Hide All", "", "", "", "", wxITEM_RADIO);
179 
180  cmd_reg.RegisterCommand(eCmdSetTreeLabel, "Set Tree Label", "Set Tree Label", "", "");
181 
182  cmd_reg.RegisterCommand(eCmdAlNone, "None", "None", "", "", "", "", wxITEM_RADIO);
183  cmd_reg.RegisterCommand(eCmdAlPhylip, "Phylip-Style", "Phylip-Style", "", "", "", "", wxITEM_RADIO);
184  cmd_reg.RegisterCommand(eCmdAlPaml, "PAML-Style", "PAML-Style", "", "", "", "", wxITEM_RADIO);
185 
186  cmd_reg.RegisterCommand(eCmdShowAll, "Expand All", "Expand All", "", "");
187  cmd_reg.RegisterCommand(eCmdCollapseChildren, "Collapse", "Collapse", "", "");
188  cmd_reg.RegisterCommand(eCmdCollapseSelected, "Collapse Selected", "Collapse Selected", "", "");
189  cmd_reg.RegisterCommand(eCmdExpandChildren, "Expand", "Expand", "", "");
190  cmd_reg.RegisterCommand(eCmdHighlightEdges, "Highlight Longer Edges", "Highlight Longer Edges", "", "", "", "", wxITEM_CHECK);
191  cmd_reg.RegisterCommand(eCmdCollapseToViewport, "Collapse Tree to fit Viewport", "Collapse Tree to fit Viewport", "", "", "", "", wxITEM_CHECK);
192 
193  cmd_reg.RegisterCommand(eSelectAll, "Select All", "Select All", "", "");
194  cmd_reg.RegisterCommand(eClearSelection, "Clear Selection", "Clear Selection", "", "");
195  cmd_reg.RegisterCommand(eCmdAddSelectionSet, "Update Selection Sets", "Update Selection Sets", "", "");
196  cmd_reg.RegisterCommand(eCmdExportSelection, "Export Selection to CSV...", "Export Selection to CSV...", "", "");
197  cmd_reg.RegisterCommand(eCmdExportTree, "Export Tree...", "Export Tree to Newick/Nexus...", "", "");
198 
199  cmd_reg.RegisterCommand(eCmdClean, "Delete Single-Child Nodes", "Delete Single-Child Nodes", "", "");
200  cmd_reg.RegisterCommand(eCmdFilterDistances, "Distance Filtering...", "Distance Filtering...", "", "");
201 
202  cmd_reg.RegisterCommand(eCmdUseSplines, "Use Splines", "Use Splines", "", "", "", "", wxITEM_CHECK);
203 
204  cmd_reg.RegisterCommand(eCmdMySettings, "Settings...", "Settings...", "", "");
205 
206  cmd_reg.RegisterCommand(eCmdLoadAttributes, "Load Attributes...", "Attributes...", "", "");
207 }
208 
209 CPhyloTreeWidget::CPhyloTreeWidget(wxWindow* parent, wxWindowID id,
210  const wxPoint& pos, const wxSize& size, long style,
211  const wxString& name)
212 : CGlWidgetBase(parent, id, pos, size, style, name)
213 , m_pPhyloTreePane(NULL)
214 , m_QueryPanel(NULL)
215 , m_SortAscending(false)
216 , m_LastCommand(EPhyloTreeEditCommand::eEditCmdNone)
217 , m_PrevPos(0.0f, 0.0f)
218 {
219  // setup Port
221  m_Port.SetMinScaleX(1 / 1000.0);
222  m_Port.SetMinScaleY(1 / 1000.0);
224  m_Port.EnableZoom(true, true);
225 }
226 
228 {
229  if (m_QueryPanel) {
231  delete m_QueryPanel;
232  }
233 }
234 
235 static
236 WX_DEFINE_MENU(sPopupMenu)
239  WX_SUBMENU("Edit")
240  WX_SUBMENU("Move")
247  WX_SUBMENU("Add")
251  WX_SUBMENU("Remove")
258 
260  WX_SUBMENU("Sort")
268 
270  WX_SUBMENU("Layout")
275  //WX_MENU_ITEM(eCmdSetGraphType4)
283 
284  WX_SUBMENU("Zoom")
290 
291  WX_SUBMENU("Zoom Behavior")
296 
297  WX_SUBMENU("Re-root")
303 
304  WX_SUBMENU("Label Visibility")
309  WX_SUBMENU("Auto-Labeling")
315 
317 
319 
326 
328 
334 
336 
340 
341 WX_END_MENU()
342 
343 BEGIN_EVENT_TABLE(CPhyloTreeWidget, CGlWidgetBase)
344  EVT_MENU(wxID_PRINT, CPhyloTreeWidget::OnPrint)
345  EVT_UPDATE_UI(wxID_PRINT, CPhyloTreeWidget::OnEnablePrintCmdUpdate)
347  EVT_UPDATE_UI(eCmdSaveImages, CPhyloTreeWidget::OnEnableSaveImagesCmdUpdate)
349  EVT_UPDATE_UI(eCmdSavePdf, CPhyloTreeWidget::OnEnableSavePdfCmdUpdate)
350 
351  EVT_CONTEXT_MENU(CPhyloTreeWidget::OnContextMenu)
352 
353  EVT_MENU(eCmdSetGraphType1, CPhyloTreeWidget::OnSetGraphType1)
354  EVT_MENU(eCmdSetGraphType2, CPhyloTreeWidget::OnSetGraphType2)
355  EVT_MENU(eCmdSetGraphType3, CPhyloTreeWidget::OnSetGraphType3)
356  EVT_MENU(eCmdSetGraphType4, CPhyloTreeWidget::OnSetGraphType4)
357  EVT_MENU(eCmdSetGraphType5, CPhyloTreeWidget::OnSetGraphType5)
358  EVT_MENU(eCmdUseDistances, CPhyloTreeWidget::OnUseDistances)
359  EVT_MENU(eCmdRotateLabels, CPhyloTreeWidget::OnRotateLabels)
362  EVT_MENU(eCmdMySettings, CPhyloTreeWidget::OnOpenPropertiesDlg)
364  EVT_MENU(eCmdRerootTreeAtEdge, CPhyloTreeWidget::OnRerootTreeAtEdge)
365  EVT_MENU(eCmdMidpointRoot, CPhyloTreeWidget::OnSetMidpointRoot)
366  EVT_MENU(eCmdLoadAttributes,CPhyloTreeWidget::OnLoadAttributes)
367 
369  EVT_UPDATE_UI(eCmdEditNode, CPhyloTreeWidget::OnUpdateEditNode)
370 
371  EVT_MENU(eCmdFilterDistances, CPhyloTreeWidget::OnFilterDistances)
372 
373  EVT_MENU(eSelectAll, CPhyloTreeWidget::OnSelectAll)
374  EVT_MENU(eClearSelection, CPhyloTreeWidget::OnClearSelection)
375  EVT_MENU(eCmdAddSelectionSet, CPhyloTreeWidget::OnAddSelectionSet)
376  EVT_MENU(eCmdExportSelection, CPhyloTreeWidget::OnExportSelection)
378 
379  EVT_MENU(eCmdCollapseChildren, CPhyloTreeWidget::OnCollapseChildren)
380  EVT_MENU(eCmdExpandChildren, CPhyloTreeWidget::OnExpandChildren)
381  EVT_MENU(eCmdCollapseSelected, CPhyloTreeWidget::OnCollapseSelected)
382  EVT_MENU(eCmdHighlightEdges, CPhyloTreeWidget::OnHighlightEdges)
383  EVT_MENU(eCmdCollapseToViewport, CPhyloTreeWidget::OnCollapseToViewport)
384 
385  EVT_MENU(eCmdZoomToSubtree, CPhyloTreeWidget::OnZoomToSubtree)
386  EVT_UPDATE_UI(eCmdZoomToSubtree, CPhyloTreeWidget::OnUpdateZoomToSubtree)
387 
389  EVT_UPDATE_UI(eCmdShowAll, CPhyloTreeWidget::OnUpdateShowAll)
390 
391  EVT_UPDATE_UI(eCmdCollapseChildren, CPhyloTreeWidget::OnUpdateCollapseChildren)
392  EVT_UPDATE_UI(eCmdExpandChildren, CPhyloTreeWidget::OnUpdateExpandChildren)
393  EVT_UPDATE_UI(eCmdCollapseSelected, CPhyloTreeWidget::OnUpdateCollapseSelected)
394 
395  EVT_UPDATE_UI(eCmdRerootTree, CPhyloTreeWidget::OnUpdateRerootTree)
396  EVT_UPDATE_UI(eCmdRerootTreeAtEdge, CPhyloTreeWidget::OnUpdateRerootTreeAtEdge)
397  EVT_UPDATE_UI(eCmdMidpointRoot, CPhyloTreeWidget::OnUpdateSetMidpointRoot)
398  EVT_UPDATE_UI(eCmdRotateLabels, CPhyloTreeWidget::OnUpdateRotateLabels)
399  EVT_UPDATE_UI(eCmdStopLayout, CPhyloTreeWidget::OnUpdateStopLayout)
400  EVT_UPDATE_UI(eCmdUseDistances, CPhyloTreeWidget::OnUpdateUseDistances)
401  EVT_UPDATE_UI(eCmdSortAscending, CPhyloTreeWidget::OnUpdateSortAscending)
402  EVT_UPDATE_UI(eCmdUseSplines, CPhyloTreeWidget::OnUpdateUseSplines)
403  EVT_UPDATE_UI(eCmdSetGraphType1, CPhyloTreeWidget::OnUpdateSetGraphType1)
404  EVT_UPDATE_UI(eCmdSetGraphType2, CPhyloTreeWidget::OnUpdateSetGraphType2)
405  EVT_UPDATE_UI(eCmdSetGraphType3, CPhyloTreeWidget::OnUpdateSetGraphType3)
406  EVT_UPDATE_UI(eCmdSetGraphType4, CPhyloTreeWidget::OnUpdateSetGraphType4)
407  EVT_UPDATE_UI(eCmdSetGraphType5, CPhyloTreeWidget::OnUpdateSetGraphType5)
408 
410  EVT_UPDATE_UI(eCmdZoomXY, CPhyloTreeWidget::OnUpdateZoomXY)
412  EVT_UPDATE_UI(eCmdZoomX, CPhyloTreeWidget::OnUpdateZoomX)
414  EVT_UPDATE_UI(eCmdZoomY, CPhyloTreeWidget::OnUpdateZoomY)
415  EVT_MENU(eCmdZoomSel, CPhyloTreeWidget::OnZoomToSelection)
417  EVT_MENU(eCmdForward, CPhyloTreeWidget::OnGoForward)
418  EVT_UPDATE_UI(eCmdBack, CPhyloTreeWidget::OnUpdateGoBack)
419  EVT_UPDATE_UI(eCmdForward, CPhyloTreeWidget::OnUpdateGoForward)
420  EVT_UPDATE_UI(eCmdZoomSel, CPhyloTreeWidget::OnUpdateZoomSel)
421 
426  EVT_MENU(eCmdSortAscending, CPhyloTreeWidget::OnSortAscending)
427 
430 
433 
434  EVT_MENU(eCmdSetTreeLabel, CPhyloTreeWidget::OnSetTreeLabel)
435 
438 
441 
443  EVT_UPDATE_UI(eCmdEditLabel, CPhyloTreeWidget::OnUpdateEditLabel)
444 
445  EVT_MENU(eCmdSubtreeFromSelected, CPhyloTreeWidget::OnSubtreeFromSelection)
446  EVT_UPDATE_UI(eCmdSubtreeFromSelected, CPhyloTreeWidget::OnUpdateSubtreeFromSelection)
447 
448  EVT_BUTTON(eCmdSearchTip, CPhyloTreeWidget::OnSearchTip)
449  EVT_BUTTON(eCmdZoomTip, CPhyloTreeWidget::OnZoomTip)
450  EVT_BUTTON(eCmdInfoTip, CPhyloTreeWidget::OnInfoTip)
451  EVT_BUTTON(eCmdTipActive, CPhyloTreeWidget::OnTipActivated)
452  EVT_BUTTON(eCmdTipInactive, CPhyloTreeWidget::OnTipDeactivated)
453 
455 
456 void CPhyloTreeWidget::x_CreateControls()
457 {
458 #ifdef CRASH_DEBUG
459  wxMessageBox(wxT("CPhyloTreeWidget::x_CreateControls()"), wxT(""), wxICON_WARNING | wxOK);
460 #endif
461  // Make sure we have loaded needed bitmaps:
462  static bool first_tree_window = false;
463  if( !first_tree_window ){
465  first_tree_window = true;
466 
467  provider->RegisterFileAlias(wxT("menu::dm_start"), wxT("playhs.png"));
468  provider->RegisterFileAlias(wxT("menu::dm_stop"), wxT("stophs.png"));
469  provider->RegisterFileAlias(wxT("menu::back"), wxT("back.png"));
470  provider->RegisterFileAlias(wxT("menu::forward"), wxT("forward.png"));
471  provider->RegisterFileAlias(wxT("menu::help"), wxT("help.png"));
472  }
473 
475 }
476 
478 {
479  m_QueryPanel = queryPanel;
481 }
482 
483 void CPhyloTreeWidget::OnContextMenu(wxContextMenuEvent& event)
484 {
485  wxPoint ms_pos = ScreenToClient(event.GetPosition());
486 
489 
491  unique_ptr<wxMenu> menu(cmd_reg.CreateMenu(sPopupMenu));
492  PopupMenu(menu.get());
493 }
494 
495 
497 {
498  m_pPopupItems = itm;
499 }
500 
502 {
503  m_pPhyloTreePane = new CPhyloTreePane(this);
504 
505  // defauld model space for renderer
506  double w = 2000.;
507  double h = 2000.;
508 
514 }
515 
516 
518 {
519  return static_cast<CGlWidgetPane*>(m_pPhyloTreePane);
520 }
521 
522 
524 {
525  if (m_pPhyloTreePane) {
526  double DimX = m_pPhyloTreePane->GetCurrRenderer()->GetDimX();
527  double DimY = m_pPhyloTreePane->GetCurrRenderer()->GetDimY();
528  m_Port.SetModelLimitsRect(TModelRect(0, 0, DimX, DimY));
529  }
530 }
531 
532 void CPhyloTreeWidget::SetPortLimits(const TModelRect & rect, bool bZoomAll)
533 {
534  const TModelRect mr = m_Port.GetModelLimitsRect();
536 
537  double scale_factor = std::max(50.0, (double)(m_DataSource->GetNumNodes()/8));
538 
539  m_Port.SetMinScaleX(m_Port.GetZoomAllScaleX() / scale_factor);
540  m_Port.SetMinScaleY(m_Port.GetZoomAllScaleY() / scale_factor);
541 
542  if (bZoomAll) {
543  m_Port.ZoomAll();
544  }
545  else {
546  TModelUnit sx = (rect.Width() / mr.Width());
547  TModelUnit sy = (rect.Height() / mr.Height());
548 
550  x_UpdateOnZoom();
551  }
552 }
553 
555 {
556  m_DataSource = p_ds;
557 
559 
560  if (m_QueryPanel != NULL) {
562  }
563 
564  double scale_factor = std::max(50.0, (double)(p_ds->GetNumNodes()/8));
565  m_Port.SetMinScaleX(m_Port.GetZoomAllScaleX() / scale_factor);
566  m_Port.SetMinScaleY(m_Port.GetZoomAllScaleY() / scale_factor);
567 }
568 
570 {
571  if (m_QueryPanel != NULL) {
573  }
574 
575  double scale_factor = std::max(50.0, (double)(p_ds->GetNumNodes()/8));
576  m_Port.SetMinScaleX(m_Port.GetZoomAllScaleX() / scale_factor);
577  m_Port.SetMinScaleY(m_Port.GetZoomAllScaleY() / scale_factor);
578 
579  if (!m_DataSource){
580  m_DataSource = p_ds;
581  x_Update();
582  }
583  else {
584  m_DataSource = p_ds;
585  x_SoftUpdate();
586  }
587 }
588 
590 {
591  if (!m_DataSource.IsNull())
592  m_DataSource->Clear();
593 
594  if (m_pPhyloTreePane) {
596  }
597 
598  if (m_QueryPanel != NULL) {
600  }
601 }
602 
604 {
605  // re-compute tree characteristics (such as children per-node)
606  if (m_DataSource != NULL) {
609 
610  // layout tree
611  x_SoftUpdate();
612 
613  // Redraw tree
614  m_pPhyloTreePane->Refresh();
615  // Recenter view on expand/colllapse
617 
618  // After expand/collapse, scroll view so that expanded/collapsed node remains
619  // at it's same position (otherwise can lose node after expand/collapse)
621  if (idx != CPhyloTree::Null()) {
622  CPhyloTree::TNodeType& current =
624 
626  float pctx = (node_screen_pos.X() - float(m_PrevPane.GetViewport().Left())) / float(m_PrevPane.GetViewport().Width());
627  float pcty = (node_screen_pos.Y() - float(m_PrevPane.GetViewport().Bottom())) / float(m_PrevPane.GetViewport().Height());
628 
631 
632  // Keep visible rect in same relative proportions after collapsing
633  CGlPane& pane = GetPort(); //There is also m_pPhyloTreePane->GetPane(); but local pane is used for visible rect...
634  pane.SetProportional(vr, mr);
635 
636  // Scroll viewport to keep newly collapsed/expanded node in same relative position
637  CVect2<float> pos = current.GetValue().XY();
638  pane.ScrollTo(CVect2<TModelUnit>(pos.X(), pos.Y()), pctx, pcty);
639  }
640 
642  }
643  }
644 }
645 
647 {
648  return m_DataSource;
649 }
650 
651 
653 {
654  return m_Port;
655 }
656 
657 
659 {
660  return m_Port;
661 }
662 
663 void CPhyloTreeWidget::OnPrint(wxCommandEvent& /* evt */)
664 {
666 
667  size_t w = m_pPhyloTreePane->GetPane().GetViewport().Width();
668  size_t h = m_pPhyloTreePane->GetPane().GetViewport().Height();
669 
670  // create the CImage
671  CRef<CImage> img(new CImage(w, h, 3));
672 
673  //_TRACE("Size (w,h,buf): (" << w << ", " << h << ", " << image_size << ")");
674 
675  // Read using single-byte alignment
676  GLint alignment;
677  glGetIntegerv(GL_PACK_ALIGNMENT, &alignment);
678  glPixelStorei(GL_PACK_ALIGNMENT, 1);
679  glReadPixels(0, 0, static_cast<GLsizei>(w), static_cast<GLsizei>(h), GL_RGB, GL_UNSIGNED_BYTE, img->SetData());
680  glPixelStorei(GL_PACK_ALIGNMENT, alignment);
681  img->Flip();
682 
683  //wxImage wximg(img->GetWidth(),
684  // img->GetHeight(),
685  // (unsigned char*)img->GetData(), true);
686  //wximg.SaveFile(wxT("c:\\temp\\image_save1.bmp"),wxBITMAP_TYPE_BMP);
687 
688  CPrintHanderWx print_handler(img,
689  1 /*1 page */,
690  wxT("Print Test"),
691  30 /* units per centimeter*/);
692 
693  print_handler.SetImage(img);
694 
695 
696  //QuickPrint* myprint = new QuickPrint( 5 /* 5 pages */,
697  // wxT("wxPrint test"),
698  // 30 /* 30 units per centimeter */ );
699  if (!print_handler.performPageSetup(true))
700  {
701  // user cancelled
702  return;
703  }
704 
705  wxPrintDialogData data(print_handler.getPrintData());
706  wxPrinter printer(&data);
707  const bool success = printer.Print(NULL, &print_handler, true /* show dialog */);
708 
709 
710  if (!success)
711  {
712  std::cerr << "Failed!!\n";
713  return;
714  }
715 }
716 
717 void CPhyloTreeWidget::OnEnablePrintCmdUpdate(wxUpdateUIEvent& event)
718 {
719  // disable until print works correctly.
720  event.Enable(false);
721 }
722 
723 void CPhyloTreeWidget::OnSaveImages(wxCommandEvent& /* evt */)
724 {
726  float xsize, ysize;
727  I3DTexture* pTexture = m_pPhyloTreePane->MMHH_GetTexture(xsize, ysize);
728  CRef<CImage> img;
729  if (pTexture) {
730  img.Reset(pTexture->GenerateImage());
731  if (img && (xsize != 1.0f || ysize != 1.0f))
732  img.Reset(img->GetSubImage(0, 0, (size_t)(xsize*img->GetWidth()), (size_t)(ysize*img->GetHeight())));
733  }
734 
735  if (!img) {
736  size_t w = m_pPhyloTreePane->GetPane().GetViewport().Width();
737  size_t h = m_pPhyloTreePane->GetPane().GetViewport().Height();
738  img.Reset(new CImage(w, h, 3));
739  }
740 
743  CSaveImagesSetupDlg dlg(img, &grb, this);
748 
749  dlg.ShowModal();
750  DlgOverlayFix(this);
751 }
752 
754 {
755 #ifdef USE_METAL
756  event.Enable(false);
757 #else
758  event.Enable(true);
759 #endif
760 }
761 
762 void CPhyloTreeWidget::OnSavePdf(wxCommandEvent & evt)
763 {
764  CSaveTreePdfDlg tree_pdf_dlg(m_pPhyloTreePane, this);
765  tree_pdf_dlg.ShowModal();
766  DlgOverlayFix(this);
767 }
768 
770 {
771  evt.Enable(true);
772 }
773 
774 void CPhyloTreeWidget::OnSetEqualScale(wxCommandEvent& /* evt */)
775 {
777  m_Port.SetScale(scale, scale);
778  x_UpdateOnZoom();
779 }
780 
781 // zoom behavior
782 void CPhyloTreeWidget::OnZoomXY(wxCommandEvent& /* evt */)
783 {
784  // Set layout-specific zoom behavior
787 
788  CGlPane& port = GetPort();
789 
790  /// With proportional zoom, visible region must be in
791  /// same proportion of limits rect, so if it isn't, update
792  /// the scale to be equal be reducing the larger dimension.
793  TModelRect v = port.GetVisibleRect();
795  TModelRect new_rect = v;
796 
797  double limits_ratio = l.Width()/l.Height();
798  double visible_ratio = v.Width()/v.Height();
799 
800  if (visible_ratio == limits_ratio) {
801  return;
802  }
803  else if (visible_ratio < limits_ratio) {
804  double target_width = l.Width()*(v.Height()/l.Height());
805  double center = (v.Left()+v.Right())/2.0;
806  new_rect.SetLeft(center - target_width/2.0);
807  new_rect.SetRight(center + target_width/2.0);
808  }
809  else if (visible_ratio > limits_ratio) {
810  double target_height = l.Height()*(v.Width()/l.Width());
811  double center = (v.Top()+v.Bottom())/2.0;
812  new_rect.SetBottom(center - target_height/2.0);
813  new_rect.SetTop(center + target_height/2.0);
814  }
815 
816  port.ZoomRect(new_rect);
817  m_pPhyloTreePane->GetPane() = port;
818  x_UpdateOnZoom();
819 
820  x_SoftUpdate();
821  Refresh();
822 }
823 
824 void CPhyloTreeWidget::OnZoomX(wxCommandEvent& /* evt */)
825 {
827  return;
828 
831 
832  x_UpdateOnZoom();
833  x_SoftUpdate();
834  Refresh();
835 }
836 
837 void CPhyloTreeWidget::OnZoomY(wxCommandEvent& /* evt */)
838 {
840  return;
841 
844 
845  x_SoftUpdate();
846  Refresh();
847 }
848 
849 void CPhyloTreeWidget::OnZoomToSelection(wxCommandEvent& /* evt */)
850 {
851  CVect2<float> min_pos;
852  CVect2<float> max_pos;
853 
854  if (m_DataSource->GetTree()->GetSelectedBoundary(min_pos, max_pos)) {
855  TModelRect sel_rect;
856 
857  sel_rect.Init(min_pos.X(), min_pos.Y(), max_pos.X(), max_pos.Y());
858 
859  TModelUnit def_node_size = (TModelUnit)
861 
862  sel_rect.Inflate(def_node_size, def_node_size);
863  // We ignore labels here, so selected labals may fall ouside of visible area
864 
867 
868  if (zb == CPhyloTreeScheme::eZoomX) {
869  // Only update X:
870  TModelRect vis_rect = GetPort().GetVisibleRect();
871  sel_rect.SetTop(vis_rect.Top());
872  sel_rect.SetBottom(vis_rect.Bottom());
873  }
874  else if (zb == CPhyloTreeScheme::eZoomY) {
875  // Only update Y:
876  TModelRect vis_rect = GetPort().GetVisibleRect();
877  sel_rect.SetLeft(vis_rect.Left());
878  sel_rect.SetRight(vis_rect.Right());
879  }
880 
881  ZoomRect(sel_rect);
882 
883  x_UpdateOnZoom();
884  }
885 }
886 
887 void CPhyloTreeWidget::OnGoBack(wxCommandEvent& /*evt*/)
888 {
890  x_UpdateOnZoom();
891 }
892 
893 void CPhyloTreeWidget::OnGoForward(wxCommandEvent& /*evt*/)
894 {
896  x_UpdateOnZoom();
897 }
898 
899 void CPhyloTreeWidget::OnUpdateGoBack(wxUpdateUIEvent& event)
900 {
901  event.Enable(m_pPhyloTreePane->CanGoBack());
902 }
903 
904 void CPhyloTreeWidget::OnUpdateGoForward(wxUpdateUIEvent& event)
905 {
906  event.Enable(m_pPhyloTreePane->CanGoForward());
907 }
908 
909 void CPhyloTreeWidget::OnUpdateZoomXY(wxUpdateUIEvent& evt)
910 {
913 }
914 
915 void CPhyloTreeWidget::OnUpdateZoomX(wxUpdateUIEvent& evt)
916 {
919 }
920 
921 void CPhyloTreeWidget::OnUpdateZoomY(wxUpdateUIEvent& evt)
922 {
925 }
926 
927 void CPhyloTreeWidget::OnUpdateZoomSel(wxUpdateUIEvent& evt)
928 {
929  // only allow selection zoom if one or more nodes are selected
930  if ( m_DataSource->GetTree()->HasSelection() )
931  evt.Enable(true);
932  else
933  evt.Enable(false);
934 
935 }
936 
937 void CPhyloTreeWidget::OnSetGraphType1(wxCommandEvent& /* evt */)
938 {
939  SetCurrRenderer(0);
940 }
941 
942 
943 void CPhyloTreeWidget::OnSetGraphType2(wxCommandEvent& /* evt */)
944 {
945  SetCurrRenderer(1);
946 }
947 
948 void CPhyloTreeWidget::OnSetGraphType3(wxCommandEvent& /* evt */)
949 {
950  SetCurrRenderer(2);
951 }
952 
953 void CPhyloTreeWidget::OnSetGraphType4(wxCommandEvent& /* evt */)
954 {
955  SetCurrRenderer(3);
956 }
957 
958 void CPhyloTreeWidget::OnSetGraphType5(wxCommandEvent& /* evt */)
959 {
960  SetCurrRenderer(4);
961 }
962 
963 void CPhyloTreeWidget::OnUpdateSetGraphType1(wxUpdateUIEvent& evt)
964 {
965  evt.Check(m_pPhyloTreePane->GetCurrRendererIdx()==0);
966 }
967 
968 
969 void CPhyloTreeWidget::OnUpdateSetGraphType2(wxUpdateUIEvent& evt)
970 {
971  evt.Check(m_pPhyloTreePane->GetCurrRendererIdx()==1);
972 }
973 
974 
975 void CPhyloTreeWidget::OnUpdateSetGraphType3(wxUpdateUIEvent& evt)
976 {
977  evt.Check(m_pPhyloTreePane->GetCurrRendererIdx()==2);
978 }
979 
980 
981 void CPhyloTreeWidget::OnUpdateSetGraphType4(wxUpdateUIEvent& evt)
982 {
983  evt.Check(m_pPhyloTreePane->GetCurrRendererIdx()==3);
984 }
985 
986 void CPhyloTreeWidget::OnUpdateSetGraphType5(wxUpdateUIEvent& evt)
987 {
988  evt.Check(m_pPhyloTreePane->GetCurrRendererIdx()==4);
989 }
990 
991 void CPhyloTreeWidget::OnRotateLabels(wxCommandEvent& /* evt */)
992 {
994  for (auto &renderer : vRend) {
995  if (!renderer->SupportsRotatedLabels())
996  continue;
997  renderer->SetRotatedLabels(!renderer->GetRotatedLabels());
998  }
999 
1000  // This event saves the rendering options for the tree in the biotreecontainer.
1001  // only called for options that we want to save with the tree itself.
1003  Send(&evt, ePool_Parent);
1004 
1005  x_SoftUpdate();
1006 }
1007 
1008 
1009 void CPhyloTreeWidget::OnUpdateRotateLabels(wxUpdateUIEvent& evt)
1010 {
1011  evt.Enable(false);
1013  return;
1014  }
1015 
1017  evt.Enable(r->SupportsRotatedLabels());
1018  evt.Check(r->GetRotatedLabels());
1019 }
1020 
1022 {
1023  bool update_layout = false;
1024 
1027  update_layout = true;
1028  }
1029 
1031  for (auto &renderer : vRend) {
1032  if (renderer->SupportsRotatedLabels() && renderer->GetRotatedLabels() != rot) {
1033  renderer->SetRotatedLabels(rot);
1034  }
1035  }
1036 
1037  // If we changed the option for the current layout, update:
1038  if (update_layout)
1039  x_SoftUpdate();
1040 }
1041 
1043 {
1044  // Get value from first renderer that supports it (the are currently
1045  // all set on/off together)
1047  for (auto &renderer : vRend) {
1048  if (renderer->SupportsRotatedLabels())
1049  return renderer->GetRotatedLabels();
1050  }
1051 
1052  return false;
1053 }
1054 
1055 void CPhyloTreeWidget::OnStopLayout(wxCommandEvent& /* evt */)
1056 {
1058  return;
1059 
1061 
1062  CPhyloForce* rforce = dynamic_cast<CPhyloForce*>(r);
1063  if (rforce) {
1064  rforce->StopLayout();
1065  }
1066 }
1067 
1068 
1069 void CPhyloTreeWidget::OnUpdateStopLayout(wxUpdateUIEvent& evt)
1070 {
1071  evt.Enable(false);
1072 
1074  return;
1075  }
1076 
1078 
1079  CPhyloForce* rforce = dynamic_cast<CPhyloForce*>(r);
1080  if (rforce) {
1081  evt.Enable(true);
1082  }
1083 }
1084 
1085 void CPhyloTreeWidget::OnUseDistances(wxCommandEvent& /* evt */)
1086 {
1088  if (vRend.empty())
1089  return;
1090 
1091  SetUseDistances(!(*vRend.begin())->GetDistRendering());
1092 
1093  // This event saves the rendering options for the tree in the biotreecontainer.
1094  // only called for options that we want to save with the tree itself.
1096  Send(&evt, ePool_Parent);
1097 
1098  x_SoftUpdate();
1099 }
1100 
1102 {
1104  for (auto &renderer : vRend) {
1105  renderer->SetDistRendering(bDist && renderer->SupportsDistanceRendering());
1106  }
1107 }
1108 
1110 {
1111  // The first renderer (rect cladogram) supports distance rendering so
1112  // get value from there. (for renderers that don't support it, value
1113  // is always false).
1115  if (vRend.empty())
1116  return true;
1117 
1118  return (*vRend.begin())->GetDistRendering();
1119 }
1120 
1121 void CPhyloTreeWidget::OnUpdateUseDistances(wxUpdateUIEvent& evt)
1122 {
1126  return;
1127  }
1128 
1130  if (vRend.empty())
1131  return;
1132 
1133  evt.Check((*vRend.begin())->GetDistRendering());
1134 }
1135 
1136 void CPhyloTreeWidget::OnUseSplines(wxCommandEvent& /* evt */)
1137 {
1139  for (auto &renderer : vRend) {
1140  renderer->SetSplinesRendering(!renderer->GetSplinesRendering());
1141  }
1142  x_SoftUpdate();
1143 }
1144 
1145 
1146 void CPhyloTreeWidget::OnUpdateUseSplines(wxUpdateUIEvent& evt)
1147 {
1149 }
1150 
1152 {
1154 
1155  /// notify our parent that we've changed
1157  Send(&evt, ePool_Parent);
1158 }
1159 
1160 // zoom preserving update
1162 {
1164 }
1165 
1167 {
1168  if (m_pPhyloTreePane) {
1170  }
1171 }
1172 
1174 {
1175  x_SetPortLimits();
1176  x_UpdatePane();
1178  x_RedrawControls();
1179 }
1180 
1181 
1183 {
1184  if (m_pPhyloTreePane) {
1186  }
1187 }
1188 
1189 
1191 {
1192  double ratio = m_Port.GetScaleY()/m_Port.GetScaleX();
1193 
1196 
1197  TModelUnit sx = scale_x;
1198  TModelUnit sy = scale_x;
1199 
1200  // handle cases of only one axes zoom
1201  if (zb == CPhyloTreeScheme::eZoomX) sy = m_Port.GetScaleY();
1202  else if (zb == CPhyloTreeScheme::eZoomY) sx = m_Port.GetScaleX();
1203  else if (zb == CPhyloTreeScheme::eZoomXY) sy *= ratio;
1204 
1205  m_Port.SetScaleRefPoint(sx, sy, point);
1206 
1207  x_UpdateOnZoom();
1208 }
1209 
1210 void CPhyloTreeWidget::DlgOverlayFix(wxWindow* /*win*/)
1211 {
1213 }
1214 
1216 {
1218  m_pPhyloTreePane->Refresh();
1219 
1220  // Update active selection set:
1221  if (m_DataSource->GetTree()->HasSelection()) {
1222  vector<CPhyloTree::TTreeIdx> sel;
1225  if (std::find(sel.begin(), sel.end(), cur_node) == sel.end())
1227  }
1228 }
1229 
1231 {
1232  m_pPhyloTreePane->SetFocus();
1235 
1236  m_pScheme->SetLayoutIdx(idx);
1238 
1239  // This event saves the rendering options for the tree in the biotreecontainer.
1240  // only called for options that we want to save with the tree itself.
1242  Send(&evt, ePool_Parent);
1243 
1244  x_Update();
1245 }
1246 
1248 {
1250 }
1251 
1253 {
1254  vector<string> names;
1255  auto size = m_pPhyloTreePane->GetRenderers().size();
1256  for (auto i=0; i<size; i++) {
1257  names.push_back(m_pPhyloTreePane->GetRenderers()[i]->GetDescription());
1258  }
1259  return names;
1260 }
1261 
1262 
1264 {
1265  // notify parents
1267  Send(&evt, ePool_Parent);
1268 
1270 }
1271 
1272 void CPhyloTreeWidget::OnLoadAttributes(wxCommandEvent& /* evt */)
1273 {
1274  SWFileDlgData data(wxT("Open attributes file"), wxALL_FILES_PATTERN, wxFD_OPEN);
1275  string error = "";
1276  if ( NcbiFileBrowser(data) == wxID_OK) {
1277  wxString filename = data.GetFilename();
1278  try {
1279  this->SetCursor(*wxHOURGLASS_CURSOR);
1281  {{
1282  CBioTreeAttrReader reader;
1283  CNcbiIfstream is(filename.fn_str());
1284  reader.Read(is, table);
1285  }}
1286 
1288  x_Update();
1289  SendEditEvent();
1290  } catch(CException& e) {
1291  error = e.GetMsg();
1292  } catch(std::exception& e) {
1293  error = e.what();
1294  }
1295  this->SetCursor(*wxSTANDARD_CURSOR);
1296  }
1297  if( ! error.empty()) {
1298  wxString s = ToWxString(error);
1299  wxMessageBox(s, wxT("Error loading file."), wxOK | wxICON_ERROR);
1300  }
1301 }
1302 
1303 void CPhyloTreeWidget::OnOpenPropertiesDlg(wxCommandEvent& /* evt */)
1304 {
1305  // temporary scheme - load from disk in case some other view has updated
1306  // the scheme since this view was created.
1307  CRef <CPhyloTreeScheme> tmp_scheme(new CPhyloTreeScheme());
1308  tmp_scheme->LoadCurrentSettings();
1309 
1310  // Label visibility is not saved to registry (should it be?) so set it here
1311  if (!m_pScheme.IsNull()) {
1313  }
1314 
1315  // show the dialog
1316  string label_format = tmp_scheme->SetLabelFormat();
1317  CwxPhyloSettingsDlg dlg(this);
1318  dlg.SetParams(m_DataSource.GetPointer(), tmp_scheme.GetPointer());
1319 
1320  int result = dlg.ShowModal();
1321  DlgOverlayFix(this);
1322 
1323  if(result == wxID_OK) {
1325  SetScheme(tmp_scheme.GetObject());
1326 
1327  m_DataSource->Relabel(tmp_scheme, tmp_scheme->SetLabelFormat());
1328 
1329  // The label format is also saved in the biotreecontainer so that it can be
1330  // tree-specific (scheme default used when it is not in the tree).
1331  if (tmp_scheme->SetLabelFormat() != label_format) {
1333  Send(&evt, ePool_Parent);
1334  }
1335 
1336  x_SoftUpdate();
1337  }
1338 }
1339 
1340 void CPhyloTreeWidget::OnRerootTree(wxCommandEvent& /* evt */)
1341 {
1343  if (idx != CPhyloTree::Null()) {
1344  m_DataSource->ReRoot(idx);
1346 
1347  // Distances can change, so that means labels could change too
1349 
1351  m_pPhyloTreePane->Refresh();
1352 
1353  SendEditEvent();
1354  }
1355 }
1356 
1357 void CPhyloTreeWidget::OnRerootTreeAtEdge(wxCommandEvent& /* evt */)
1358 {
1359  if (m_DataSource->GetTree()->HasCurrentEdge()) {
1360  CPhyloTree::TTreeIdx child_idx, parent_idx;
1361 
1362  m_DataSource->GetTree()->GetCurrentEdge(child_idx, parent_idx);
1363  m_DataSource->ReRootEdge(child_idx);
1365 
1366  // Distances can change, so that means labels could change too
1368 
1370  m_pPhyloTreePane->Refresh();
1371 
1372  SendEditEvent();
1373  }
1374 }
1375 
1376 void CPhyloTreeWidget::OnSetMidpointRoot(wxCommandEvent& /* evt */)
1377 {
1380 
1381  // Distances can change, so that means labels could change too
1383 
1385  m_pPhyloTreePane->Refresh();
1386 
1387  SendEditEvent();
1388 }
1389 
1391 {
1392  bool has_current_node =
1394 
1395  evt.Enable(m_DataSource->GetTree()->GetNumSelected() > 0 || has_current_node);
1396 }
1397 
1398 void CPhyloTreeWidget::OnUpdateRerootTree(wxUpdateUIEvent& evt)
1399 {
1401  if (idx != CPhyloTree::Null() &&
1402  idx != m_DataSource->GetTree()->GetRootIdx()) {
1403  evt.Enable(true);
1404  }
1405  else {
1406  evt.Enable(false);
1407  }
1408 }
1409 
1411 {
1412  if (m_DataSource->GetTree()->HasCurrentEdge()) {
1413  evt.Enable(true);
1414  }
1415  else {
1416  evt.Enable(false);
1417  }
1418 }
1419 
1421 {
1422  evt.Enable(m_DataSource->GetTree()->GetNumNodes() > 1);
1423 }
1424 
1426 {
1428  bool collapsable = false;
1429  if (idx != CPhyloTree::Null()) {
1430  CPhyloTree::TNodeType& current =
1432 
1434  collapsable = true;
1435  }
1436  }
1437 
1438  evt.Enable(collapsable);
1439 }
1440 
1442 {
1444  bool expandable = false;
1445  if (idx != CPhyloTree::Null()) {
1446  CPhyloTree::TNodeType& current =
1448 
1450  expandable = true;
1451  }
1452  }
1453 
1454  evt.Enable(expandable);
1455 }
1456 
1458 {
1459  bool collapsable = false;
1460 
1461  vector<TTreeIdx> sel;
1462  m_DataSource->GetTree()->GetSelected(sel);
1463  TTreeIdx root_idx = m_DataSource->GetTree()->GetRootIdx();
1464 
1465  // Make sure at least one selected node is eligable to be collapsed
1466  for (size_t i = 0; i < sel.size(); ++i)
1467  {
1468  CPhyloTree::TTreeIdx node_idx = sel[i];
1469 
1470  // A node can be collapsed if it is not already collapsed and none of its parent nodes are collapsed.
1471  // The root node also cannot be collapsed.
1473  TTreeIdx parent_node_idx = m_DataSource->GetTree()->GetNode(node_idx).GetParent();
1474  while (parent_node_idx != root_idx) {
1476  break;
1477  parent_node_idx = m_DataSource->GetTree()->GetNode(parent_node_idx).GetParent();
1478  }
1479 
1480  // no parent nodes were already collapsed, so this node can be collapsed:
1481  if (parent_node_idx == root_idx) {
1482  collapsable = true;
1483  break;
1484  }
1485  }
1486  }
1487 
1488  evt.Enable(collapsable);
1489 }
1490 
1491 
1493 {
1494  m_pScheme.Reset(&sl);
1497  for (auto &renderer : vRend) {
1498  renderer->SetScheme(sl);
1499  }
1500 
1501  if (m_DataSource.NotNull())
1503 }
1504 
1505 void CPhyloTreeWidget::SetRegistryPath(const string& reg_path)
1506 {
1507  m_RegPath = reg_path;
1508 }
1509 
1511 {
1512  CPhyloTreeScheme * style = new CPhyloTreeScheme();
1513 
1514  if (!style->LoadCurrentSettings())
1515  return;
1516 
1517  SetScheme(*style);
1518 
1519  if (m_QueryPanel != NULL) {
1522  }
1523 }
1524 
1526 {
1527  if (m_QueryPanel != NULL)
1529 
1530  if (!m_pScheme.IsNull())
1532 }
1533 
1534 void CPhyloTreeWidget::OnSelectAll(wxCommandEvent& /* evt */)
1535 {
1537  true, true, false);
1538  x_SoftUpdate();
1539 }
1540 
1541 void CPhyloTreeWidget::OnClearSelection(wxCommandEvent& /* evt */)
1542 {
1544  x_SoftUpdate();
1545 }
1546 
1547  void CPhyloTreeWidget::OnAddSelectionSet(wxCommandEvent & evt)
1548  {
1549  string sel_name = m_QueryPanel->GetLastQuery();
1550 
1552  edit->GetPrevSet() = m_DataSource->GetSelectionSets();
1553 
1554  CPhyloSaveSelectiondlg dlg(this);
1555  dlg.SetSelections(m_DataSource, sel_name);
1556  dlg.ShowModal();
1557 
1560  m_pPhyloTreePane->Refresh();
1561 
1562  // This event saves the rendering options for the tree in the biotreecontainer.
1563  // This way, the updated selection sets will be saved with the tree and
1564  // used when we re-initialize from the biotreecontainer on updates.
1565  edit->GetUpdatedSet() = m_DataSource->GetSelectionSets();
1566  if (edit->Updated()) {
1567  m_DataSource->GetTree()->GetSelectionSets() = edit->GetPrevSet();
1569  Send(&selection_set_change, ePool_Parent);
1570  }
1571  }
1572 
1573  void CPhyloTreeWidget::OnExportSelection(wxCommandEvent & evt)
1574  {
1575  vector< CPhyloTree::TTreeIdx > selection;
1576  const CPhyloTree *tree = m_DataSource->GetTree();
1577  tree->GetSelected(selection);
1578  if (selection.empty())
1579  return;
1580 
1581  vector<wxString> columns;
1584  columns.push_back(itFeature->second);
1585  }
1586 
1587  CCSVSelectionExportDlg dlgExport(this);
1588  dlgExport.SetRegistryPath("Dialogs.ExportTreeViewToCSV");
1589  dlgExport.SetColumnsList(columns);
1590 
1591  if (dlgExport.ShowModal() != wxID_OK)
1592  return;
1593 
1594  wxString fileName = dlgExport.GetFileName();
1595  if (fileName.empty())
1596  return;
1597 
1598  unique_ptr<CNcbiOstream> os;
1599  os.reset(new CNcbiOfstream(fileName.fn_str(), IOS_BASE::out));
1600 
1601  if (os.get() == NULL){
1602  NCBI_THROW(
1604  "File is not accessible"
1605  );
1606  }
1607 
1608  CCSVExporter exporter(*os, ',', '"');
1609 
1610  CBioTreeFeatureDictionary::TFeatureDict featuresToExport;
1611  vector<wxString> selected;
1612  dlgExport.GetSelectedColumns(selected);
1613  ITERATE(vector<wxString>, field, selected) {
1615  if (itFeature->second == *field)
1616  featuresToExport.insert(*itFeature);
1617  }
1618  }
1619 
1620  if (dlgExport.GetWithHeaders()) {
1621  ITERATE(CBioTreeFeatureDictionary::TFeatureDict, itFeature, featuresToExport) {
1622  exporter.Field(itFeature->second);
1623  }
1624  exporter.NewRow();
1625  }
1626 
1627  bool leavesOnly = dlgExport.GetLeavesOnly();
1628 
1629  ITERATE(vector< CPhyloTree::TTreeIdx >, itIdx, selection) {
1630  const CPhyloTreeNode &node = tree->GetNode(*itIdx);
1631  if (leavesOnly && !node.IsLeaf())
1632  continue;
1633 
1634  const CBioTreeFeatureList &features = node.GetValue().GetBioTreeFeatureList();
1635 
1636  ITERATE(CBioTreeFeatureDictionary::TFeatureDict, itFeature, featuresToExport) {
1637  exporter.Field(features.GetFeatureValue(itFeature->first));
1638  }
1639  exporter.NewRow();
1640  }
1641  }
1642 
1643  void CPhyloTreeWidget::OnExportTree(wxCommandEvent & evt)
1644  {
1646  Send(&fwd_evt, ePool_Parent);
1647  }
1648 
1649  void CPhyloTreeWidget::OnExpandChildren(wxCommandEvent& /* evt */)
1650 {
1652  if (idx != CPhyloTree::Null()) {
1653  CPhyloTree::TNodeType& current =
1655 
1658  }
1659  }
1660 }
1661 
1662 void CPhyloTreeWidget::OnCollapseSelected(wxCommandEvent& /* evt */)
1663 {
1665  SendEditEvent();
1666 }
1667 
1668 void CPhyloTreeWidget::OnHighlightEdges(wxCommandEvent& /* evt */)
1669 {
1670  // Enable for current renderer (only).
1672 
1673  x_SoftUpdate();
1674 }
1675 
1676 void CPhyloTreeWidget::OnCollapseToViewport(wxCommandEvent& /* evt */)
1677 {
1678  set<CPhyloNodeData::TID> collapsed_nodes;
1679 
1680  // Collapse nodes in tree from most to least distant until tree fits in viewport
1682  int target_leaves = m_pPhyloTreePane->GetCurrRenderer()->GetMaxLeavesVisible();
1683 
1685 
1686  collapsed_nodes = m_DataSource->CollapseByDistance(target_leaves, c.GetPointer());
1687 
1688  // Event collapses nodes (and supports undo of collapse)
1689  if (collapsed_nodes.size() > 0) {
1692  ec->GetIds().insert(ec->GetIds().begin(), collapsed_nodes.begin(), collapsed_nodes.end());
1694 
1696  Send(&evt, ePool_Parent);
1697  }
1698  }
1699 }
1700 
1701 void CPhyloTreeWidget::OnCollapseChildren(wxCommandEvent& /* evt */)
1702 {
1704  if (idx != CPhyloTree::Null()) {
1705  CPhyloTree::TNodeType& current = m_DataSource->GetTree()->GetNode(idx);
1706 
1710  }
1711  }
1712 }
1713 
1714 void CPhyloTreeWidget::OnZoomToSubtree(wxCommandEvent& /* evt */)
1715 {
1717  if (idx != CPhyloTree::Null()) {
1718  CPhyloTree::TTreeIdx parent_idx = m_DataSource->GetTree()->GetNode(idx).GetParent();
1719 
1720  // Re-root the tree to currently selected node
1721  m_DataSource->ReRoot(idx);
1722 
1723  // invalidate selections (would need to reselect otherwise since topology changed)
1725 
1726  // if possible, hide other nodes
1727  if (parent_idx != CPhyloTree::Null()) {
1728  CPhyloTree::TNodeType& node =
1729  m_DataSource->GetTree()->GetNode(parent_idx);
1730 
1731  // Don't use SendEditEvent(eCmdNodeExpandCollapse) for
1732  // expand/collapse here (undo for this operation will
1733  // undo both reroot and collapse)
1737  }
1738  }
1739  }
1740 
1741  SendEditEvent();
1742 }
1743 
1745 {
1746  evt.Enable(false);
1747 
1749 
1750  if (idx != CPhyloTree::Null() &&
1751  idx != m_DataSource->GetTree()->GetRootIdx()) {
1752  CPhyloTreeNode& current = m_DataSource->GetTree()->GetNode(idx);
1753  if (current.Expanded() && !current.IsLeafEx())
1754  evt.Enable(true);
1755  }
1756 }
1757 
1758 
1759 void CPhyloTreeWidget::OnSearchTip(wxCommandEvent & evt)
1760 {
1761  // Need the tool tip window for the event - we stored its pointer in
1762  // the button's (event objects) client data when the button was created
1763  wxEvtHandler* obj = dynamic_cast<wxEvtHandler*>(evt.GetEventObject());
1764  if (obj != NULL) {
1765  CTooltipFrame* f = static_cast<CTooltipFrame*>(obj->GetClientData());
1766  std::string tip_id = f->GetTipInfo().GetTipID();
1767 
1768  int id = NStr::StringToInt(tip_id);
1769  CPhyloTree::TTreeIdx idx =
1771 
1772  if (idx != CPhyloTreeNode::Null()){
1773  CVect2<float> pos = m_DataSource->GetTree()->GetNode(idx)->XY();
1774 
1775  wxPoint win_pos = m_pPhyloTreePane->GetScreenPosition();
1776 
1777  // move to center of screen (if current zoom level allows)
1778  TModelUnit center_x = m_pPhyloTreePane->GetScreenRect().x +
1779  m_pPhyloTreePane->GetScreenRect().GetWidth()/2 -
1780  win_pos.x;
1781  TModelUnit center_y = m_pPhyloTreePane->GetScreenRect().y - win_pos.y;
1782  center_y = m_pPhyloTreePane->GetRect().GetHeight()/2-center_y;
1783 
1784  // Get rectangle for tool tip within the window using standard
1785  // cartesian (and opengl) coords. (Lower left is (0,0)).
1786  wxRect tip_rect = f->GetScreenRect();
1787  tip_rect.x = tip_rect.x - win_pos.x;
1788  tip_rect.y = tip_rect.y - win_pos.y;
1789  tip_rect.y = m_pPhyloTreePane->GetRect().GetHeight() -
1790  (tip_rect.y + tip_rect.GetHeight());
1791 
1792  // Could potentially add code to make sure glyph doesn't wind up
1793  // under this, or some other, tooltip here. But that's not easy
1794  // since we don't have pointers to other tips (here) and we don't
1795  // know how much the actual scroll will be since it is constrained
1796  // when we are zoomed out.
1797 
1798  TModelPoint center_model_coord =
1799  m_pPhyloTreePane->GetPane().UnProject((int)center_x, (int)center_y);
1800 
1801  double dx = center_model_coord.X()-pos.X();
1802  double dy = center_model_coord.Y()-pos.Y();
1803 
1804  Scroll(-dx, -dy);
1805 
1806  std::string tip_id = f->GetTipInfo().GetTipID();
1807  int id = NStr::StringToInt(tip_id);
1808  m_pPhyloTreePane->GetCurrRenderer()->PointToNode(id, tip_rect, 0.5);
1809  m_pPhyloTreePane->Refresh();
1810  }
1811  }
1812 }
1813 
1814 void CPhyloTreeWidget::OnZoomTip(wxCommandEvent & evt)
1815 {
1816  // Need the tool tip window for the event - we stored its pointer in
1817  // the button's (event objects) client data when the button was created
1818  wxEvtHandler* obj = dynamic_cast<wxEvtHandler*>(evt.GetEventObject());
1819  if (obj != NULL) {
1820  CTooltipFrame* f = static_cast<CTooltipFrame*>(obj->GetClientData());
1821  std::string tip_id = f->GetTipInfo().GetTipID();
1822 
1823  int id = NStr::StringToInt(tip_id);
1824  TTreeIdx idx =
1826 
1827  if (idx != NULL_TREE_IDX) {
1828  CPhyloTreeNode& tip_node = m_DataSource->GetTree()->GetNode(idx);
1829  TModelPoint pt((tip_node)->X(), (tip_node)->Y());
1830 
1831  // Scroll to the glyph prior to zooming:
1832  OnSearchTip(evt);
1833 
1834  float def_node_size = (float)
1836 
1837  // Compute distance between nodes here since not all renderers
1838  // do it the same (and they return int, but we can't round)
1839  float dimy = (float)m_pPhyloTreePane->GetCurrRenderer()->GetDimY();
1840  float size = (float)m_DataSource->GetSize();
1841  float scale_y = (float)m_pPhyloTreePane->GetPane().GetScaleY();
1842  float dist_between_nodes = dimy/(size * scale_y);
1843 
1844  // should not happen, but just in case:
1845  if (dist_between_nodes <= 0.0f) {
1846  m_pPhyloTreePane->Refresh();
1847  return;
1848  }
1849 
1850  // Normally labels are displayed if the distance between nodes
1851  // is > 2*node size. We set the zoom factor here to be twice that
1852  // zoom level. We do not zoom in more if view is already zoomed.
1853  float zfact = 4.0f*def_node_size/dist_between_nodes;
1854 
1855  if (zfact > 1.0f) {
1856 
1857  // Zoom based on current zoom behavior. If user has selected
1858  // horizonal zoom, zooming in generally won't provide much
1859  // if any benefit. With veritcal or proportional zoom, this
1860  // should guarantee label visibility.
1863  if (zb == CPhyloTreeScheme::eZoomX)
1864  options = CGlPane::fZoomX;
1865  else if (zb == CPhyloTreeScheme::eZoomY)
1866  options = CGlPane::fZoomY;
1867 
1868  ZoomPoint(pt, zfact, options);
1869  }
1870  m_pPhyloTreePane->Refresh();
1871  }
1872  }
1873 }
1874 
1875 void CPhyloTreeWidget::OnInfoTip(wxCommandEvent & evt)
1876 {
1877  // Need the tool tip window for the event - we stored its pointer in
1878  // the button's (event objects) client data when the button was created
1879  wxEvtHandler* obj = dynamic_cast<wxEvtHandler*>(evt.GetEventObject());
1880  if (obj != NULL) {
1881  CTooltipFrame* f = static_cast<CTooltipFrame*>(obj->GetClientData());
1882  std::string tip_id = f->GetTipInfo().GetTipID();
1883 
1884  int id = NStr::StringToInt(tip_id);
1885  CPhyloTree::TTreeIdx tip_node_idx =
1887 
1888  if (tip_node_idx != CPhyloTree::Null()) {
1889  CPhyloTreeNode& n = m_DataSource->GetTree()->GetNode(tip_node_idx);
1890 
1891  CFeatureEdit* feat_edit(new CFeatureEdit());
1892  feat_edit->GetDictionary() = m_DataSource->GetDictionary();
1893  feat_edit->GetUpdated().push_back(CUpdatedFeature());
1894  feat_edit->GetUpdated()[0].SetNode(n->GetId(), tip_node_idx);
1895  feat_edit->GetUpdated()[0].GetPrevFeatures() = n->GetBioTreeFeatureList();
1896 
1897  CwxPhyloEditDlg dlg(this);
1898  dlg.SetParams(m_DataSource->GetTree(), tip_node_idx, feat_edit);
1899 
1900  int result = dlg.ShowModal();
1901  DlgOverlayFix(this);
1902 
1903  if(result == wxID_OK) {
1906  Send(&evt, ePool_Parent);
1907  }
1908  else {
1909  delete feat_edit;
1910  }
1911  }
1912  }
1913 }
1914 
1915 void CPhyloTreeWidget::OnTipActivated(wxCommandEvent & evt)
1916 {
1917  // Need the tool tip window for the event - we stored its pointer in
1918  // the button's (event objects) client data when the button was created
1919  wxEvtHandler* obj = dynamic_cast<wxEvtHandler*>(evt.GetEventObject());
1920  if (obj != NULL) {
1921  CTooltipFrame* f = static_cast<CTooltipFrame*>(obj->GetClientData());
1922  std::string tip_id = f->GetTipInfo().GetTipID();
1923  int id = NStr::StringToInt(tip_id);
1925  m_pPhyloTreePane->Refresh();
1926  }
1927 }
1928 
1929 void CPhyloTreeWidget::OnTipDeactivated(wxCommandEvent& /* evt */)
1930 {
1932  m_pPhyloTreePane->Refresh();
1933 }
1934 
1935 void CPhyloTreeWidget::OnShowAll(wxCommandEvent& /* evt */)
1936 {
1937  vector<CPhyloTree::TTreeIdx> collapsed =
1939 
1940  if (collapsed.size() == 0)
1941  return;
1942 
1945 
1946  for (size_t i=0; i<collapsed.size(); ++i) {
1947  CPhyloTreeNode& current= (*m_DataSource->GetTree())[collapsed[i]];
1948  ec->AddNode(current->GetId());
1949  }
1950 
1952  Send(&evt, ePool_Parent);
1953 }
1954 
1955 void CPhyloTreeWidget::OnUpdateShowAll(wxUpdateUIEvent& evt)
1956 {
1957  evt.Enable(true);
1958 }
1959 
1960 void CPhyloTreeWidget::OnEditNode(wxCommandEvent& /* evt */)
1961 {
1962  if (m_DataSource->GetTree()->HasCurrentNode()){
1964 
1965  CwxPhyloEditDlg dlg(this);
1966 
1967  CFeatureEdit* feat_edit(new CFeatureEdit());
1968  feat_edit->GetDictionary() = m_DataSource->GetDictionary();
1969  feat_edit->GetUpdated().push_back(CUpdatedFeature());
1970  feat_edit->GetUpdated()[0].SetNode(hover->GetId(), m_DataSource->GetTree()->GetCurrentNodeIdx());
1971  feat_edit->GetUpdated()[0].GetPrevFeatures() = hover->GetBioTreeFeatureList();
1972  dlg.SetParams(m_DataSource->GetTree(),
1974  feat_edit);
1975 
1976  int result = dlg.ShowModal();
1977  DlgOverlayFix(this);
1978 
1979  if(result == wxID_OK) {
1982  Send(&evt, ePool_Parent);
1983  }
1984  else {
1985  delete feat_edit;
1986  }
1987  }
1988 }
1989 
1990 void CPhyloTreeWidget::OnUpdateEditNode(wxUpdateUIEvent& evt)
1991 {
1992  evt.Enable(m_DataSource->GetTree()->HasCurrentNode());
1993 }
1994 
1995 
1996 void CPhyloTreeWidget::OnFilterDistances(wxCommandEvent& /* evt */)
1997 {
1998  /*
1999  unique_ptr <CPhyloTreeFilterDlg> filterDialog(new CPhyloTreeFilterDlg(m_pDataSource->GetMinDistance(),
2000  m_pDataSource->GetNormDistance()));
2001  int result = dlg.ShowModal();
2002  DlgOverlayFix(this);
2003 
2004  if(result == wxID_OK) {
2005  m_pDataSource->FilterDistances(filterDialog->GetDistance());
2006  m_pDataSource->Refresh();
2007  x_SoftUpdate();
2008  SendEditEvent();
2009  }
2010  */
2011 }
2012 
2013 void CPhyloTreeWidget::x_ZoomIn(int /* options */)
2014 {
2017 
2021 }
2022 
2023 
2024 void CPhyloTreeWidget::x_ZoomOut(int /* options */)
2025 {
2028 
2032 }
2033 
2034 void CPhyloTreeWidget::OnSort(wxCommandEvent& evt)
2035 {
2036  switch (evt.GetId()){
2037  case eCmdSort:
2039  break;
2040  case eCmdSortDist:
2042  break;
2043  case eCmdSortLabel:
2045  break;
2046  case eCmdSortLabelRange:
2048  break;
2049  default:
2050  return;
2051  }
2052 
2054 }
2055 
2057 {
2058  evt.Check(m_SortAscending);
2059 }
2060 
2061 void CPhyloTreeWidget::OnSortAscending(wxCommandEvent & evt)
2062 {
2064 }
2065 
2066 void CPhyloTreeWidget::OnClean(wxCommandEvent& /* evt */)
2067 {
2068  m_DataSource->Clean();
2070  SendEditEvent();
2071 }
2072 
2073 void CPhyloTreeWidget::OnFilter(wxCommandEvent& /* evt */)
2074 {
2075  m_DataSource->Filter();
2076  SendEditEvent();
2077 }
2078 
2079 void CPhyloTreeWidget::OnLabels(wxCommandEvent & evt)
2080 {
2081  switch (evt.GetId()){
2084  break;
2085  case eCmdLabelsVisible:
2087  break;
2088  case eCmdLabelsHidden:
2090  break;
2091  default:
2092  break;
2093  }
2094  x_SoftUpdate();
2095 }
2096 
2097 void CPhyloTreeWidget::OnUpdateLabels(wxUpdateUIEvent& evt)
2098 {
2099  switch (evt.GetId()){
2102  break;
2103  case eCmdLabelsVisible:
2105  break;
2106  case eCmdLabelsHidden:
2108  break;
2109  default:
2110  break;
2111  }
2112 }
2113 
2114 void CPhyloTreeWidget::OnAl(wxCommandEvent & evt)
2115 {
2116  switch (evt.GetId()){
2117  case eCmdAlNone:
2119  break;
2120  case eCmdAlPhylip:
2122  break;
2123  case eCmdAlPaml:
2125  break;
2126  default:
2127  break;
2128  }
2129 
2130  x_SoftUpdate();
2131 }
2132 
2133 void CPhyloTreeWidget::OnUpdateAl(wxUpdateUIEvent& evt)
2134 {
2135  switch (evt.GetId()){
2136  case eCmdAlNone:
2138  break;
2139  case eCmdAlPhylip:
2141  break;
2142  case eCmdAlPaml:
2144  break;
2145  default:
2146  break;
2147  }
2148 }
2149 
2150 void CPhyloTreeWidget::OnSetTreeLabel(wxCommandEvent& evt)
2151 {
2152  CwxTreeLabelEdit dlg(this);
2154 
2155  int result = dlg.ShowModal();
2156  DlgOverlayFix(this);
2157 
2158  if(result == wxID_OK) {
2160  Send(&evt, ePool_Parent);
2161 
2162  x_SoftUpdate();
2163  }
2164 }
2165 
2166 void CPhyloTreeWidget::OnEdit(wxCommandEvent & evt)
2167 {
2168  switch (evt.GetId()){
2169  case eCmdNodeCut: m_DataSource->Cut(); break;
2170  case eCmdNodePaste: m_DataSource->Paste(); break;
2171  case eCmdNodeNewChild: m_DataSource->NewNode(); break;
2172  case eCmdNodeNewParent: m_DataSource->NewNode(false); break;
2173  case eCmdRemoveNode: m_DataSource->Remove(false); break;
2175  case eCmdRemoveSubtree: m_DataSource->Remove(); break;
2176  case eCmdMoveUp: m_DataSource->MoveNode(true); break;
2177  case eCmdMoveDown: m_DataSource->MoveNode(false); break;
2178  default: break;
2179  }
2180 
2181  //x_SoftUpdate();
2182 
2183  SendEditEvent();
2184 }
2185 
2186 void CPhyloTreeWidget::OnUpdateEdit(wxUpdateUIEvent& evt)
2187 {
2188  switch (evt.GetId()){
2189  case eCmdNodeCut:
2190  evt.Enable((m_DataSource->GetTree()->HasCurrentNode()) &&
2192  break;
2193  case eCmdNodePaste:
2194  evt.Enable((m_DataSource->GetTree()->HasCurrentNode()) &&
2196  break;
2197  case eCmdNodeNewChild:
2198  evt.Enable(m_DataSource->GetTree()->HasCurrentNode());
2199  break;
2200  case eCmdNodeNewParent:
2201  case eCmdMoveUp:
2202  case eCmdMoveDown:
2203  evt.Enable((m_DataSource->GetTree()->HasCurrentNode()) &&
2205  break;
2206  case eCmdRemoveNode:
2207  case eCmdRemoveSubtree:
2208  evt.Enable(m_DataSource->GetTree()->HasCurrentNode());
2209  break;
2210  case eCmdRemoveSelected:
2211  evt.Enable(m_DataSource->GetTree()->HasSelection());
2212  break;
2213  default:
2214  break;
2215  }
2216 }
2217 
2219 {
2220  m_LastCommand = ec;
2221 
2222  if (ec == eCmdNodeExpandCollapse) {
2223 
2224 
2225  if (m_DataSource->GetTree()->HasCurrentNode()) {
2226  CPhyloTree::TNodeType& current =
2228 
2229  // Saving these values allows us to recenter viewport after expand/collapse completed
2231  m_PrevPos = current.GetValue().XY();
2232 
2233  CFeatureEdit* feat_edit(new CFeatureEdit());
2234  feat_edit->GetDictionary() = m_DataSource->GetDictionary();
2235 
2236  CUpdatedFeature f;
2237 
2238  f.GetPrevFeatures() = (*current).GetBioTreeFeatureList();
2239  f.GetFeatures() = (*current).GetBioTreeFeatureList();
2240  TBioTreeFeatureId feat_id = feat_edit->m_Dictionary.Register("$NODE_COLLAPSED");
2241 
2242  bool update = false;
2243 
2244  // Update features (but not prevfeatures)
2245  switch ((*current).GetDisplayChildren()){
2248  f.GetFeatures().SetFeature(feat_id, "0"); //showdhilds
2249  update = true;
2250  }
2251  break;
2254  f.GetFeatures().SetFeature(feat_id, "1"); //hidechildren
2255  update = true;
2256  }
2257  break;
2258  }
2259 
2260  // Caller should have already updated feature in node in this case so we
2261  // just grab that and the (possibly) updated dictionary.
2262 
2263  if (!update) {
2264  delete feat_edit;
2265  return;
2266  }
2267 
2268  f.SetNode((*current).GetId(), m_DataSource->GetTree()->GetCurrentNodeIdx());
2269 
2270  feat_edit->GetUpdated().push_back(f);
2271  CEvent evt(CEvent::eEvent_Message, ec, feat_edit, CEvent::eRelease, this);
2272  Send(&evt, ePool_Parent);
2273  }
2274  }
2275  else {
2276  CEvent evt(CEvent::eEvent_Message, ec);
2277  Send(&evt, ePool_Parent);
2278  }
2279 }
2280 
2281 
2282 void CPhyloTreeWidget::OnUpdateEditLabel(wxUpdateUIEvent& evt)
2283 {
2284  evt.Enable(m_DataSource->GetTree()->HasCurrentNode());
2285 }
2286 
2287 void CPhyloTreeWidget::OnEditLabel(wxCommandEvent& /* evt */)
2288 {
2289  EditLabel();
2290 }
2291 
2293 {
2294  if (m_DataSource->GetTree()->HasCurrentNode()) {
2296  CwxLabelEditDlg dlg(this);
2298 
2299  int result = dlg.ShowModal();
2300  DlgOverlayFix(this);
2301 
2302  if(result == wxID_OK) {
2303  // Get updated label and set it in out updated feature list
2304  string new_label = dlg.GetUpdatedLabel();
2305  TBioTreeFeatureId label_id = m_DataSource->GetTree()->GetFeatureDict().GetId("label");
2306 
2307  CFeatureEdit* feat_edit(new CFeatureEdit());
2308  feat_edit->GetDictionary() = m_DataSource->GetDictionary();
2309  feat_edit->GetUpdated().push_back(CUpdatedFeature());
2310  feat_edit->GetUpdated()[0].SetNode(hover->GetId(), m_DataSource->GetTree()->GetCurrentNodeIdx());
2311  feat_edit->GetUpdated()[0].GetPrevFeatures() = hover->GetBioTreeFeatureList();
2312  feat_edit->GetUpdated()[0].GetFeatures() = hover->GetBioTreeFeatureList();
2313  feat_edit->GetUpdated()[0].GetFeatures().SetFeature(label_id, new_label);
2314 
2316  Send(&evt, ePool_Parent);
2317  }
2318  }
2319 }
2320 
2321 void CPhyloTreeWidget::OnSubtreeFromSelection(wxCommandEvent& /* evt */)
2322 {
2324  Send(&eee, ePool_Parent);
2325 }
2326 
2328 {
2329  this->SetCursor(*wxHOURGLASS_CURSOR);
2330  m_pPhyloTreePane->Disable();
2331  m_QueryPanel->SetCursor(*wxSTANDARD_CURSOR);
2332 }
2333 
2335 {
2336  this->SetCursor(*wxSTANDARD_CURSOR);
2337  m_pPhyloTreePane->Enable();
2338 
2339  /// Set the current node to the first node in the selection set
2341 
2343 
2344  // If query was a macro, also set undo/redo event here
2345  if (exec != NULL) {
2346  CTreeQueryExec *e = dynamic_cast<CTreeQueryExec*>(exec);
2347 
2348  if (e != NULL) {
2349  CFeatureEdit* feat_edit = e->GetFeatureEdit();
2350  CSelectionSetEdit* sel_edit = e->GetSelectionEdit();
2351 
2352  // If user changed topology (deleted node(s)), we need to clear selection and send an
2353  // edit event which updates the project and saves a copy of previous tree for undo/redo
2354  if (e->GetTopologyChange()) {
2356 
2357  // Distances can change, so that means labels could change too
2359 
2360  SendEditEvent();
2361  }
2362  else if (feat_edit != NULL) {
2363  feat_edit->GetDictionary() = m_DataSource->GetDictionary();
2364 
2365  if (feat_edit->m_Updated.size() > 0) {
2367  Send(&evt, ePool_Parent);
2368  }
2369 
2370  // If selection set was updated, update the current selection set with the value
2371  // it had before macros were invoked, then use the eCmdRenderingOptionsChanged to
2372  // perform the update/edit using undo-redo mechanism.
2373  sel_edit->GetUpdatedSet() = m_DataSource->GetTree()->GetSelectionSets();
2374  if (sel_edit->Updated()) {
2375  m_DataSource->GetTree()->GetSelectionSets() = sel_edit->GetPrevSet();
2377  Send(&evt2, ePool_Parent);
2378  }
2379  }
2380  }
2381  }
2382 }
2383 
2385 {
2386  CPhyloTree::TTreeIdx node_idx;
2387 
2388  // Go to the next/previous node in the selection set, and return it
2390 
2391  // If we have a node, check to see if it is currently on screen. If
2392  // it isn't, scroll the window so that it is visible. Do not scroll it
2393  // to the screen center, but rather half way toward the center. That
2394  // gives a better impression to the user of which way the screen is
2395  // moving.
2396  if (node_idx != CPhyloTree::Null()) {
2397  CPhyloTree::TNodeType& node = m_DataSource->GetTree()->GetNode(node_idx);
2398 
2399  TModelPoint pt((node)->X(), (node)->Y());
2400 
2401  // Get extent of label in ll,ur (lower-left and upper-right) if labels
2402  // are visible
2403  CVect2<float> ll(node->XY()), ur(node->XY());
2404  bool rotated = false;
2405  bool label_visible = false;
2406 
2408  if (r != NULL) {
2409  label_visible = r->LabelsVisible();
2410  rotated = r->GetRotatedLabels();
2411  }
2412 
2413  if (label_visible) {
2414  // Get current rotation angle for zoom level (varies from default rotation angle
2415  // which is node.GetAngle()
2416  float rotation_angle =
2418 
2419  if (label_visible) {
2420  CVect2<float> scalef(float(m_pPhyloTreePane->GetPane().GetScale().X()),
2421  float(m_pPhyloTreePane->GetPane().GetScale().Y()));
2422 
2423  // Remember current angle 'a'
2424  float a = node->GetAngle();
2425  node->SetAngle(rotation_angle);
2426  node.GetValue().GetLabelRect(scalef, ll, ur, rotated);
2427  node->SetAngle(a);
2428  }
2429  }
2430 
2431  // label_end_pos holds the labels x and y coordinates that are most
2432  // distant from the node itself (so when we can scroll we can
2433  // try to get the entire label into viewport)
2434  CVect2<float> label_end_pos;
2435  if (std::abs(ll.X() - node->X()) > std::abs(ur.X() - node->X()))
2436  label_end_pos.X() = ll.X();
2437  else
2438  label_end_pos.X() = ur.X();
2439 
2440  if (std::abs(ll.Y() - node->Y()) > std::abs(ur.Y() - node->Y()))
2441  label_end_pos.Y() = ll.Y();
2442  else
2443  label_end_pos.Y() = ur.Y();
2444 
2445  // Get viewport
2447 
2448  // Get viewport coordinates of node position and (furthest) label position
2449  TVPPoint ppt = m_pPhyloTreePane->GetPane().Project(pt.X(), pt.Y());
2450  TVPPoint label_ppt = m_pPhyloTreePane->GetPane().Project(label_end_pos.X(), label_end_pos.Y());
2451 
2452  // Labels could be wider or (if rotated) taller than the viewport which
2453  // would make it impossible to scroll the whole label into view.
2454  // restrict label width/height to 70% of the viewport size for
2455  // scrolling purposes.
2456  float label_xpct = float(label_ppt.X() - ppt.X()) / float(vp.Width());
2457  float label_ypct = float(label_ppt.Y() - ppt.Y()) / float(vp.Height());
2458 
2460  if (label_xpct > 0.7f) {
2461  label_xpct = 0.7f;
2462  label_end_pos.X() = pt.X() + label_xpct*m_pPhyloTreePane->GetPane().UnProjectWidth(vp.Width());
2463  }
2464  else if (label_xpct < -0.7f) {
2465  label_xpct = -0.7f;
2466  label_end_pos.X() = pt.X() + label_xpct*m_pPhyloTreePane->GetPane().UnProjectWidth(vp.Width());
2467  }
2468 
2469  if (label_ypct > 0.7f) {
2470  label_ypct = 0.7f;
2471  label_end_pos.Y() = pt.Y() + label_xpct*m_pPhyloTreePane->GetPane().UnProjectHeight(vp.Height());
2472  }
2473  else if (label_ypct < -0.7f) {
2474  label_ypct = -0.7f;
2475  label_end_pos.Y() = pt.Y() + label_xpct*m_pPhyloTreePane->GetPane().UnProjectHeight(vp.Height());
2476  }
2478 
2479  // Reset (distant) label projected position to match label_x/ypct
2480  label_ppt.Init(ppt.X() + int(label_xpct*vp.Width()),
2481  ppt.Y() + int(label_ypct*vp.Height()));
2482 
2483  // If either the node position or the (possibly truncated) label end
2484  // are not within the viewport, set up to scroll them into view
2485  if (!m_pPhyloTreePane->GetPane().GetViewport().PtInRect(ppt) ||
2486  !m_pPhyloTreePane->GetPane().GetViewport().PtInRect(label_ppt)) {
2487  wxPoint win_pos = m_pPhyloTreePane->GetScreenPosition();
2488 
2489  //Get center of screen in model coords
2490  TModelUnit center_x = m_pPhyloTreePane->GetScreenRect().x +
2491  m_pPhyloTreePane->GetScreenRect().GetWidth()/2 -
2492  win_pos.x;
2493  TModelUnit center_y = m_pPhyloTreePane->GetScreenRect().y - win_pos.y;
2494  center_y = m_pPhyloTreePane->GetRect().GetHeight()/2-center_y;
2495 
2496  TModelPoint center_model_coord =
2497  m_pPhyloTreePane->GetPane().UnProject((int)center_x, (int)center_y);
2498 
2499  double dx = 0.0;
2500  double dy = 0.0;
2501 
2502  // The node and/or label end are outside of the viewport.
2503  // determine for both x and y which one is further outside
2504  // the viewport and set scroll amounts (in model coords)
2505  // to bring it back in.
2506  if (ppt.X() > vp.Width() || label_ppt.X() > vp.Width()) {
2507  // If node or (end of) label are to the right of the viewport
2508  if (ppt.X() > label_ppt.X()) {
2509  double off = ppt.X() - vp.Width();
2510 
2511  // In each of these, 'dx' is the amount to scroll the node
2512  // or label position to the center of the viewport
2513  dx = (center_model_coord.X() - pt.X());
2514 
2515  // We then scale that amount to bring the node to just
2516  // 25% inside the viewport (or for end of label just 10%)
2517  dx *= (off + vp.Width()*0.25)/(off + vp.Width()*0.5);
2518  }
2519  else {
2520  double off = label_ppt.X() - vp.Width();
2521  dx = (center_model_coord.X() - label_end_pos.X());
2522  dx *= (off + vp.Width()*0.10)/(off + vp.Width()*0.5);
2523  }
2524  }
2525  else if (ppt.X() < 0 || label_ppt.X() < 0) {
2526  // If node or (end of) label are to the left of the viewport
2527  if (ppt.X() < label_ppt.X()) {
2528  double off = -ppt.X();
2529  dx = (center_model_coord.X() - pt.X());
2530  dx *= (off + vp.Width()*0.25) / (off + vp.Width()*0.5);
2531  }
2532  else {
2533  double off = -label_ppt.X();
2534  dx = (center_model_coord.X() - label_end_pos.X());
2535  dx *= (off + vp.Width()*0.10) / (off + vp.Width()*0.5);
2536  }
2537  }
2538 
2539  if (ppt.Y() > vp.Height() || label_ppt.Y() > vp.Height()) {
2540  if (ppt.Y() > label_ppt.Y()) {
2541  double off = ppt.Y() - vp.Height();
2542  dy = (center_model_coord.Y() - pt.Y());
2543  dy *= (off + vp.Height()*0.25) / (off + vp.Height()*0.5);
2544  }
2545  else {
2546  double off = label_ppt.Y() - vp.Height();
2547  dy = (center_model_coord.Y() - label_end_pos.Y());
2548  dy *= (off + vp.Height()*0.10) / (off + vp.Height()*0.5);
2549  }
2550  }
2551  else if (ppt.Y() < 0 || label_ppt.Y() < 0) {
2552  if (ppt.Y() < label_ppt.Y()) {
2553  double off = -ppt.Y();
2554  dy = (center_model_coord.Y() - pt.Y());
2555  dy *= (off + vp.Height()*0.25) / (off + vp.Height()*0.5);
2556  }
2557  else {
2558  double off = -label_ppt.Y();
2559  dy = (center_model_coord.Y() - label_end_pos.Y());
2560  dy *= (off + vp.Height()*0.10) / (off + vp.Height()*0.5);
2561  }
2562  }
2563 
2564  Scroll(-dx, -dy);
2565  }
2566  }
2567 
2569 }
2570 
2572 {
2573  if (m_DataSource != NULL) {
2577  }
2578 }
2579 
2581 {
2586  m_pPhyloTreePane->Refresh();
2587 }
2588 
2589 
User-defined methods of the data storage class.
User-defined methods of the data storage class.
User-defined methods of the data storage class.
User-defined methods of the data storage class.
User-defined methods of the data storage class.
User-defined methods of the data storage class.
User-defined methods of the data storage class.
EVT_UPDATE_UI(eCmdAlnShowMethodsDlg, CAlnMultiWidget::OnUpdateShowMethodDlg) EVT_UPDATE_UI(eCmdMethodProperties
@ eCmdShowAll
Parser-reader for BKBTA - biotree attributes format.
Features storage for the bio tree node.
Definition: bio_tree.hpp:101
void Field(const string &value)
void GetSelectedColumns(vector< wxString > &columns) const
Gets the columns, selected by the user.
void SetColumnsList(const vector< wxString > &columns)
Sets the columns lists.
virtual void SetRegistryPath(const string &path)
Definition: dialog.cpp:59
CEvent - generic event implementation TODO TODO - Attachments.
Definition: event.hpp:86
class CGlPane
Definition: glpane.hpp:62
class CGlWidgetBase
virtual void x_UpdateOnZoom()
virtual void Scroll(TModelUnit d_x, TModelUnit d_y)
TModelPoint m_PopupPoint
virtual void x_ZoomIn(int options)
Zoom functions.
virtual void ZoomRect(const TModelRect &rc)
virtual void x_RedrawControls(void)
virtual void x_ZoomOut(int options)
string m_RegPath
path to the widget's settings in GUI Registry
virtual void x_CreateControls(void)
creates Pane, Scrollbars and other child widgets, called from Create()
virtual void x_UpdateScrollbars()
virtual void ZoomPoint(const TModelPoint &point, TModelUnit factor, CGlPane::EZoomOptions=CGlPane::fZoomXY)
CGlWidgetPane represent a window component residing in CGlWidgetBase client area.
CImage –.
Definition: Image.hpp:66
size_t GetWidth(void) const
Definition: image.hpp:98
void Flip(void)
Definition: image.cpp:275
CImage * GetSubImage(size_t x, size_t y, size_t w, size_t h) const
Definition: image.cpp:232
size_t GetHeight(void) const
Definition: image.hpp:99
unsigned char * SetData(void)
Definition: image.cpp:92
class CMacroQueryExec
CMenuItem - represents a menu items in IMenu-style menus.
Definition: menu_item.hpp:53
Template class to create a table with custom row-column access.
Definition: ncbi_table.hpp:66
Main layout class.
void StopLayout()
Stop active layout (particle system)
CGlRect< float > GetLabelRect() const
CBioTreeFeatureList & GetBioTreeFeatureList()
void SetSelections(CRef< CPhyloTreeDataSource > ds, string name)
void MeasureTree(TTreeIdx node)
void SortDist(bool ascending)
TTreeIdx GetCurrentSearchNode() const
void ReRootMidpoint()
Re-root tree using midpoint-method.
TTreeIdx IterateOverSelNodes(int direction, bool highlight)
void Clusterize(CPhyloTreeScheme *scheme)
CPhyloTree * GetTree()
void SortLabel(bool ascending)
void UpdateSelectionSets(CPhyloTreeScheme *scheme)
virtual void ClearQueryResults()
Clear any current results from previous queries.
void ApplyAttributes(CBioTreeAttrReader::TAttrTable &attrs, CPhyloTreeScheme *scheme, const string &labelfmt="")
void ReRootEdge(TTreeIdx edge_child_node)
Re-root on the edge between the selected node and its parent.
void Relabel(CPhyloTreeScheme *scheme, string labelFmt)
void ReRoot(TTreeIdx root_idx)
Set the root node of the tree to the node at root_idx.
TTreeIdx NewNode(bool after=true)
void Remove(bool subtree=true)
void Sort(bool ascending)
CPhyloSelectionSetMgr & GetSelectionSets()
unsigned int GetNumNodes(void)
set< CPhyloNodeData::TID > CollapseByDistance(int leaf_count_target, SCollapsable *collapse_func)
Collapse, based on distance, enough nodes in the tree to get the total number of leaves down to the r...
void SetCollapsedLabels(const vector< CPhyloNodeData::TID > &node_ids)
Collapse all nodes in node_ids, doing relabeling if needed.
void SortLabelRange(bool ascending)
const CBioTreeFeatureDictionary & GetDictionary() const
CTreeGraphicsModel & GetModel()
Get model for rendering.
bool ClipboardEmpty() const
void SetCollapsedLabel(CPhyloTree::TTreeIdx idx)
Collapse single node, do any relabeling if needed.
bool Expanded() const
Return true if node is currently not collapsed.
void ExpandCollapse(CBioTreeFeatureDictionary &dict, CPhyloNodeData::TDisplayChildren chds)
Set this node to be expanded/collapsed.
bool CanExpandCollapse(CPhyloNodeData::TDisplayChildren chds)
Return true if node can have its expand/collapsed state changed to chds.
bool IsLeafEx() const
Return true if node is a leaf or is collapsed.
class CPhyloTreePane
void GoBack()
move to view position prior to most recent zoom/pan
virtual void SetContext(void)
CGlPane & GetPane()
void SetCurrRendererIdx(int idx)
IPhyloTreeRender * GetCurrRenderer(void)
void AddRenderer(CRef< IPhyloTreeRender > &&renderer)
void RemoveCurrentDataSource()
TRenderers & GetRenderers(void)
int GetCurrRendererIdx(void)
virtual I3DTexture * MMHH_GetTexture(float &xcoord_limit, float &ycoord_limit)
gets a texture and its coordinate limits for the minmap
vector< CRef< IPhyloTreeRender > > TRenderers
void GoForward()
return to view position that you just left through 'GoBack()'
void SaveCurrentView()
Record current zoom/pan so that user can undo/redo navigation.
virtual void Update(void)
bool CanGoForward() const
Return true if there are saved view positions you can nav forward to.
virtual TModelUnit SHH_GetModelByWindow(int z, EOrientation orient)
virtual void SoftUpdate(void)
bool CanGoBack() const
Return true if there are previous view positions you can nav back to.
virtual bool LoadCurrentSettings()
string & SetTooltipFormat(void)
void SetShowAllSelected(bool show_all)
const TLabelsVisibility & GetLabelVisibility(void) const
string & SetLabelFormat(void)
void SetAutoLabels(const TAutoLabels &al)
TZoomBehavior GetZoomBehavior(const string &renderer)
void SetLabelVisibility(const TLabelsVisibility &lv)
void SetZoomBehavior(const string &renderer, TZoomBehavior zb)
void SetLayoutIdx(int lidx)
const TAutoLabels & GetAutoLabels(void) const
void SetSelectionVisibility(const TSelectionVisibility sv)
virtual bool SaveCurrentSettings() const
class CPhyloTreeWidget
void OnUpdateSetGraphType1(wxUpdateUIEvent &evt)
void OnUpdateEditNode(wxUpdateUIEvent &evt)
void OnZoomXY(wxCommandEvent &evt)
void OnUpdateZoomSel(wxUpdateUIEvent &evt)
void OnClean(wxCommandEvent &evt)
void OnFilter(wxCommandEvent &evt)
void OnUpdateZoomXY(wxUpdateUIEvent &evt)
void OnEdit(wxCommandEvent &evt)
void OnGoForward(wxCommandEvent &evt)
virtual CGlWidgetPane * x_GetPane()
void OnSubtreeFromSelection(wxCommandEvent &evt)
void OnGoBack(wxCommandEvent &evt)
void SetCurrRenderer(int idx)
void OnSetGraphType2(wxCommandEvent &evt)
void OnUpdateZoomX(wxUpdateUIEvent &evt)
bool GetUseDistances() const
void OnRerootTree(wxCommandEvent &evt)
void OnEnableSavePdfCmdUpdate(wxUpdateUIEvent &evt)
void OnRotateLabels(wxCommandEvent &evt)
void OnAl(wxCommandEvent &evt)
void OnStopLayout(wxCommandEvent &evt)
void OnUpdateAl(wxUpdateUIEvent &evt)
void SetQueryPanel(CQueryParsePanel *queryPanel)
CRef< CPhyloTreeDataSource > m_DataSource
void OnContextMenu(wxContextMenuEvent &)
Command handlers.
void OnInfoTip(wxCommandEvent &evt)
void OnUpdateUseDistances(wxUpdateUIEvent &evt)
void OnUpdateZoomToSubtree(wxUpdateUIEvent &evt)
void OnClearSelection(wxCommandEvent &evt)
virtual CGlPane & GetPort()
implement these 2 functions in derived classes
virtual void x_Update()
Update handlers.
void OnUpdateSetGraphType4(wxUpdateUIEvent &evt)
CPhyloTreeWidget(wxWindow *parent, wxWindowID id=wxID_ANY, const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxDefaultSize, long style=wxTAB_TRAVERSAL, const wxString &name=wxT("panel"))
void OnUpdateSubtreeFromSelection(wxUpdateUIEvent &evt)
virtual CPhyloTreeDataSource * GetDS(void)
virtual void DlgOverlayFix(wxWindow *win)
this will forward events to fix opengl bug (windows) to pane
void OnUpdateZoomY(wxUpdateUIEvent &evt)
CVect2< float > m_PrevPos
void OnUpdateUseSplines(wxUpdateUIEvent &evt)
virtual void x_UpdatePane()
void OnZoomToSubtree(wxCommandEvent &evt)
void OnZoomY(wxCommandEvent &evt)
virtual void x_SoftUpdate()
void OnUpdateSetGraphType5(wxUpdateUIEvent &evt)
virtual void OnSetScaleXY(TModelUnit scale_x, const TModelPoint &point)
CPhyloTreePane * m_pPhyloTreePane
void OnUpdateSetMidpointRoot(wxUpdateUIEvent &evt)
bool GetRotateLabels() const
void OnEnablePrintCmdUpdate(wxUpdateUIEvent &evt)
virtual void QueryEnd(CMacroQueryExec *exec)
Re-enable any widgets disabled during the query.
void OnExpandChildren(wxCommandEvent &evt)
void OnTipActivated(wxCommandEvent &evt)
virtual void x_ZoomIn(int options)
Zoom functions.
void OnCollapseChildren(wxCommandEvent &evt)
void OnSelectAll(wxCommandEvent &evt)
void OnSort(wxCommandEvent &evt)
void IterateSelection(int dir)
Advance to previous/next selected row from query (in current sort order)
void OnUseDistances(wxCommandEvent &evt)
void SetPortLimits(const TModelRect &rect, bool bZoomAll=true)
void OnUpdateRerootTreeAtEdge(wxUpdateUIEvent &evt)
void OnUpdateGoBack(wxUpdateUIEvent &evt)
virtual void QueryStart()
Disable any widgets that the user should not use during the query.
void OnRerootTreeAtEdge(wxCommandEvent &evt)
void OnEditNode(wxCommandEvent &evt)
virtual void SetDataSourceNoUpdate(CPhyloTreeDataSource *p_ds)
void OnCollapseToViewport(wxCommandEvent &evt)
void OnUpdateExpandChildren(wxUpdateUIEvent &evt)
void OnUpdateSetGraphType2(wxUpdateUIEvent &evt)
void OnLoadAttributes(wxCommandEvent &evt)
void OnExportTree(wxCommandEvent &evt)
void OnSearchTip(wxCommandEvent &evt)
void OnShowAll(wxCommandEvent &evt)
virtual void SetSelectAll(bool b)
Set to true to show all rows selected by most recent query as selected.
void OnUpdateCollapseSelected(wxUpdateUIEvent &evt)
void OnUpdateRotateLabels(wxUpdateUIEvent &evt)
virtual void SetHideUnselected(bool b)
If true, only rows that were selected by prevous query will be shown.
void OnUpdateEdit(wxUpdateUIEvent &evt)
void OnPrint(wxCommandEvent &evt)
void OnUpdateCollapseChildren(wxUpdateUIEvent &evt)
virtual void x_SaveStates()
void OnHighlightEdges(wxCommandEvent &evt)
void OnUpdateLabels(wxUpdateUIEvent &evt)
virtual void RemoveCurrentDataSource()
void OnUpdateSortAscending(wxUpdateUIEvent &evt)
void SetRotateLabels(bool rot)
void OnZoomToSelection(wxCommandEvent &evt)
void SendEditEvent(EPhyloTreeEditCommand ec=eCmdSomethingEdited)
void OnUpdateSetGraphType3(wxUpdateUIEvent &evt)
void OnSetGraphType1(wxCommandEvent &evt)
void OnEditLabel(wxCommandEvent &evt)
void SetScheme(CPhyloTreeScheme &sl)
void OnTipDeactivated(wxCommandEvent &evt)
void OnUpdateEditLabel(wxUpdateUIEvent &evt)
virtual void x_ZoomOut(int options)
void OnSetTreeLabel(wxCommandEvent &evt)
void OnLabels(wxCommandEvent &evt)
void OnSaveImages(wxCommandEvent &evt)
void OnUpdateGoForward(wxUpdateUIEvent &evt)
void OnSetGraphType5(wxCommandEvent &evt)
void OnUpdateShowAll(wxUpdateUIEvent &evt)
CRef< CPhyloTreeScheme > m_pScheme
void OnSetMidpointRoot(wxCommandEvent &evt)
void OnSetEqualScale(wxCommandEvent &evt)
void OnUpdateStopLayout(wxUpdateUIEvent &evt)
void OnSetGraphType3(wxCommandEvent &evt)
vector< string > GetRenderersNames(void)
void OnZoomX(wxCommandEvent &evt)
void OnAddSelectionSet(wxCommandEvent &evt)
void SetUseDistances(bool bDist)
void SetRegistryPath(const string &reg_path)
virtual void x_SetPortLimits(void)
updates model limits of the Master CGlPane
void OnExportSelection(wxCommandEvent &evt)
void OnSetGraphType4(wxCommandEvent &evt)
void OnUpdateRerootTree(wxUpdateUIEvent &evt)
void OnFilterDistances(wxCommandEvent &evt)
static void RegisterCommands(CUICommandRegistry &cmd_reg, wxFileArtProvider &provider)
class CPhyloTreeWidget
void OnOpenPropertiesDlg(wxCommandEvent &evt)
virtual void RedrawDataSource()
Force tree to be re-masured and call layout.
CQueryParsePanel * m_QueryPanel
void OnZoomTip(wxCommandEvent &evt)
void SetPopupMenuItems(CMenuItem *itm)
EPhyloTreeEditCommand m_LastCommand
void OnSortAscending(wxCommandEvent &evt)
void OnSavePdf(wxCommandEvent &evt)
virtual void SetDataSource(CPhyloTreeDataSource *p_ds)
void OnCollapseSelected(wxCommandEvent &evt)
void OnEnableSaveImagesCmdUpdate(wxUpdateUIEvent &evt)
void OnUseSplines(wxCommandEvent &evt)
virtual void x_CreatePane(void)
factory method creating master pane, called form x_CreateControls()
Tree subclass also has functions and data needed for rendering and selection.
Definition: phylo_tree.hpp:52
void ClearSelection()
Sets selection state of all nodes to eNotSelected and clears m_Selected.
Definition: phylo_tree.cpp:242
void GetCurrentEdge(TTreeIdx &child_idx, TTreeIdx &parent_idx) const
Definition: phylo_tree.cpp:448
bool GetSelectedBoundary(CVect2< float > &ll, CVect2< float > &ur)
Return bounding rectangle from lower-left to upper-right of selected nodes (eSelected) and false if n...
Definition: phylo_tree.cpp:397
bool HasSelection() const
Definition: phylo_tree.hpp:201
CPhyloSelectionSetMgr & GetSelectionSets()
Definition: phylo_tree.hpp:326
void SetSelection(TTreeIdx idx, bool sel, bool sel_children=true, bool sel_parents=true)
Select or deselect the node at the specified index and, optionally, its parents and children as well.
Definition: phylo_tree.cpp:577
TTreeIdx GetCurrentNodeIdx() const
Return the index of the currently active node (may be Null()).
Definition: phylo_tree.hpp:268
void GetExplicitlySelectedAndNotCollapsed(vector< TTreeIdx > &esel) const
Returns only indices of nodes explicitly selected, but when a node is underneath a collapsed node,...
Definition: phylo_tree.cpp:279
CPhyloTreeNode & GetCurrentNode()
Get reference to currently active node. Throws exception if it's Null()
Definition: phylo_tree.cpp:434
bool HasCurrentNode() const
Return true if the currently active node is not Null()
Definition: phylo_tree.hpp:274
TTreeIdx FindNodeById(TID id) const
Return index of the node with the given id or Null().
Definition: phylo_tree.hpp:307
CBioTreeFeatureDictionary & GetFeatureDict()
Return feature dictionary.
Definition: phylo_tree.hpp:323
void GetSelected(vector< TTreeIdx > &sel) const
Returns indices of selected nodes.
Definition: phylo_tree.cpp:259
size_t GetNumSelected() const
Returns the number of selected nodes.
Definition: phylo_tree.hpp:151
CPhyloNodeData::TID TID
Definition: phylo_tree.hpp:55
bool HasCurrentEdge() const
Definition: phylo_tree.cpp:454
vector< TTreeIdx > GetAllCollapsed() const
Returns indices of nodes thate are currently collapsed.
Definition: phylo_tree.cpp:368
void SetZoomBehavior(bool zoomx, bool zoomy)
Enable/disable zoom in x && y.
Shows a basic example of how to print stuff in wx.
bool performPageSetup(const bool showPageSetupDialog)
shows the page setup dialog, OR sets up defaults
wxPrintData getPrintData()
returns the data obtained from the page setup dialog (or the defaults, if dialog was not shown)
void SetImage(CRef< CImage > img)
CQueryParsePanel.
string GetLastQuery() const
Get the text for the most recently executed query.
virtual void SaveSettings() const
virtual void SetRegistryPath(const string &reg_path)
bool IsSelectAll()
Return true if select all checkbox is checked.
void SetDataSource(IQueryDataSource *ds)
Set or update data source.
virtual void LoadSettings()
The tooltip window that displays tip information.
void SetScheme(CPhyloTreeScheme &sl)
Set rendering scheme for tree (some nodes need this to render)
float GetCurrentRotationAngle(const CGlPane &pane, const CPhyloTreeNode &n, bool &visible) const
Return node's label rotation angle for current zoom level.
TTreeIdx GetParent() const
Get node's parent.
Definition: tree_model.hpp:82
TData & GetValue()
Return the value object for the node.
Definition: tree_model.hpp:159
bool HasParent() const
Check if the node has a parent.
Definition: tree_model.hpp:90
bool IsLeaf() const
Report whether this is a leaf node.
Definition: tree_model.hpp:121
static TTreeIdx Null()
Static function that returns the null value.
Definition: tree_model.hpp:636
size_t GetNumNodes() const
Get the number of displayed nodes in current tree layout.
Definition: tree_model.hpp:223
static TTreeIdx Null()
Return the index value that represents a NULL node.
Definition: tree_model.hpp:678
TNodeType & GetNode(TTreeIdx idx)
Return a reference to the node at the given index.
Definition: tree_model.hpp:207
TTreeIdx GetRootIdx() const
Return the index of the root node.
Definition: tree_model.hpp:267
class CTreeQueryExec
bool GetTopologyChange() const
CFeatureEdit * GetFeatureEdit()
CSelectionSetEdit * GetSelectionEdit()
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
int RegisterCommand(CUICommand *cmd)
assumes ownership of the given object returns a command id (useful when registry is used for auto id ...
Definition: ui_command.cpp:198
@ eWidgetSelectionChanged
a view has been destroyed
Definition: view_event.hpp:55
@ eWidgetRangeChanged
notification from child to parent that the visible range has changed
Definition: view_event.hpp:58
string GetUpdatedLabel() const
void SetParams(CPhyloTree *tree, CPhyloTree::TTreeIdx node_idx)
void SetParams(CPhyloTree *tree, CPhyloTree::TTreeIdx node_idx, CFeatureEdit *updated_feature)
void SetParams(CPhyloTreeDataSource *ds, CPhyloTreeScheme *sl)
void SetParams(CPhyloTreeDataSource *ds, CPhyloTreeScheme *sl)
virtual bool SupportsDistanceRendering() const
bool GetDistRendering(void) const
bool GetSplinesRendering(void) const
virtual string GetDescription(void)=0
const double GetDimX(void)
bool GetHighlightEdges() const
const double GetDimY(void)
void SetActiveTooltipNode(int id)
id is the tip id of the tip that the users mouse is currently on, or -1
void SetHighlightEdges(bool enable)
void PointToNode(int id, wxRect tip_rect, float sec)
point to a particular node from a tooltip to help user spot it rectangle should be the tooltip screen...
virtual float DefaultNodeSize()
Return default node size according to scheme or 0 if not visible at current scale.
virtual float GetDefaultNodeSize(const CPhyloTreeNode *node) const
bool GetRotatedLabels(void) const
iterator_bool insert(const value_type &val)
Definition: map.hpp:165
Definition: set.hpp:45
const_iterator begin() const
Definition: set.hpp:135
size_type size() const
Definition: set.hpp:132
const_iterator end() const
Definition: set.hpp:136
virtual void RegisterFileAlias(const wxArtID &anId, const wxArtClient &aClient, const wxSize &aSize, const wxString &aName, long aType=wxBITMAP_TYPE_ANY, int anIndex=-1)
std::ofstream out("events_result.xml")
main entry point for tests
static const struct name_t names[]
#define false
Definition: bool.h:36
static FILE * f
Definition: readconf.c:23
static const column_t columns[]
Definition: utf8_2.c:22
char data[12]
Definition: iconv.c:80
#define ITERATE(Type, Var, Cont)
ITERATE macro to sequence through container elements.
Definition: ncbimisc.hpp:815
string
Definition: cgiapp.hpp:690
#define NULL
Definition: ncbistd.hpp:225
#define NCBI_THROW(exception_class, err_code, message)
Generic macro to throw an exception, given the exception class, error code and message string.
Definition: ncbiexpt.hpp:704
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
T & X()
Definition: vect2.hpp:107
T & Y()
Definition: vect2.hpp:109
void Read(CNcbiIstream &is, TAttrTable &attr_table)
Read attributes stream into the table.
GLdouble TModelUnit
Definition: gltypes.hpp:48
void SetMinScaleY(TModelUnit scale)
Definition: glpane.hpp:447
void SetModelLimitsRect(const TModelRect &R)
Definition: glpane.hpp:342
void SetRight(T right)
Definition: glrect.hpp:114
T X() const
Definition: glpoint.hpp:59
virtual CImage * GenerateImage()=0
T Height() const
Definition: glrect.hpp:90
CVect2< TModelUnit > GetScale() const
Definition: glpane.cpp:128
bool OpenOrtho()
Definition: glpane.hpp:427
void Init()
Definition: glrect.hpp:62
void SetBottom(T bottom)
Definition: glrect.hpp:113
T Top() const
Definition: glrect.hpp:84
T Bottom() const
Definition: glrect.hpp:82
TModelUnit UnProjectWidth(TVPUnit vp_w) const
Definition: glpane.cpp:755
TModelPoint UnProject(TVPUnit m_x, TVPUnit m_y) const
Definition: glpane.cpp:738
T Width() const
Definition: glrect.hpp:86
T Right() const
Definition: glrect.hpp:83
TVPRect & GetViewport(void)
Definition: glpane.hpp:332
void ScrollTo(const CVect2< TModelUnit > &pos, TModelUnit pctx, TModelUnit pcty)
Definition: glpane.cpp:626
void ZoomAll(int options=fZoomXY)
Definition: glpane.cpp:289
void SetScale(TModelUnit scale_x, TModelUnit scale_y, TModelPoint p_center)
Definition: glpane.cpp:361
void SetScaleRefPoint(TModelUnit scale_x, TModelUnit scale_y, TModelPoint p_ref)
Definition: glpane.cpp:382
void ZoomRect(const TModelRect &r)
Definition: glpane.cpp:348
TModelRect & GetModelLimitsRect(void)
Definition: glpane.hpp:347
void Init(T x, T y)
Definition: glpoint.hpp:58
T Left() const
Definition: glrect.hpp:81
void SetProportional(TModelRect &vr, TModelRect &mr)
Definition: glpane.cpp:612
T Y() const
Definition: glpoint.hpp:60
bool PtInRect(T x, T y) const
Definition: glrect.hpp:154
void SetAdjustmentPolicy(int adjust_x, int adjust_y)
Definition: glpane.hpp:383
void Inflate(T d_x, T d_y)
Definition: glrect.hpp:178
TModelUnit GetZoomAllScaleY(void) const
Definition: glpane.cpp:138
void Close(void)
Definition: glpane.cpp:178
TModelUnit UnProjectHeight(TVPUnit vp_h) const
Definition: glpane.cpp:768
void EnableZoom(bool en_x, bool en_y)
Definition: glpane.hpp:462
TModelUnit GetZoomAllScaleX(void) const
Definition: glpane.cpp:133
EZoomOptions
EZoomOptions flags control behavior of Zoom operations.
Definition: glpane.hpp:99
void SetLeft(T left)
Definition: glrect.hpp:112
TModelRect & GetVisibleRect(void)
Definition: glpane.hpp:357
void SetMinScaleX(TModelUnit scale)
Definition: glpane.hpp:442
CGlRect< TModelUnit > TModelRect
Definition: gltypes.hpp:54
TModelUnit GetScaleX(void) const
Definition: glpane.cpp:118
TModelUnit GetScaleY(void) const
Definition: glpane.cpp:123
void SetTop(T top)
Definition: glrect.hpp:115
void SetOriginType(EOriginType type_x, EOriginType type_y)
Definition: glpane.hpp:377
TVPPoint Project(TModelUnit m_x, TModelUnit m_y) const
Definition: glpane.cpp:691
@ eOriginBottom
Definition: glpane.hpp:74
@ eOriginLeft
Definition: glpane.hpp:72
@ fAdjustAll
Definition: glpane.hpp:94
@ fZoomX
Definition: glpane.hpp:100
@ fZoomY
Definition: glpane.hpp:101
@ fZoomXY
Definition: glpane.hpp:103
@ eHorz
Definition: gltypes.hpp:59
@ eVert
Definition: gltypes.hpp:60
virtual void RemoveListener(CEventHandler *listener)
Remove a listener.
int NcbiFileBrowser(SFileDlgData &data, wxWindow *parent=NULL)
show wxFileDialog and returns
virtual void AddListener(CEventHandler *listener, int pool_name=ePool_Default)
Add a listener.
virtual bool Send(CEvent *evt, EDispatch disp_how=eDispatch_Default, int pool_name=ePool_Default)
Sends an event synchronously.
@ eCmdZoomTip
search (scroll) window to tip element
Definition: command.hpp:126
@ eCmdSearchTip
tool tip pinned or unpinned
Definition: command.hpp:125
@ eCmdTipActive
User is interactively moving a tool tip.
Definition: command.hpp:131
@ eCmdInfoTip
zoom into tip element
Definition: command.hpp:127
@ eCmdTipInactive
Mouse entered a tip (highlight matching glyph)
Definition: command.hpp:132
@ eCmdForward
Definition: command.hpp:101
@ eCmdSaveImages
Definition: command.hpp:106
@ eCmdZoomIn
empty command
Definition: command.hpp:68
@ eCmdSavePdf
Definition: command.hpp:107
@ eCmdZoomOut
Definition: command.hpp:69
@ eCmdZoomAll
Definition: command.hpp:70
@ eCmdBack
Navigation commands.
Definition: command.hpp:100
@ eCmdZoomSel
Definition: command.hpp:73
@ eRelease
delete object when ownership end
Definition: event.hpp:111
@ eEvent_Message
message from one class to another
Definition: event.hpp:99
bool NotNull(void) const THROWS_NONE
Check if pointer is not null – same effect as NotEmpty().
Definition: ncbiobj.hpp:744
TObjectType * GetPointer(void) THROWS_NONE
Get pointer,.
Definition: ncbiobj.hpp:998
void Reset(void)
Reset reference object.
Definition: ncbiobj.hpp:773
bool IsNull(void) const THROWS_NONE
Check if pointer is null – same effect as Empty().
Definition: ncbiobj.hpp:735
TObjectType & GetObject(void)
Get object.
Definition: ncbiobj.hpp:1011
#define END_NCBI_SCOPE
End previously defined NCBI scope.
Definition: ncbistl.hpp:103
#define BEGIN_NCBI_SCOPE
Define ncbi namespace.
Definition: ncbistl.hpp:100
IO_PREFIX::ofstream CNcbiOfstream
Portable alias for ofstream.
Definition: ncbistre.hpp:500
IO_PREFIX::ifstream CNcbiIfstream
Portable alias for ifstream.
Definition: ncbistre.hpp:439
static int StringToInt(const CTempString str, TStringToNumFlags flags=0, int base=10)
Convert string to int.
Definition: ncbistr.cpp:630
unsigned int TBioTreeFeatureId
Feature Id.
Definition: bio_tree.hpp:60
TBioTreeFeatureId GetId(const string &feature_name) const
If feature is already registered returns its id by name.
Definition: bio_tree.cpp:209
TBioTreeFeatureId Register(const string &feature_name)
Register new feature, return its id.
Definition: bio_tree.cpp:160
const string & GetFeatureValue(TBioTreeFeatureId id) const
Get feature value by id.
Definition: bio_tree.cpp:69
const TFeatureDict & GetFeatureDict() const
Get reference on the internal map.
Definition: bio_tree.hpp:219
unsigned int
A callback function used to compare two keys in a database.
Definition: types.hpp:1210
<!DOCTYPE HTML >< html > n< header > n< title > PubSeq Gateway Help Page</title > n< style > n table
END_EVENT_TABLE()
int i
yy_size_t n
CMinPanelContainer::OnRestoreWindow EVT_UPDATE_UI_RANGE(eCmdCloseDockPanel, eCmdWindowRestore, CMinPanelContainer::OnUpdateWindowCommand) CMinPanelContainer
#define wxT(x)
Definition: muParser.cpp:41
Definition: fix_pub.hpp:45
const struct ncbi::grid::netcache::search::fields::SIZE size
#define abs(a)
Definition: ncbi_heapmgr.c:130
unsigned int a
Definition: ncbi_localip.c:102
Defines: CTimeFormat - storage class for time format.
T max(T x_, T y_)
T min(T x_, T y_)
double r(size_t dimension_, const Int4 *score_, const double *prob_, double theta_)
EPhyloTreeEditCommand
@ eCmdGrpExpandCollapse
@ eCmdTreeLabelSet
@ eCmdLabelFormatChanged
@ eCmdNodeExpandCollapse
@ eCmdTreeSorted
@ eCmdRenderingOptionsChanged
@ eEditCmdNone
@ eCmdFeaturesEdited
@ eCmdSortLabelRange
@ eCmdMoveDown
@ eCmdExportSelection
@ eCmdSubtreeFromSelected
@ eCmdNodePaste
@ eCmdEditNode
@ eClearSelection
@ eCmdExportSelected
@ eCmdEditLabel
@ eCmdSortAscending
@ eCmdSetGraphType2
@ eCmdRotateLabels
@ eCmdZoomToSubtree
@ eCmdLabelsHidden
@ eCmdZoomX
@ eCmdSort
@ eSelectAll
@ eCmdRemoveSubtree
@ eCmdRerootTreeAtEdge
@ eCmdLoadAttributes
@ eCmdSetGraphType5
@ eCmdClean
@ eCmdMoveUp
@ eCmdHighlightEdges
@ eCmdLabelsVisible
@ eCmdAlPaml
@ eCmdSetGraphType4
@ eCmdCollapseChildren
@ eCmdStopLayout
@ eCmdAlPhylip
@ eCmdUseSplines
@ eCmdNodeCut
@ eCmdMidpointRoot
@ eCmdRerootTree
@ eCmdSetTreeLabel
@ eCmdNodeNewChild
@ eCmdZoomY
@ eCmdFilter
@ eCmdSetGraphType3
@ eCmdZoomXY
@ eCmdSortDist
@ eCmdExportTree
@ eCmdUseDistances
@ eCmdMySettings
@ eCmdCollapseToViewport
@ eCmdAlNone
@ eCmdExpandChildren
@ eCmdFilterDistances
@ eCmdRemoveSelected
@ eCmdSetGraphType1
@ eCmdAddSelectionSet
@ eCmdLabelsForLeavesOnly
@ eCmdCollapseSelected
@ eCmdNodeNewParent
@ eCmdSortLabel
@ eCmdRemoveNode
EVT_MENU_RANGE(MID_SHOW_TITLES, MID_HIDE_TITLES, ViewerWindowBase::OnTitleView) EVT_MENU_RANGE(MID_ENABLE_EDIT
ViewerWindowBase::OnEditMenu ViewerWindowBase::OnJustification EVT_MENU(MID_SHOW_GEOM_VLTNS, ViewerWindowBase::OnShowGeomVltns) EVT_MENU(MID_FIND_PATTERN
static SLJIT_INLINE sljit_ins l(sljit_gpr r, sljit_s32 d, sljit_gpr x, sljit_gpr b)
void AddNode(CPhyloNodeData::TID id)
vector< CPhyloNodeData::TID > & GetIds()
void SetExpanded(CPhyloNodeData::TDisplayChildren ec)
Edits for one or more nodes.
vector< CUpdatedFeature > m_Updated
One entry for each updated node.
vector< CUpdatedFeature > & GetUpdated()
CBioTreeFeatureDictionary m_Dictionary
CBioTreeFeatureDictionary & GetDictionary()
Edits for one or more nodes.
CPhyloSelectionSetMgr & GetUpdatedSet()
CPhyloSelectionSetMgr & GetPrevSet()
Function to exclude nodes during a collapse those nodes that meet a priority threshold.
else result
Definition: token2.c:20
#define NULL_TREE_IDX
Global define for a NULL link in the tree used for comparison.
Definition: tree_model.hpp:51
size_t TTreeIdx
Bi-directionaly linked N way tree allocated in a contiguous memory block.
Definition: tree_model.hpp:48
#define WX_DEFINE_MENU(name)
New macros for defining menus for use with CUICommandRegistry.
Definition: ui_command.hpp:266
#define WX_SUBMENU(label)
Definition: ui_command.hpp:288
#define WX_END_MENU()
Definition: ui_command.hpp:294
#define WX_MENU_ITEM(cmd)
Definition: ui_command.hpp:270
#define WX_MENU_SEPARATOR()
Definition: ui_command.hpp:282
#define WX_END_SUBMENU()
Definition: ui_command.hpp:291
wxFileArtProvider * GetDefaultFileArtProvider()
Definition: wx_utils.cpp:334
wxString ToWxString(const string &s)
Definition: wx_utils.hpp:173
Modified on Fri Sep 20 14:58:03 2024 by modify_doxy.py rev. 669887