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

Go to the SVN repository for this file.

1 /* $Id: project_tree_panel.cpp 47479 2023-05-02 13:24:02Z ucko $
2  * ===========================================================================
3  *
4  * PUBLIC DOMAIN NOTICE
5  * National Center for Biotechnology Information
6  *
7  * This software/database is a "United States Government Work" under the
8  * terms of the United States Copyright Act. It was written as part of
9  * the author's official duties as a United States Government employee and
10  * thus cannot be copyrighted. This software/database is freely available
11  * to the public for use. The National Library of Medicine and the U.S.
12  * Government have not placed any restriction on its use or reproduction.
13  *
14  * Although all reasonable efforts have been taken to ensure the accuracy
15  * and reliability of the software and data, the NLM and the U.S.
16  * Government do not and cannot warrant the performance or results that
17  * may be obtained by using this software or data. The NLM and the U.S.
18  * Government disclaim all warranties, express or implied, including
19  * warranties of performance, merchantability or fitness for any particular
20  * purpose.
21  *
22  * Please cite the author in any work or product based on this material.
23  *
24  * ===========================================================================
25  *
26  * Authors: Andrey Yazhuk
27  *
28  * File Description:
29  *
30  */
31 
32 #include <ncbi_pch.hpp>
33 
35 
36 #include <gui/core/commands.hpp>
40 #include <gui/core/app_dialogs.hpp>
42 #include <gui/core/pt_project.hpp>
45 #include <gui/core/pt_view.hpp>
47 #include <gui/core/pt_root.hpp>
48 #include <gui/core/pt_folder.hpp>
50 #include <gui/core/pt_utils.hpp>
52 
56 
63 
67 
69 
70 
71 #include <wx/artprov.h>
72 #include <wx/sizer.h>
73 #include <wx/panel.h>
74 #include <wx/menu.h>
75 #include <wx/wupdlock.h>
76 #include <wx/frame.h>
77 #include <wx/msgdlg.h>
78 #include <wx/clipbrd.h>
79 #include <wx/settings.h>
80 
81 
84 
85 ///////////////////////////////////////////////////////////////////////////////
86 /// CProjectTreeViewDropTarget
88 : m_Panel(panel),
89  m_AcceptableData(false)
90 {
91  wxDataObjectComposite* composite = new wxDataObjectComposite();
92  composite->Add(new wxFileDataObject);
93  composite->Add(new CAppExplorerDataObject, true);
94  SetDataObject(composite);
95 }
96 
97 
98 wxDragResult CProjectTreeViewDropTarget::OnEnter(wxCoord x, wxCoord y, wxDragResult def)
99 {
100  wxDataObjectComposite* composite = dynamic_cast<wxDataObjectComposite*>(m_dataObject);
101  wxDataFormat format = composite->GetReceivedFormat();
102  if (format == wxDF_FILENAME)
103  return def;
104 
105  m_AcceptableData = true;
106  return OnDragOver(x, y, def);
107 }
108 
109 
110 wxDragResult CProjectTreeViewDropTarget::OnDragOver(wxCoord x, wxCoord y, wxDragResult def)
111 {
112  wxDataObjectComposite* composite = dynamic_cast<wxDataObjectComposite*>(m_dataObject);
113  wxDataFormat format = composite->GetReceivedFormat();
114  if (format == wxDF_FILENAME)
115  return def;
116 
117  if(m_AcceptableData) {
118  return m_Panel->OnDragOver(x, y, def);
119  }
120  return wxDragNone;
121 }
122 
123 
124 wxDragResult CProjectTreeViewDropTarget::OnData(wxCoord x, wxCoord y, wxDragResult def)
125 {
126  GetData();
127  wxDataObjectComposite* composite = dynamic_cast<wxDataObjectComposite*>(m_dataObject);
128  wxDataFormat format = composite->GetReceivedFormat();
129  if (format == wxDF_FILENAME) {
130  wxFileDataObject *fileDataObj = dynamic_cast<wxFileDataObject*>
131  (composite->GetObject(wxDF_FILENAME));
132 
133  if(fileDataObj && (def == wxDragMove || def == wxDragCopy || def == wxDragLink)) {
134  wxArrayString filenames = fileDataObj->GetFilenames();
135 
136  vector<wxString> names;
137  size_t n = filenames.GetCount();
138  names.reserve(n);
139  for( size_t i = 0; i < n; i++ ){
140  names.push_back (filenames[i]);
141  }
142 
144  }
145 
146  return def;
147  }
148  CAppExplorerDataObject* data_obj = dynamic_cast<CAppExplorerDataObject*>
149  (composite->GetObject(format));
150  if (data_obj) {
151  m_Panel->OnDrop(x, y, def, *data_obj);
152  return def;
153  }
154 
155  return def;
156 }
157 
158 BEGIN_EVENT_TABLE(CProjectTreeCtrl, wxTreeCtrl)
159  EVT_LEFT_UP( CProjectTreeCtrl::OnLeftDown)
160  EVT_KEY_UP(CProjectTreeCtrl::OnKeyUp)
161  EVT_MOTION( CProjectTreeCtrl::OnMove )
163 ///////////////////////////////////////////////////////////////////////////////
164 /// CProjectTreeCtrl
165 
167  : wxTreeCtrl()
168 {
169 }
170 
171 CProjectTreeCtrl::CProjectTreeCtrl(wxWindow *parent, wxWindowID id,
172  const wxPoint& pos,
173  const wxSize& size,
174  long style,
175  const wxValidator &validator,
176  const wxString& name)
177  : wxTreeCtrl(parent, id, pos, size, style, validator, name)
178 {
179 }
180 
181 wxTextCtrl *CProjectTreeCtrl::EditLabel(const wxTreeItemId& item, wxClassInfo* textCtrlClass)
182 {
183  wxTextCtrl* t = wxTreeCtrl::EditLabel(item, textCtrlClass);
184 
185  // In windows, when an item in the tree is selected for editing, all characters
186  // are selected by default. This is not true on the Mac, but the EditLabel function
187  // does return the edit control so we can use that to select the text. The
188  // documentation however says that EditLabel returns NULL. Restrict it to
189  // to MAC only since that is where it is needed and it is not validated on other platforms.
190 #ifdef NCBI_OS_DARWIN
191  if (t!=NULL)
192  t->SelectAll();
193 #endif
194 
195  return t;
196 }
197 
198 void CProjectTreeCtrl::OnLeftDown(wxMouseEvent& event)
199 {
200  CProjectTreePanel* tree_panel = dynamic_cast<CProjectTreePanel*>(GetParent());
201  if( tree_panel ){
202  wxTreeEvent tree_event;
203  tree_panel->OnSelectionChanged( tree_event );
204  }
205 
206  event.Skip();
207 }
208 
209 void CProjectTreeCtrl::OnKeyUp(wxKeyEvent& event)
210 {
211  // Keep track of cmd(osx)/ctrl(other os) key status since it changes whether
212  // drag and drop is a copy or a move (cmd/ctrl down=> copy)
213  CProjectTreePanel* tree_panel = dynamic_cast<CProjectTreePanel*>(GetParent());
214  bool b = event.CmdDown();
215  tree_panel->SetCopyMode(b);
216  event.Skip();
217 }
218 
219 void CProjectTreeCtrl::OnMove(wxMouseEvent& event)
220 {
221 #ifdef __WXOSX_COCOA__
222  // Tree's built-in drag and drop does not have a 'isdragging' event so
223  // we call the 'OnDragOver' on all mouse moves and it checks if a
224  // drag is actually in progress.
225  CProjectTreePanel* tree_panel = dynamic_cast<CProjectTreePanel*>(GetParent());
226  if( tree_panel ){
227  // The result is ignored (it is used by the other drag method - this method is only
228  // for the osx/cocoa case.)
229  wxDragResult ignore_me = wxDragMove;
230  wxCoord x,y;
231  event.GetPosition(&x,&y);
232  tree_panel->OnDragOver(x, y, ignore_me);
233  }
234 #endif
235 
236  event.Skip();
237 }
238 
239 ///////////////////////////////////////////////////////////////////////////////
240 /// CProjectTreePanel
241 
242 BEGIN_EVENT_TABLE(CProjectTreePanel, wxPanel)
243  EVT_CONTEXT_MENU(CProjectTreePanel::OnContextMenu)
244 
245  EVT_TREE_ITEM_COLLAPSED(wxID_ANY, CProjectTreePanel::OnItemExpandedCollapsed)
247  EVT_TREE_ITEM_ACTIVATED(wxID_ANY, CProjectTreePanel::OnItemActivated)
248  EVT_TREE_KEY_DOWN(wxID_ANY, CProjectTreePanel::OnTreeKeyDown)
249  EVT_TREE_BEGIN_LABEL_EDIT(wxID_ANY, CProjectTreePanel::OnBeginLabelEdit)
250  EVT_TREE_END_LABEL_EDIT(wxID_ANY, CProjectTreePanel::OnEndLabelEdit)
251 
252  EVT_TREE_SEL_CHANGED(wxID_ANY, CProjectTreePanel::OnSelectionChanged)
253 
254  EVT_TREE_BEGIN_DRAG(wxID_ANY, CProjectTreePanel::OnBeginDrag)
255  EVT_TREE_END_DRAG(wxID_ANY, CProjectTreePanel::OnEndDrag)
256 
257  EVT_LEFT_UP( CProjectTreePanel::OnLeftDown)
258 
265 
268 
271 
276 
281  EVT_MENU(wxID_PROPERTIES, CProjectTreePanel::OnProperties)
283 
286 
289 
292 
296 
297 
299 : m_DataObject(NULL),
300  m_Workbench(NULL),
301  m_Tree(NULL),
302  m_CopyMode(false)
303 {
304  Init();
305 }
306 
307 
309 {
311  delete m_DataObject;
312  m_DataObject = NULL;
313 }
314 
315 
316 void CProjectTreePanel::Create(wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size)
317 {
318 #ifdef __WXOSX_COCOA__
319  SetBackgroundStyle(wxBG_STYLE_COLOUR);
320  SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
321 #endif
322  wxPanel::Create(parent, id, pos, size, wxBORDER_NONE);
323  CreateControls();
324 }
325 
326 
328 {
329 }
330 
331 
333 {
334  wxSizer* sizer = new wxBoxSizer(wxVERTICAL);
335  SetSizer(sizer);
336 
337  long style = wxTR_HAS_BUTTONS | wxTR_MULTIPLE | wxTR_EDIT_LABELS
338  | wxTR_HIDE_ROOT | wxBORDER_NONE | wxTR_GBENCH_LINES
339  ;
340 
341  // create Tree Control
342  m_Tree = new CProjectTreeCtrl(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, style);
343  sizer->Add(m_Tree, 1, wxEXPAND);
344 
345  m_Tree->SetDropTarget(new CProjectTreeViewDropTarget(this));
346  m_Tree->SetImageList(&PT::CPTIcons::GetInstance().GetImageList());
347 }
348 
349 
351 {
352  m_Workbench = workbench;
353  if (m_Workbench) {
355  } else {
356  wxTreeItemId rootId = m_Tree->GetRootItem();
357  if (rootId.IsOk()) {
358  m_Tree->DeleteChildren(rootId);
360  }
361  }
362 }
363 
364 WX_DEFINE_MENU(kContextMenu)
365  WX_MENU_SEPARATOR_L("Top Actions")
366  WX_MENU_SEPARATOR_L("Actions")
367  WX_MENU_SEPARATOR_L("Edit")
368  WX_MENU_SEPARATOR_L("Properties")
369 WX_END_MENU()
370 
371 
372 void CProjectTreePanel::OnContextMenu(wxContextMenuEvent& event)
373 {
374  SetFocus();
375 
376  CUICommandRegistry& cmd_reg = m_Workbench->GetUICommandRegistry();
377 
378  PT::TItems sel_items;
379  GetSelectedItems(sel_items);
380 
381  // create menu backbone
382  unique_ptr<wxMenu> menu(cmd_reg.CreateMenu(kContextMenu));
383 
385  contrib = x_GetContextMenu(sel_items);
386  wxMenu* obj_menu = contrib.first;
387  if (obj_menu) {
388  Merge(*menu, *obj_menu);
389  delete obj_menu;
390  /// register provided handler
391  wxEvtHandler* handler = contrib.second;
392  if (handler) {
393  m_ContributedHandlers.push_back(handler);
394  PushEventHandler(handler);
395  }
396  }
397 
398  // get contributed menus
399  vector< CIRef<IExplorerItemCmdContributor> > contributors;
400  static string id("project_tree_view::context_menu::item_cmd_contributor");
401  GetExtensionAsInterface(id, contributors);
402 
403  // Merge contributed menus into the main Menu
404  for( size_t i = 0; i < contributors.size(); i++ ) {
405  IExplorerItemCmdContributor& obj = *contributors[i];
407  contrib = obj.GetMenu(*m_Tree, sel_items);
408  /// update menu
409  wxMenu* obj_menu = contrib.first;
410  if(obj_menu) {
411  Merge(*menu, *obj_menu);
412  delete obj_menu;
413 
414  /// register provided handler
415  wxEvtHandler* handler = contrib.second;
416  if(handler) {
417  m_ContributedHandlers.push_back(handler);
418  PushEventHandler(handler);
419  }
420  } else {
421  _ASSERT(contrib.second == NULL);
422  delete contrib.second;
423  }
424  }
425 
426  CleanupSeparators(*menu); // Remove empty groups
427 
428  PopupMenu(menu.get());
429 
430 
431  /// disconnect and destroy contributed handlers
432  for( size_t i = 0; i < m_ContributedHandlers.size(); i++ ) {
433  wxEvtHandler* handler = PopEventHandler();
434  _ASSERT(handler == m_ContributedHandlers[i]);
435  delete handler;
436  }
437  m_ContributedHandlers.clear();
438 }
439 
441 {
442  if (!m_WS || projectId == -1) return;
443 
444  CGBDocument* doc = dynamic_cast<CGBDocument*>(m_WS->GetProjectFromId(projectId));
445  if (!doc || !doc->IsLoaded()) return;
446  const CGBProject_ver2* gbproj = dynamic_cast<const CGBProject_ver2*>(&doc->GetProject());
447 
448  vector< CIRef<IProjectView> > views = doc->GetViews();
449 
450  NON_CONST_ITERATE(vector< CIRef<IProjectView> >, it_view, views) {
451  IProjectView& view = **it_view;
452  TConstScopedObjects objs;
453  view.GetMainObject(objs);
454  if (objs.size() == 1 && objs[0].object == gbproj) {
455  CEventHandler* handler = dynamic_cast<CEventHandler*>(&view);
456  if (handler) {
458  handler->Send(ev);
459  }
460  }
461  }
462 }
463 
464 static void s_RemoveDependentItems(wxTreeCtrl& treeCtrl, wxArrayTreeItemIds& items)
465 {
466  // build an index for fast look-up
467  set<wxTreeItemId> items_set;
468  ITERATE (wxArrayTreeItemIds, it, items)
469  items_set.insert(*it);
470 
471  wxArrayTreeItemIds topItems;
472  ITERATE (wxArrayTreeItemIds, it, items) {
473  wxTreeItemId parent = treeCtrl.GetItemParent(*it);
474  while (parent.IsOk()) {
475  if (items_set.find(parent) != items_set.end())
476  break;
477  parent = treeCtrl.GetItemParent(parent);
478  }
479 
480  if (!parent.IsOk())
481  topItems.push_back(*it);
482  }
483 
484  items = topItems;
485 }
486 
488 {
489  wxArrayTreeItemIds sel_ids;
490  m_Tree->GetSelections(sel_ids);
491  if (sel_ids.empty()) return 0;
492 
493  ITERATE (wxArrayTreeItemIds, it, sel_ids) {
494  PT::CItem* item = x_GetExplorerItem(*it);
495  if (!item->CanCopyToClipboard(*m_Tree))
496  return 0;
497  }
498  s_RemoveDependentItems(*m_Tree, sel_ids);
499 
500  return new CAppExplorerDataObject (m_Tree, sel_ids, cut);
501 }
502 
504 {
505  CAppExplorerDataObject* data_object = x_CreateDataObject(cut);
506  if (!data_object) return;
507 
508  wxClipboardLocker clipLocker;
509  if (!clipLocker) return;
510  wxTheClipboard->SetData(data_object);
511 }
512 
514 {
515  wxClipboardLocker clipLocker;
516  if (!clipLocker) return;
517 
518  if (wxTheClipboard->IsSupported(CAppExplorerDataObject::m_ItemsFormat))
519  wxTheClipboard->Clear();
520 }
521 
523 {
524  //CStopWatch sw; sw.Start();
526 
528 
530  m_WS = prj_srv->GetGBWorkspace();
531 
532  wxTreeItemId rootId = m_Tree->GetRootItem();
533  if (rootId.IsOk()) {
534  m_Tree->DeleteChildren(rootId);
535  } else {
536  PT::CRoot* item = new PT::CRoot(0);
537  rootId = m_Tree->AddRoot(wxT(""), -1, -1, item);
538  item->SetTreeItemId(rootId);
539  }
540 
542 
543  PT::CRoot* rootItem = x_GetRootItem();
544  rootItem->Initialize(*m_Tree, m_WS);
545  rootItem->UpdateDataSources(*m_Tree, *m_Workbench);
546  rootItem->UpdateAllViews(*m_Tree, m_WS);
547  //LOG_POST(Info << "CProjectTreePanel::ReloadProjectTree()" << int(1000 * sw.Elapsed()) << " ms");
548 }
549 
551 {
552  wxTreeItemId rootId = m_Tree->GetRootItem();
553  if (!rootId.IsOk()) return 0;
554  return dynamic_cast<PT::CRoot*>(m_Tree->GetItemData(rootId));
555 }
556 
558 {
559  PT::CRoot* rootItem = x_GetRootItem();
560  return rootItem ? rootItem->GetWorkspaceItem(*m_Tree) : 0;
561 }
562 
564 {
565  wxTreeItemData* data = m_Tree->GetItemData(id);
566  PT::CItem* item = dynamic_cast<PT::CItem*>(data);
567  _ASSERT(item);
568  return item;
569 }
570 
571 
572 // returns selection as a vector of pointers to CItem
574 {
575  wxArrayTreeItemIds sel_ids;
576  m_Tree->GetSelections(sel_ids);
577 
578  x_GetItemsFromIds(sel_ids, items);
579 }
580 
581 void CProjectTreePanel::x_CollectItemIds( wxTreeItemId root, wxArrayTreeItemIds &ids )
582 {
583  wxTreeItemIdValue cookie;
584  wxTreeItemId search;
585  wxTreeItemId item = m_Tree->GetFirstChild( root, cookie );
586  wxTreeItemId child;
587 
588  while( item.IsOk() )
589  {
590  ids.Add(item);
591  if( m_Tree->ItemHasChildren( item ) )
592  {
593  x_CollectItemIds( item, ids );
594  }
595  item = m_Tree->GetNextChild( root, cookie);
596  }
597 }
598 
599 // returns selection as a vector of pointers to CItem
601 {
602  wxArrayTreeItemIds ids;
603  x_CollectItemIds(m_Tree->GetRootItem(), ids);
604  x_GetItemsFromIds(ids, items);
605 }
606 
607 
608 void CProjectTreePanel::x_GetItemsFromIds(const wxArrayTreeItemIds& ids,
609  PT::TItems& items)
610 {
611  for( size_t i = 0; i < ids.GetCount(); i++ ) {
612  wxTreeItemId id = ids[i];
613  PT::CItem* item = x_GetExplorerItem(id);
614  items.push_back(item);
615  }
616 }
617 
618 
620 {
621  wxArrayTreeItemIds sel_ids;
622  m_Tree->GetSelections(sel_ids);
623 
624  if(sel_ids.size() == 1) {
625  PT::CItem* item = x_GetExplorerItem(sel_ids[0]);
626  return item;
627  }
628  return NULL;
629 }
630 
631 
633 {
634  PT::TItems sel_items;
635  GetSelectedItems(sel_items);
636 
637  NON_CONST_ITERATE(PT::TItems, it, sel_items) {
638  PT::CItem& item = **it;
639  PT::CProject* project_item = dynamic_cast<PT::CProject*>(&item);
640  if(project_item) {
641  TProjectId id = project_item->GetData()->GetId();
642  ids.push_back(id);
643  }
644  }
645 }
646 
647 
649 {
650  wxTreeItemId id = event.GetItem();
651  PT::CItem* item = x_GetExplorerItem(id);
653 }
654 
655 
656 void CProjectTreePanel::OnItemActivated(wxTreeEvent& event)
657 {
658  wxTreeItemId id = event.GetItem();
659  if (!id.IsOk()) return;
660 
661  PT::CItem* item = x_GetExplorerItem(id);
662  if (!item) return;
663 
665 
666  int type = item->GetType();
667 
668  switch(type) {
669  case PT::eWorkspace:
670  // OnProperties(item);
671  break;
672  case PT::eProjectFolder: {{
673  // OnProperties(item);
674  PT::CProjectFolder* folder = dynamic_cast<PT::CProjectFolder*>(item);
675  if (folder->IsCompacted()) {
676  auto projectId = PT::GetProjectId(*m_Tree, *item);
677  if (m_WS && projectId != -1) {
678  try {
679  CGBDocument* doc = dynamic_cast<CGBDocument*>(m_WS->GetProjectFromId(projectId));
680  wxBusyCursor wait;
681  wxWindowUpdateLocker locker(m_Tree);
682  GUI_AsyncExec([&](ICanceled& cancel) {
683  folder->ExpandCompacted(*m_Tree, id, *doc, m_Workbench->GetStatusBarService(), &cancel);
684  }, wxT("Expanding project items..."));
685  }
686  NCBI_CATCH("CProjectTreePanel::OnItemActivated");
687  }
688  }
689  break;
690  }}
691 
692  case PT::eProject:
693  break;
694 
695  case PT::eProjectItem: {{
696  menu_srv->AddPendingCommand(eCmdOpenViewDefault);
697  break;
698  }}
699  case PT::eView: {{
700  menu_srv->AddPendingCommand(eCmdActivateClients);
701  break;
702  }}
703  case PT::eDataSource: {{
704  PT::CDataSource* ds_item =
705  dynamic_cast<PT::CDataSource*>(item);
706 
707  if(ds_item) {
708  CIRef<IUIDataSource> ds = ds_item->GetData();
709  int def_command = ds->GetDefaultCommand();
710  if( def_command ){
711  menu_srv->AddPendingCommand(def_command);
712 
713  wxEvtHandler* handler = ds->CreateEvtHandler();
714  if( handler ){
715  wxCommandEvent event(wxEVT_COMMAND_MENU_SELECTED, def_command);
716  handler->ProcessEvent(event);
717 
718  delete handler;
719  }
720  }
721  }
722  }}
723  case PT::eHiddenItems: {{
726  }}
727  default:
728  break;
729  }
730 }
731 
732 
734 {
736  Send(&evt, ePool_Parent);
737 }
738 
739 void CProjectTreePanel::OnLeftDown(wxMouseEvent& event)
740 {
741  event.Skip();
742 }
743 
744 
745 // this functions inititates and performs the whole D&D session
746 void CProjectTreePanel::OnBeginDrag(wxTreeEvent& event)
747 {
748  // create a wxDataObject for the selected items
750  if (!m_DataObject) return;
751 
752  // reset D&D state
753  m_DropItemId = wxTreeItemId();
754  m_DropTimerActive = false;
755 
756  // For osx cocoa, we use wxTreeCtrl's built-in D&D. For others we continue to
757  // use the original (general) drag and drop and approach. They seem
758  // to be equivalent in behavior in this case afik)
759 #ifdef __WXOSX_COCOA__
760  // Tree D&D does not take over the event loop...
761  event.Allow();
762 #else
763  wxDropSource source(*m_DataObject, this);
764 
765  // the whole D&D session happens in this call
766  wxDragResult res = source.DoDragDrop(wxDragCopy | wxDragMove);
767 
768  // reset D&D state
769  if(m_DropItemId.IsOk()) {
770  m_Tree->SetItemDropHighlight(m_DropItemId, false);
771  }
772  m_DropItemId = wxTreeItemId();
774  m_DropTimerActive = false;
775 
776  delete m_DataObject;
777  m_DataObject = NULL;
778 
779  // at this point session has ended and Drag Traget already has done all necessary work
780  if(res == wxDragError) {
781  NcbiErrorBox("Unexpected error while performing D&D");
782  ERR_POST("CProjectTreePanel::OnBeginDrag() - Unexpected error while performing D&D");
783  }
784 #endif
785 }
786 
787 // end drag for the trees built-in drag and drop (used for osx cocoa)
788 // never called by other os's since they don't call event.Allow() when
789 // D&D starts.)
790 void CProjectTreePanel::OnEndDrag(wxTreeEvent& event)
791 {
792  int flags = 0;
793  wxTreeItemId id = m_Tree->HitTest( event.GetPoint(), flags);
794 
795  if( id.IsOk() ){
796  PT::CItem* item = x_GetExplorerItem(id);
797  PT::TItems items;
798  m_DataObject->GetItems(*m_Tree, items);
799  item->Paste(*m_Tree, items, !m_CopyMode);
800  }
801 
802  // reset D&D state
803  m_DropItemId = wxTreeItemId();
805  m_DropTimerActive = false;
806  delete m_DataObject;
807  m_DataObject = NULL;
808 }
809 
810 void CProjectTreePanel::x_SetSelections(wxArrayTreeItemIds& ids)
811 {
812  wxArrayTreeItemIds sel_ids;
813  m_Tree->GetSelections(sel_ids);
814 
815  //reset current selection
816  for( size_t i = 0; i < sel_ids.size(); i++ ) {
817  wxTreeItemId id = sel_ids[i];
818  m_Tree->SelectItem(id, false);
819  }
820  // set new selection
821  for( size_t i = 0; i < ids.size(); i++ ) {
822  wxTreeItemId id = ids[i];
823  m_Tree->SelectItem(id, true);
824  }
825 }
826 
827 
828 wxDragResult CProjectTreePanel::OnDragOver(wxCoord x, wxCoord y, wxDragResult def)
829 {
830  // If null, a drag is not in progress.
831  if (m_DataObject == NULL)
832  return def;
833 
834  static const double kExpandDelay = 0.5;
835  // get the item under the mouse pointer
836  int flags = 0;
837  wxTreeItemId id = m_Tree->HitTest(wxPoint(x, y), flags);
838 
839  if(id != m_DropItemId) {
840  // current item have changed - need to update highlight and "expand" timer
841 
842  // stop the timer
844  m_DropTimerActive = false;
845 
846  // change highlight
847  if(m_DropItemId.IsOk()) {
848  m_Tree->SetItemDropHighlight(m_DropItemId, false);
849  }
850 
851  m_DropItemId = id;
852 
853  if(m_DropItemId.IsOk()) {
854  m_Tree->SetItemDropHighlight(m_DropItemId, true);
855 
856  // launch "expand" timer
857  if(m_Tree->ItemHasChildren(m_DropItemId) && ! m_Tree->IsExpanded(m_DropItemId)) {
858  // start the timer
860  m_DropTimerActive = true;
861  }
862  }
863  } else if(m_DropTimerActive) {
864  // current item has not changed and timer is active
865  if(m_DropItemTimer.Elapsed() >= kExpandDelay) {
866  m_Tree->Expand(m_DropItemId);
867 
869  m_DropTimerActive = false;
870  }
871  }
872 
873  if(id.IsOk()) {
874  PT::CItem* item = x_GetExplorerItem(id);
875  if (item->CanPaste(*m_Tree))
876  return def;
877  }
878  return wxDragNone;
879 }
880 
881 // drag end for standard (general) drag and drop used on non-cocoa platforms
883  wxCoord x, wxCoord y, wxDragResult def, CAppExplorerDataObject& data
884 ){
885  if( def == wxDragCopy || def == wxDragMove ){
886  int flags = 0;
887  wxTreeItemId id = m_Tree->HitTest( wxPoint(x, y), flags );
888 
889  if( id.IsOk() ){
890  PT::CItem* item = x_GetExplorerItem(id);
891 
892  if (item->CanPaste(*m_Tree)) {
893  bool move = (def == wxDragMove);
894  PT::TItems items;
895  data.GetItems(*m_Tree, items);
896  item->Paste(*m_Tree, items, move);
897  return def;
898  }
899  }
900  }
901 
902  return wxDragNone;
903 }
904 
905 void CProjectTreePanel::OnTreeKeyDown(wxTreeEvent& event)
906 {
907  const wxKeyEvent& keyEvent = event.GetKeyEvent();
908  m_CopyMode = keyEvent.CmdDown();
909 
910  if (WXK_F2 != keyEvent.GetKeyCode() || keyEvent.GetModifiers() != wxMOD_NONE) {
911  event.Skip();
912  return;
913  }
914 
915  wxArrayTreeItemIds items;
916  if (m_Tree->GetSelections(items) != 1)
917  return;
918 
919  wxTreeItemId item = items[0];
920  if (!item.IsOk())
921  return;
922 
923  (void)m_Tree->EditLabel(item);
924 }
925 
926 void CProjectTreePanel::OnBeginLabelEdit(wxTreeEvent& event)
927 {
928  wxTreeItemId item = event.GetItem();
929  PT::CItem* eitem = x_GetExplorerItem(item);
930  eitem->BeginLabelEdit(*m_Tree, event);
931 }
932 
933 void CProjectTreePanel::OnEndLabelEdit(wxTreeEvent& event)
934 {
935  wxTreeItemId item = event.GetItem();
936  PT::CItem* eitem = x_GetExplorerItem(item);
937  if (!eitem)
938  return;
939 
940  if (eitem->EndLabelEdit(*m_Tree, event))
942 }
943 
944 void CProjectTreePanel::OnPaste(wxCommandEvent& event)
945 {
946  PT::TItems sel_items;
947  GetSelectedItems(sel_items);
948 
949  if (sel_items.size() == 1) {
950  wxClipboardLocker clipLocker;
951  if (!clipLocker) return;
952 
953  CAppExplorerDataObject data_object;
954  if (!wxTheClipboard->GetData(data_object))
955  return;
956  wxTheClipboard->Clear();
957 
958  PT::TItems items;
959  data_object.GetItems(*m_Tree, items);
960  sel_items[0]->Paste(*m_Tree, items, data_object.IsCut());
961  } else _ASSERT(false);
962 }
963 
964 void CProjectTreePanel::OnUpdatePaste(wxUpdateUIEvent& event)
965 {
966  PT::TItems sel_items;
967  GetSelectedItems(sel_items);
968 
969  bool en = false;
970  if (sel_items.size() == 1 && sel_items[0]->CanPaste(*m_Tree)) {
971  wxClipboardLocker clipLocker;
972  if (!!clipLocker)
973  en = wxTheClipboard->IsSupported(CAppExplorerDataObject::m_ItemsFormat);
974  }
975  event.Enable(en);
976 }
977 
978 void CProjectTreePanel::OnCut(wxCommandEvent& event)
979 {
980  x_CutOrCopyToClipboard (true);
981 }
982 
983 void CProjectTreePanel::OnUpdateCut(wxUpdateUIEvent& event)
984 {
985  PT::TItems sel_items;
986  GetSelectedItems(sel_items);
987 
988  if (sel_items.empty()) {
989  event.Enable(false);
990  return;
991  }
992 
993  ITERATE (PT::TItems, it, sel_items) {
994  if (!(*it)->CanCutToClipboard(*m_Tree)) {
995  event.Enable(false);
996  return;
997  }
998  }
999 
1000  event.Enable(true);
1001 }
1002 
1003 
1004 void CProjectTreePanel::OnCopy(wxCommandEvent& event)
1005 {
1006  x_CutOrCopyToClipboard (false);
1007 }
1008 
1009 
1010 void CProjectTreePanel::OnUpdateCopy(wxUpdateUIEvent& event)
1011 {
1012  PT::TItems sel_items;
1013  GetSelectedItems(sel_items);
1014 
1015  if (sel_items.empty()) {
1016  event.Enable(false);
1017  return;
1018  }
1019 
1020  ITERATE (PT::TItems, it, sel_items) {
1021  if (!(*it)->CanCopyToClipboard(*m_Tree)) {
1022  event.Enable(false);
1023  return;
1024  }
1025  }
1026 
1027  event.Enable(true);
1028 }
1029 
1030 void CProjectTreePanel::OnRemove(wxCommandEvent& event)
1031 {
1032  wxArrayTreeItemIds sel_ids;
1033  m_Tree->GetSelections(sel_ids);
1034  if (sel_ids.empty()) return;
1035 
1036  wxString quest;
1037  if (sel_ids.size() == 1) {
1038  quest = wxT("Delete selected item?");
1039  } else {
1040  quest.Printf(wxT("Delete %lu selected items?"), (unsigned long)sel_ids.size());
1041  }
1042  int answer =
1043  wxMessageBox(quest, wxT("Confirm"),
1044  wxYES_NO | wxCANCEL | wxICON_QUESTION );
1045  if (answer != wxYES)
1046  return;
1047 
1048  s_RemoveDependentItems(*m_Tree, sel_ids);
1049 
1050  PT::TItems sel_items;
1051  x_GetItemsFromIds(sel_ids, sel_items);
1052 
1053  set<TProjectId> projIds;
1054 
1055  typedef map<PT::CProject*, vector<CProjectItem*> > TItemMap;
1056  TItemMap toDelete;
1057 
1058  NON_CONST_ITERATE (PT::TItems, it, sel_items) {
1059  if ((*it)->GetType() == PT::eProjectItem) {
1060  PT::CProjectItem& item = static_cast<PT::CProjectItem&>(**it);
1061  PT::CProject* project = PT::GetProject (*m_Tree, **it);
1062  if (project) {
1063  CRef<CProjectItem> prjItem = item.GetData();
1064  toDelete[project].push_back(prjItem);
1065  }
1066  } else {
1067  auto projId = PT::GetProjectId(*m_Tree, **it);
1068  if ((*it)->DoRemove(*m_Tree))
1069  projIds.insert(projId);
1070  }
1071  }
1072 
1073  ITERATE(TItemMap, it, toDelete) {
1074  CGBDocument* doc = it->first->GetData();
1075  if (doc) {
1076  if (doc->RemoveProjectItems(it->second)) {
1077  projIds.insert(doc->GetId());
1078  }
1079  }
1080  }
1081 
1082  for (const auto id : projIds)
1084 
1085  PT::CWorkspace* wsItem = x_GetWorkspaceItem();
1086  if (wsItem) wsItem->UpdateHiddenItems(*m_Tree);
1087  m_Tree->UnselectAll();
1088 }
1089 
1090 
1091 void CProjectTreePanel::OnUpdateRemove(wxUpdateUIEvent& event)
1092 {
1093  // check if we can delete this selection
1094  PT::TItems sel_items;
1095  GetSelectedItems(sel_items);
1096  if (sel_items.empty()) {
1097  event.Enable(false);
1098  return;
1099  }
1100 
1101  ITERATE(PT::TItems, it, sel_items) {
1102  if (!(*it)->CanDoRemove(*m_Tree)) {
1103  event.Enable(false);
1104  return;
1105  }
1106  }
1107 
1108  event.Enable(true);
1109 }
1110 
1112 {
1115 }
1116 
1118 {
1119  event.SetText(PT::sm_HideDisabledItems ? wxT("Show Disabled Items") : wxT("Hide Disabled Items"));
1120  event.Enable(true);
1121 }
1122 
1123 void CProjectTreePanel::OnEnableDisable(wxCommandEvent& event)
1124 {
1125  PT::TItems sel_items;
1126  GetSelectedItems(sel_items);
1127 
1128  PT::CWorkspace* wsItem = x_GetWorkspaceItem();
1129  if (!wsItem) return;
1130 
1131  typedef map<PT::CProject*, vector<CProjectItem*> > TItemMap;
1132  TItemMap toEnable, toDisable;
1133 
1134  NON_CONST_ITERATE(PT::TItems, it, sel_items) {
1135  if ((*it)->GetType() == PT::eProjectItem) {
1136  PT::CProjectItem& item = static_cast<PT::CProjectItem&>(**it);
1137  PT::CProject* project = PT::GetProject (*m_Tree, **it);
1138  if (project) {
1139  CRef<CProjectItem> prjItem = item.GetData();
1140  if (prjItem->IsEnabled())
1141  toDisable[project].push_back(prjItem);
1142  else
1143  toEnable[project].push_back(prjItem);
1144  }
1145  }
1146  }
1147 
1148  ITERATE(TItemMap, it, toEnable) {
1149  CGBDocument* doc = it->first->GetData();
1150  if (doc) {
1151  doc->AttachProjectItems(it->second);
1152  it->first->UpdateProjectItems(*m_Tree);
1153  }
1154  }
1155 
1156  ITERATE(TItemMap, it, toDisable) {
1157  CGBDocument* doc = it->first->GetData();
1158  if (doc) {
1159  doc->DetachProjectItems(it->second);
1160  it->first->UpdateProjectItems(*m_Tree);
1161  }
1162  }
1163 
1164  wsItem->UpdateHiddenItems(*m_Tree);
1165 }
1166 
1167 void CProjectTreePanel::OnUpdateEnableDisable(wxUpdateUIEvent& event)
1168 {
1169  PT::TItems sel_items;
1170  GetSelectedItems(sel_items);
1171 
1172  int types = PT::GetItemTypes(sel_items);
1173  if (types == PT::eProjectItem) {
1174  // only Project Items or Data Loaders
1175  bool en = false, dis = false;
1176  for (size_t i = 0; i < sel_items.size(); i++) {
1177  PT::CProjectItem& item = static_cast<PT::CProjectItem&>(*sel_items[i]);
1178  if(item.GetData()->IsEnabled()) {
1179  en = true;
1180  } else {
1181  dis = true;
1182  }
1183  }
1184  wxString text = (en == dis) ? wxT("Enable / Disable") : (en ? wxT("Disable") : wxT("Enable"));
1185  event.SetText(text);
1186  event.Enable(true);
1187  } else {
1188  event.Enable(false);
1189  }
1190 }
1191 
1192 void CProjectTreePanel::OnNewFolder(wxCommandEvent& event)
1193 {
1194  PT::TItems sel_items;
1195  GetSelectedItems(sel_items);
1196 
1197  if(sel_items.size() == 1) {
1198  PT::CItem& item = *sel_items[0];
1199  item.DoNewFolder(*m_Tree);
1200  } else _ASSERT(false);
1201 }
1202 
1203 
1204 void CProjectTreePanel::OnUpdateNewFolder(wxUpdateUIEvent& event)
1205 {
1206  PT::TItems sel_items;
1207  GetSelectedItems(sel_items);
1208 
1209  bool en = false;
1210  if (sel_items.size() == 1)
1211  en = sel_items[0]->CanDoNewFolder();
1212  event.Enable(en);
1213 }
1214 
1215 static void s_ItemsToViews(PT::TItems& items, vector<CIRef<IProjectView> >& views)
1216 {
1217  set<IProjectView*> st_sel_views; // to avoid dupplication
1218 
1219  for (size_t i = 0; i < items.size(); ++i) {
1220  PT::CItem& item = *items[i];
1221  if (item.GetType() == PT::eView) {
1222  IProjectView* view = static_cast<PT::CView*>(&item)->GetData();
1223  st_sel_views.insert(view);
1224  }
1225  }
1226  // copy from st_sel_views to sel_views
1227  NON_CONST_ITERATE(set<IProjectView*>, it, st_sel_views) {
1228  views.push_back(CIRef<IProjectView>(*it));
1229  }
1230 }
1231 
1232 void CProjectTreePanel::OnCloseView(wxCommandEvent& event)
1233 {
1234  if (!m_Workbench) return;
1235 
1236  vector<CIRef<IProjectView> > views;
1237 
1238  PT::TItems sel_items;
1239  GetSelectedItems(sel_items);
1240 
1241  s_ItemsToViews(sel_items, views);
1242 
1243  CProjectService* prj_srv =
1245 
1246  for( size_t i = 0; i < views.size(); i++) {
1247  IProjectView& view = *views[i];
1248  prj_srv->RemoveProjectView(view);
1249  }
1250 }
1251 
1252 
1253 void CProjectTreePanel::OnUpdateCloseView(wxUpdateUIEvent& event)
1254 {
1255  vector<CIRef<IProjectView> > views;
1256 
1257  PT::TItems sel_items;
1258  GetSelectedItems(sel_items);
1259 
1260  s_ItemsToViews(sel_items, views);
1261  event.Enable(views.size() > 0);
1262 }
1263 
1264 
1265 void CProjectTreePanel::OnActivateClients(wxCommandEvent& event)
1266 {
1267  if (!m_Workbench) return;
1268 
1269  vector<CIRef<IProjectView> > views;
1270 
1271  PT::TItems sel_items;
1272  GetSelectedItems(sel_items);
1273 
1274  s_ItemsToViews(sel_items, views);
1275 
1276  vector<IWMClient*> clients;
1277  for( size_t i = 0; i < views.size(); i++) {
1278  IProjectView* view = views[i].GetPointer();
1279  clients.push_back(view);
1280  }
1281 
1282  IWindowManagerService* wm_srv =
1284 
1285  wm_srv->ActivateClients(clients);
1286 }
1287 
1288 
1290 {
1291  vector<CIRef<IProjectView> > views;
1292 
1293  PT::TItems sel_items;
1294  GetSelectedItems(sel_items);
1295 
1296  s_ItemsToViews(sel_items, views);
1297 
1298  event.Enable(views.size() > 0);
1299 }
1300 
1301 
1302 void CProjectTreePanel::OnProperties(wxCommandEvent& event)
1303 {
1304  PT::TItems sel_items;
1305  GetSelectedItems(sel_items);
1306 
1307  if (sel_items.size() == 1) {
1308  PT::CItem& item = *sel_items[0];
1309  if (item.DoProperties(*m_Tree)) {
1311  }
1312  } else _ASSERT(false);
1313 }
1314 
1315 
1316 void CProjectTreePanel::OnUpdateProperties(wxUpdateUIEvent& event)
1317 {
1318  PT::TItems sel_items;
1319  GetSelectedItems(sel_items);
1320 
1321  bool en = false;
1322  if(sel_items.size() == 1)
1323  en = sel_items[0]->CanDoProperties();
1324  event.Enable(en);
1325 }
1326 
1327 void CProjectTreePanel::OnUpdateUnLoadProject(wxUpdateUIEvent& event)
1328 {
1329  event.Enable(false);
1330 
1331  TProjectIdVector ids;
1332  GetSelectedProjectIds(ids);
1333 
1334  if (!m_WS) return;
1335 
1336  ITERATE(TProjectIdVector, it, ids) {
1337  CGBDocument* doc = dynamic_cast<CGBDocument*>(m_WS->GetProjectFromId(*it));
1338  if (doc && (doc->IsLoaded() || doc->IsLoading())) {
1339  event.Enable(true);
1340  return;
1341  }
1342  }
1343 }
1344 
1345 void CProjectTreePanel::OnUnLoadProject(wxCommandEvent& event)
1346 {
1347  TProjectIdVector ids, toUnload;
1348  GetSelectedProjectIds(ids);
1349 
1350  if (!m_WS) return;
1351  ITERATE(TProjectIdVector, it, ids) {
1352  CGBDocument* doc = dynamic_cast<CGBDocument*>(m_WS->GetProjectFromId(*it));
1353  if (doc && (doc->IsLoaded() || doc->IsLoading())) {
1354  toUnload.push_back(*it);
1355  }
1356  }
1357 
1358  if (toUnload.empty())
1359  return;
1360 
1362 }
1363 
1364 void CProjectTreePanel::OnLoadProject(wxCommandEvent& event)
1365 {
1366  TProjectIdVector ids, toLoad;
1367  GetSelectedProjectIds(ids);
1368 
1369  if (!m_WS) return;
1370  ITERATE(TProjectIdVector, it, ids) {
1371  CGBDocument* doc = dynamic_cast<CGBDocument*>(m_WS->GetProjectFromId(*it));
1372  if (doc && !(doc->IsLoaded() || doc->IsLoading())) {
1373  toLoad.push_back(*it);
1374  }
1375  }
1376 
1377  if (toLoad.empty())
1378  return;
1379 
1381 }
1382 
1383 void CProjectTreePanel::OnUpdateLoadProject(wxUpdateUIEvent& event)
1384 {
1385  event.Enable(false);
1386 
1387  TProjectIdVector ids;
1388  GetSelectedProjectIds(ids);
1389 
1390  if (!m_WS) return;
1391  ITERATE(TProjectIdVector, it, ids) {
1392  CGBDocument* doc = dynamic_cast<CGBDocument*>(m_WS->GetProjectFromId(*it));
1393  if (doc && !(doc->IsLoaded() || doc->IsLoading())) {
1394  event.Enable(true);
1395  return;
1396  }
1397  }
1398 }
1399 
1400 void CProjectTreePanel::OnRemoveProject(wxCommandEvent& event)
1401 {
1402  TProjectIdVector ids, toRemove;
1403  GetSelectedProjectIds(ids);
1404  if (ids.empty()) return;
1405 
1406  if (!m_WS) return;
1407  ITERATE(TProjectIdVector, it, ids) {
1408  CGBDocument* doc = dynamic_cast<CGBDocument*>(m_WS->GetProjectFromId(*it));
1409  if (doc) {
1410  toRemove.push_back(*it);
1411  }
1412  }
1413 
1414  if (toRemove.empty()) return;
1415 
1417 }
1418 
1419 void CProjectTreePanel::OnUpdateRemoveProject(wxUpdateUIEvent& event)
1420 {
1421  event.Enable(false);
1422 
1423  TProjectIdVector ids;
1424  GetSelectedProjectIds(ids);
1425 
1426  if (!m_WS) return;
1427  ITERATE(TProjectIdVector, it, ids) {
1428  CGBDocument* doc = dynamic_cast<CGBDocument*>(m_WS->GetProjectFromId(*it));
1429  if (doc) {
1430  event.Enable(true);
1431  return;
1432  }
1433  }
1434 }
1435 
1436 void CProjectTreePanel::OnProjectTableView(wxCommandEvent& event)
1437 {
1438  TProjectIdVector ids;
1439  GetSelectedProjectIds(ids);
1440 
1441  if (!m_WS) return;
1442 
1444 
1445  ITERATE(TProjectIdVector, it, ids) {
1446  CGBDocument* doc = dynamic_cast<CGBDocument*>(m_WS->GetProjectFromId(*it));
1447  if (doc && doc->IsLoaded()) {
1448  const CGBProject_ver2* gbproj = dynamic_cast<const CGBProject_ver2*>(&doc->GetProject());
1449  if (gbproj) {
1450  SConstScopedObject obj(gbproj, doc->GetScope());
1451  projectService->AddProjectView( "Project Table View", obj, 0 );
1452  }
1453  }
1454  }
1455 }
1456 
1458 {
1459  event.Enable(false);
1460 
1461  TProjectIdVector ids;
1462  GetSelectedProjectIds(ids);
1463 
1464  if (!m_WS) return;
1465  ITERATE(TProjectIdVector, it, ids) {
1466  CGBDocument* doc = dynamic_cast<CGBDocument*>(m_WS->GetProjectFromId(*it));
1467  if (doc && doc->IsLoaded()) {
1468  event.Enable(true);
1469  return;
1470  }
1471  }
1472 }
1473 
1474 static bool s_IsProjectDataFolder(wxTreeCtrl& treeCtrl, const PT::CItem& item)
1475 {
1476  if (item.GetType() != PT::eProjectFolder)
1477  return false;
1478 
1479  const PT::CItem* parent_item = item.GetParent(treeCtrl);
1480  if (parent_item != 0 && parent_item->GetType() == PT::eProject)
1481  return true;
1482 
1483  return false;
1484 }
1485 
1486 // returns true if Load / Unload command can be performed on the given set of items
1487 // all items must represent Projects and at least one must allow the operation
1488 static bool s_CanLoadUnloadProjects(CGBWorkspace* ws, PT::TItems& items, bool load)
1489 {
1490  if (!ws) return false;
1491 
1492  for (size_t i = 0; i < items.size(); ++i) {
1493  PT::CItem& item = *items[i];
1494  PT::CProject* project_item = dynamic_cast<PT::CProject*>(&item);
1495 
1496  if(project_item) {
1497  CGBDocument* doc = project_item->GetData();
1498  if (doc && !doc->IsLoading() && doc->IsLoaded() != load) {
1499  return true; // found a project on which we can perform the operation
1500  }
1501  } else {
1502  return false; // not a Project
1503  }
1504  }
1505  return false;
1506 }
1507 
1508 static const int kSaveTypesMask =
1509  PT::eWorkspace |
1510  PT::eProject;
1511 
1512 static const int kClipboardTypesMask =
1516 
1517 static const int kPropertyTypesMask =
1519  PT::eProject |
1521  PT::eDataLoader |
1523 
1526 {
1528 
1529  int types = PT::GetItemTypes(items);
1530 
1531  bool projectDataFolder = false;
1532  ITERATE(PT::TItems, it, items) {
1533  if (s_IsProjectDataFolder(*m_Tree, **it)) {
1534  projectDataFolder = true;
1535  break;
1536  }
1537  }
1538 
1539  wxMenu* menu = new wxMenu;
1540 
1541  // Save and Save As commands for Workspace and Projects
1542  if( (types & kSaveTypesMask) && (types & ~kSaveTypesMask) == 0) {
1543  bool ws = types & PT::eWorkspace;
1544  if(ws || s_CanLoadUnloadProjects(m_WS, items, false)) {
1545  menu->Append(wxID_SEPARATOR, wxT("Top Actions"));
1546  cmd_reg.AppendMenuItem(*menu, wxID_SAVE);
1547  cmd_reg.AppendMenuItem(*menu, wxID_SAVEAS);
1548  }
1549  menu->Append(wxID_SEPARATOR, wxT("Actions"));
1550  cmd_reg.AppendMenuItem(*menu, eCmdShowHideDisabledItems);
1551  }
1552 
1553  // View commands
1554  if(types == PT::eView) {
1555  menu->Append(wxID_SEPARATOR, wxT("Actions"));
1556  cmd_reg.AppendMenuItem( *menu, eCmdActivateClients );
1557  cmd_reg.AppendMenuItem( *menu, eCmdCloseProjectView );
1558  cmd_reg.AppendMenuItem( *menu, eCmdCloseAllProjectViews );
1559 
1560  } else if(items.size() == 1 &&
1561  items[0]->GetType() == PT::eFolder &&
1562  static_cast<PT::CFolder*>(items[0])->GetData() == wxT("All Views"))
1563  {
1564  menu->Append(wxID_SEPARATOR, wxT("Actions"));
1565  cmd_reg.AppendMenuItem(*menu, eCmdCloseAllProjectViews);
1566  }
1567 
1568  // Project Item commands
1569  if( types == PT::eProjectItem ){
1570 
1571  menu->Append(wxID_SEPARATOR, wxT("Top Actions"));
1572  cmd_reg.AppendMenuItem(*menu, eCmdOpenView);
1573  menu->Append(wxID_SEPARATOR, wxT("Actions"));
1574  cmd_reg.AppendMenuItem(*menu, eCmdEnableDisable);
1575  menu->Append(wxID_SEPARATOR, wxT("Actions"));
1576  cmd_reg.AppendMenuItem(*menu, eCmdShowHideDisabledItems);
1577  }
1578 
1579  // Project commands
1580  if( types == PT::eProject ){
1581  menu->Append(wxID_SEPARATOR, wxT("Actions"));
1582  cmd_reg.AppendMenuItem(*menu, eCmdLoadProject);
1583  cmd_reg.AppendMenuItem(*menu, eCmdUnLoadProject);
1584  cmd_reg.AppendMenuItem(*menu, eCmdProjectTableView);
1585  }
1586 
1587  // Edit commands
1588  TCmdID clp_cmds[4] = { wxID_CUT, wxID_COPY, wxID_PASTE, wxID_DELETE };
1589 
1590  if((types & kClipboardTypesMask) == types) {
1591  menu->Append(wxID_SEPARATOR, wxT("Edit"));
1592 
1593  if (projectDataFolder) {
1594  cmd_reg.AppendMenuItem( *menu, wxID_PASTE );
1595 
1596  } else {
1597  cmd_reg.AppendMenuItems(*menu, clp_cmds, sizeof(clp_cmds) / sizeof(TCmdID));
1598  }
1599 
1600  if (types == PT::eProjectFolder)
1601  cmd_reg.AppendMenuItem( *menu, eCmdNewFolder );
1602  }
1603 
1604  if( types == PT::eProject ){
1605  menu->Append(wxID_SEPARATOR, wxT("Edit"));
1606  cmd_reg.AppendMenuItem( *menu, eCmdRemoveProject );
1607 
1608  }
1609 
1610  // Properties
1611  if( (types & kPropertyTypesMask) == types ){
1612  menu->Append( wxID_SEPARATOR, wxT("Properties") );
1613  cmd_reg.AppendMenuItem( *menu, wxID_PROPERTIES );
1614  }
1615 
1616  return IExplorerItemCmdContributor::TContribution(menu, (wxEvtHandler*)NULL);
1617 }
1618 
1620 {
1621  PT::CWorkspace* wsItem = x_GetWorkspaceItem();
1622  if (wsItem) {
1623  wxWindowUpdateLocker locker(m_Tree);
1624  wsItem->ProjectStateChanged(*m_Tree, doc);
1625  }
1626 }
1627 
1629 {
1630  PT::CRoot* rootItem = x_GetRootItem();
1631  if (rootItem) {
1632  wxWindowUpdateLocker locker(m_Tree);
1633  PT::CWorkspace* wsItem = rootItem->GetWorkspaceItem(*m_Tree);
1634  if (wsItem) wsItem->UpdateViews(*m_Tree, &doc);
1635  rootItem->UpdateAllViews(*m_Tree, m_WS);
1636  }
1637 }
1638 
1640 {
1641  PT::CWorkspace* wsItem = x_GetWorkspaceItem();
1642  if (wsItem) {
1643  wxWindowUpdateLocker locker(m_Tree);
1644  wsItem->ProjectAdded(*m_Tree, doc);
1645  }
1646 }
1647 
1649 {
1650  wxBusyCursor wait;
1651 
1652  PT::CWorkspace* wsItem = x_GetWorkspaceItem();
1653  wxWindowUpdateLocker locker(m_Tree);
1654  if (wsItem) wsItem->UpdateDisabledItems(*m_Tree);
1655 }
1656 
1658 {
1659  PT::CWorkspace* wsItem = x_GetWorkspaceItem();
1660  wxWindowUpdateLocker locker(m_Tree);
1661  if (wsItem) wsItem->ProjectRemoved(*m_Tree, id);
1662 }
1663 
1665 {
1666  PT::CWorkspace* wsItem = x_GetWorkspaceItem();
1667  if (wsItem) wsItem->UpdateLabel(*m_Tree);
1668 }
1669 
1671 {
1672  wxBusyCursor wait;
1673 
1674  PT::CWorkspace* wsItem = x_GetWorkspaceItem();
1675  if (wsItem) {
1676  wxWindowUpdateLocker locker(m_Tree);
1677  wsItem->UpdateProjectItems(*m_Tree, doc);
1678  }
1679 }
1680 
1682 {
1683  PT::CWorkspace* wsItem = x_GetWorkspaceItem();
1684  if (wsItem) wsItem->UpdateProjectLabel(*m_Tree, doc);
1685 }
1686 
1688 {
1689  PT::CRoot* rootItem = x_GetRootItem();
1690  if (rootItem) {
1691  rootItem->UpdateViewLabel(*m_Tree, view);
1692  PT::CWorkspace* wsItem = rootItem->GetWorkspaceItem(*m_Tree);
1693  if (wsItem) wsItem->UpdateViewLabel(*m_Tree, doc, view);
1694  }
1695 }
1696 
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
std::invoke_result< _Fty, ICanceled & >::type GUI_AsyncExec(_Fty &&_Fnarg, const wxString &msg=wxT("Accessing network..."))
Definition: async_call.hpp:130
static void COpenDialog(IWorkbench *workbench, const string &loader_label=NcbiEmptyString, const vector< wxString > &filenames=vector< wxString >())
CAppExplorerDataObject - wxDataObject for use with CAppExplorerService.
static wxDataFormat m_ItemsFormat
CAppExplorerDataObject.
void GetItems(wxTreeCtrl &treeCtrl, PT::TItems &items)
CEventHandler.
CEvent - generic event implementation TODO TODO - Attachments.
Definition: event.hpp:86
CGBDocument.
Definition: document.hpp:113
bool RemoveProjectItems(const vector< objects::CProjectItem * > &items)
Definition: document.cpp:744
void AttachProjectItems(const vector< objects::CProjectItem * > &items)
Definition: document.cpp:788
virtual const TViews & GetViews(void) const
Retrieve the existing views for this class.
Definition: document.cpp:388
void DetachProjectItems(const vector< objects::CProjectItem * > &items)
Definition: document.cpp:811
bool IsLoading() const
Definition: document.cpp:264
CGBWorkspace.
Definition: GBWorkspace.hpp:63
bool IsEnabled(void) const
enabled flag
CProjectService - a service providing API for operations with Workspaces and Projects.
CIRef< IProjectView > AddProjectView(const string &view_name, SConstScopedObject &object, const objects::CUser_object *params, bool bFloat=false)
void RemoveProjectView(IProjectView &view)
removes the view from View manager Service and disconnects it from the project
CRef< objects::CGBWorkspace > GetGBWorkspace()
static void LoadProjects(IServiceLocator *serviceLocator, const TProjectIdVector &project_ids)
static bool RemoveProjects(IServiceLocator *serviceLocator, const TProjectIdVector &project_ids, bool confirm=true)
static void UnLoadProjects(IServiceLocator *serviceLocator, const TProjectIdVector &project_ids)
CProjectTreeCtrl - subclass of wxTreeCtrl to allow functions to be overridden for application-specifi...
void OnMove(wxMouseEvent &event)
void OnLeftDown(wxMouseEvent &event)
void OnKeyUp(wxKeyEvent &event)
CProjectTreeCtrl()
CProjectTreeCtrl.
virtual wxTextCtrl * EditLabel(const wxTreeItemId &item, wxClassInfo *textCtrlClass=CLASSINFO(wxTextCtrl))
CProjectTreePanel - a window that represents Project View.
void OnActivateClients(wxCommandEvent &event)
void ProjectUpdateLabel(CGBDocument &doc)
CAppExplorerDataObject * x_CreateDataObject(bool cut)
void OnUpdateShowHideDisabledItems(wxUpdateUIEvent &event)
void Create(wxWindow *parent, wxWindowID id=wxID_ANY, const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxDefaultSize)
void OnUpdateCut(wxUpdateUIEvent &event)
void OnEnableDisable(wxCommandEvent &event)
void OnEndDrag(wxTreeEvent &event)
void OnBeginDrag(wxTreeEvent &event)
void OnProjectTableView(wxCommandEvent &event)
void OnRemove(wxCommandEvent &event)
void OnPaste(wxCommandEvent &event)
void ProjectRemoved(size_t id)
void OnUpdateLoadProject(wxUpdateUIEvent &event)
wxDragResult OnDrop(wxCoord x, wxCoord y, wxDragResult def, CAppExplorerDataObject &data)
void OnItemExpandedCollapsed(wxTreeEvent &event)
wxDragResult OnDragOver(wxCoord x, wxCoord y, wxDragResult def)
void OnLeftDown(wxMouseEvent &event)
void OnUpdateUnLoadProject(wxUpdateUIEvent &event)
void OnUpdateProperties(wxUpdateUIEvent &event)
CRef< objects::CGBWorkspace > m_WS
void OnTreeKeyDown(wxTreeEvent &event)
void ProjectViewsChanged(CGBDocument &doc)
void OnShowHideDisabledItems(wxCommandEvent &event)
objects::CGBProjectHandle::TId TProjectId
PT::CRoot * x_GetRootItem()
void OnUnLoadProject(wxCommandEvent &event)
PT::CItem * x_GetSingleSelectedItem()
void OnCloseView(wxCommandEvent &event)
void ProjectUpdateItems(CGBDocument &doc)
void OnCut(wxCommandEvent &event)
void GetAllItems(PT::TItems &items)
void GetSelectedProjectIds(TProjectIdVector &ids)
void Init()
Initializes member variables.
CAppExplorerDataObject * m_DataObject
Data object used for drag and drop (this is the data being dragged)
void OnCopy(wxCommandEvent &event)
void OnRemoveProject(wxCommandEvent &event)
void OnUpdateRemove(wxUpdateUIEvent &event)
PT::CWorkspace * x_GetWorkspaceItem()
void OnBeginLabelEdit(wxTreeEvent &event)
IExplorerItemCmdContributor::TContribution x_GetContextMenu(PT::TItems &items)
void OnProperties(wxCommandEvent &event)
wxTreeItemId m_DropItemId
D&D state.
void x_SetSelections(wxArrayTreeItemIds &ids)
void SetCopyMode(bool b)
Drag and drop support for OSX Cocoa (generic dnd path not working in OSX cocoa 2.9....
void ProjectStateChanged(CGBDocument &doc)
vector< TProjectId > TProjectIdVector
void OnContextMenu(wxContextMenuEvent &event)
void OnUpdateNewFolder(wxUpdateUIEvent &event)
void OnEndLabelEdit(wxTreeEvent &event)
void CreateControls()
Creates the controls and sizers.
friend class CProjectTreeViewDropTarget
void GetSelectedItems(PT::TItems &items)
void x_CollectItemIds(wxTreeItemId root, wxArrayTreeItemIds &ids)
void OnItemActivated(wxTreeEvent &event)
void OnUpdateEnableDisable(wxUpdateUIEvent &event)
void x_CutOrCopyToClipboard(bool cut)
CProjectTreeCtrl * m_Tree
void OnUpdateCopy(wxUpdateUIEvent &event)
void OnLoadProject(wxCommandEvent &event)
void OnUpdateActivateClients(wxUpdateUIEvent &event)
void x_GetItemsFromIds(const wxArrayTreeItemIds &ids, PT::TItems &items)
void OnUpdateRemoveProject(wxUpdateUIEvent &event)
void UpdateViewLabel(CGBDocument &doc, IProjectView &view)
void OnUpdateProjectTableView(wxUpdateUIEvent &event)
void SetWorkbench(IWorkbench *workbench)
PT::CItem * x_GetExplorerItem(const wxTreeItemId &id)
void x_RefreshProjectTables(TProjectId projectId)
void OnUpdatePaste(wxUpdateUIEvent &event)
void OnNewFolder(wxCommandEvent &event)
void ProjectAdded(CGBDocument &doc)
void OnSelectionChanged(wxTreeEvent &event)
void OnUpdateCloseView(wxUpdateUIEvent &event)
virtual wxDragResult OnEnter(wxCoord x, wxCoord y, wxDragResult def)
CProjectTreeViewDropTarget(CProjectTreePanel *panel)
CProjectTreeViewDropTarget.
virtual wxDragResult OnDragOver(wxCoord x, wxCoord y, wxDragResult def)
virtual wxDragResult OnData(wxCoord x, wxCoord y, wxDragResult def)
CProjectViewEvent.
Definition: document.hpp:62
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
void AppendMenuItems(wxMenu &menu, const TCmdID *cmd_ids, int count) const
Definition: ui_command.cpp:330
wxMenuItem * AppendMenuItem(wxMenu &menu, TCmdID cmd_id) const
Definition: ui_command.cpp:300
@ eWidgetSelectionChanged
a view has been destroyed
Definition: view_event.hpp:55
Interface for testing cancellation request in a long lasting operation.
Definition: icanceled.hpp:51
IExplorerItemCmdContributor - interface representing a component that contributes commands applicable...
Definition: pt_item.hpp:149
virtual TContribution GetMenu(wxTreeCtrl &treeCtrl, PT::TItems &items)=0
for the given set of items returns a contribution
pair< wxMenu *, wxEvtHandler * > TContribution
Contribution consists of a Menu object and event handler.
Definition: pt_item.hpp:152
IMenuService - Menu Service.
class IProjectView defines the abstract interface for views observing projects.
virtual void GetMainObject(TConstScopedObjects &objects) const =0
Adds the main data objects represented by the client to "objects".
IWindowManagerService Window Manager Service provides access to Window Manager functionality.
IWorkbench is the central interface in the application framework.
Definition: workbench.hpp:113
virtual int GetType() const =0
virtual bool Paste(wxTreeCtrl &, vector< CItem * > &, bool)
Definition: pt_item.hpp:87
virtual bool DoProperties(wxTreeCtrl &)
Definition: pt_item.hpp:76
virtual bool CanPaste(wxTreeCtrl &) const
Definition: pt_item.hpp:86
virtual void DoNewFolder(wxTreeCtrl &)
Definition: pt_item.hpp:73
virtual bool CanCopyToClipboard(wxTreeCtrl &) const
Definition: pt_item.hpp:84
virtual void OnItemExpandedCollapsed(wxTreeCtrl &)
Definition: pt_item.hpp:70
virtual void BeginLabelEdit(wxTreeCtrl &, wxTreeEvent &event)
Definition: pt_item.hpp:78
void SetTreeItemId(wxTreeItemId treeItemId)
Definition: pt_item.hpp:63
virtual bool EndLabelEdit(wxTreeCtrl &, wxTreeEvent &event)
Definition: pt_item.hpp:79
static void LogInstanceCount()
Definition: pt_item.cpp:46
CItem * GetParent(wxTreeCtrl &treeCtrl) const
Definition: pt_item.cpp:74
static CPTIcons & GetInstance()
void ExpandCompacted(wxTreeCtrl &treeCtrl, wxTreeItemId &compacted_node, CGBDocument &doc, IStatusBarService *sb_srv, ICanceled *cancel)
void UpdateDataSources(wxTreeCtrl &treeCtrl, IServiceLocator &serviceLocator)
Definition: pt_root.cpp:83
void Initialize(wxTreeCtrl &treeCtrl, objects::CGBWorkspace *ws)
Definition: pt_root.cpp:60
void UpdateAllViews(wxTreeCtrl &treeCtrl, objects::CGBWorkspace *ws)
Definition: pt_root.cpp:127
CWorkspace * GetWorkspaceItem(wxTreeCtrl &treeCtrl)
Definition: pt_root.cpp:163
void UpdateViewLabel(wxTreeCtrl &treeCtrl, IProjectView &view)
Definition: pt_root.cpp:173
void ProjectRemoved(wxTreeCtrl &treeCtrl, size_t id)
void ProjectStateChanged(wxTreeCtrl &treeCtrl, CGBDocument &doc)
void UpdateViews(wxTreeCtrl &treeCtrl, CGBDocument *doc=0)
void UpdateProjectItems(wxTreeCtrl &treeCtrl, CGBDocument &doc)
void UpdateViewLabel(wxTreeCtrl &treeCtrl, CGBDocument &doc, IProjectView &view)
void UpdateLabel(wxTreeCtrl &treeCtrl)
void UpdateProjectLabel(wxTreeCtrl &treeCtrl, CGBDocument &doc)
void ProjectAdded(wxTreeCtrl &treeCtrl, CGBDocument &doc)
void UpdateDisabledItems(wxTreeCtrl &treeCtrl)
void UpdateHiddenItems(wxTreeCtrl &treeCtrl)
const TData & GetData() const
Definition: pt_item.hpp:135
Definition: map.hpp:338
Definition: set.hpp:45
iterator_bool insert(const value_type &val)
Definition: set.hpp:149
const_iterator find(const key_type &key) const
Definition: set.hpp:137
const_iterator end() const
Definition: set.hpp:136
void(*)(CSeq_entry_Handle seh, IWorkbench *wb, const CSerialObject &obj) handler
@ eCmdUnLoadProject
Definition: commands.hpp:77
@ eCmdOpenViewDefault
Definition: commands.hpp:106
@ eCmdShowHideDisabledItems
Definition: commands.hpp:72
@ eCmdEnableDisable
Definition: commands.hpp:96
@ eCmdRemoveProject
Definition: commands.hpp:78
@ eCmdCloseAllProjectViews
Definition: commands.hpp:86
@ eCmdCloseProjectView
Definition: commands.hpp:85
@ eCmdProjectTableView
Definition: commands.hpp:81
@ eCmdLoadProject
Definition: commands.hpp:76
@ eCmdNewFolder
Definition: commands.hpp:95
@ eCmdActivateClients
Definition: commands.hpp:87
@ eCmdOpenView
Definition: commands.hpp:67
static uch flags
static const struct name_t names[]
#define false
Definition: bool.h:36
static void Init(void)
Definition: cursor6.c:76
static const struct type types[]
Definition: type.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
#define NON_CONST_ITERATE(Type, Var, Cont)
Non constant version of ITERATE macro.
Definition: ncbimisc.hpp:822
#define NULL
Definition: ncbistd.hpp:225
#define ERR_POST(message)
Error posting with file, line number information but without error codes.
Definition: ncbidiag.hpp:186
#define NCBI_CATCH(message)
Catch CExceptions as well This macro is deprecated - use *_X or *_XX variant instead of it.
Definition: ncbiexpt.hpp:580
CIRef< T > GetServiceByType()
retrieves a typed reference to a service, the name of C++ type is used as the name of the service.
Definition: service.hpp:91
virtual IStatusBarService * GetStatusBarService()=0
virtual void ActivateClients(TClients &clients)=0
makes clients visible, make the first client in the given container focused
void GetExtensionAsInterface(const string &ext_point_id, vector< CIRef< I > > &interfaces)
GetExtensionAsInterface() is a helper function that extracts all extensions implementing the specifie...
void NcbiErrorBox(const string &message, const string &title="Error")
specialized Message Box function for reporting critical errors
vector< SConstScopedObject > TConstScopedObjects
Definition: objects.hpp:65
virtual bool Send(CEvent *evt, EDispatch disp_how=eDispatch_Default, int pool_name=ePool_Default)
Sends an event synchronously.
int TCmdID
@ eEvent_Message
message from one class to another
Definition: event.hpp:99
#define END_NCBI_SCOPE
End previously defined NCBI scope.
Definition: ncbistl.hpp:103
#define BEGIN_NCBI_SCOPE
Define ncbi namespace.
Definition: ncbistl.hpp:100
#define NcbiEmptyString
Definition: ncbistr.hpp:122
double Restart(void)
Return time elapsed since first Start() or last Restart() call (in seconds).
Definition: ncbitime.hpp:2816
double Elapsed(void) const
Return time elapsed since first Start() or last Restart() call (in seconds).
Definition: ncbitime.hpp:2775
void Stop(void)
Suspend the timer.
Definition: ncbitime.hpp:2792
END_EVENT_TABLE()
int i
yy_size_t n
static void text(MDB_val *v)
Definition: mdb_dump.c:62
#define wxT(x)
Definition: muParser.cpp:41
objects::CGBProjectHandle::TId GetProjectId(wxTreeCtrl &treeCtrl, const CItem &item)
Definition: pt_utils.cpp:67
int GetItemTypes(const TItems &items)
Definition: pt_utils.cpp:59
CProject * GetProject(wxTreeCtrl &treeCtrl, const CItem &item)
Definition: pt_utils.cpp:77
bool sm_HideDisabledItems
Definition: pt_utils.cpp:57
@ eProject
Definition: pt_item.hpp:118
@ eWorkspace
Definition: pt_item.hpp:117
@ eView
Definition: pt_item.hpp:122
@ eProjectItem
Definition: pt_item.hpp:120
@ eFolder
Definition: pt_item.hpp:123
@ eDataSource
Definition: pt_item.hpp:121
@ eHiddenItems
Definition: pt_item.hpp:125
@ eDataLoader
Definition: pt_item.hpp:124
@ eProjectFolder
Definition: pt_item.hpp:119
vector< CItem * > TItems
Definition: pt_item.hpp:113
const struct ncbi::grid::netcache::search::fields::SIZE size
const CharType(& source)[N]
Definition: pointer.h:1149
EIPRangeType t
Definition: ncbi_localip.c:101
static Format format
Definition: njn_ioutil.cpp:53
static int filenames
Definition: pcregrep.c:172
static void s_RemoveDependentItems(wxTreeCtrl &treeCtrl, wxArrayTreeItemIds &items)
USING_SCOPE(objects)
static void s_ItemsToViews(PT::TItems &items, vector< CIRef< IProjectView > > &views)
static bool s_CanLoadUnloadProjects(CGBWorkspace *ws, PT::TItems &items, bool load)
static const int kClipboardTypesMask
static const int kSaveTypesMask
static bool s_IsProjectDataFolder(wxTreeCtrl &treeCtrl, const PT::CItem &item)
static const int kPropertyTypesMask
wxEVT_COMMAND_MENU_SELECTED
static static static wxID_ANY
ViewerWindowBase::OnEditMenu ViewerWindowBase::OnJustification EVT_MENU(MID_SHOW_GEOM_VLTNS, ViewerWindowBase::OnShowGeomVltns) EVT_MENU(MID_FIND_PATTERN
Definition: type.c:6
#define _ASSERT
#define WX_DEFINE_MENU(name)
New macros for defining menus for use with CUICommandRegistry.
Definition: ui_command.hpp:266
#define WX_END_MENU()
Definition: ui_command.hpp:294
#define WX_MENU_SEPARATOR_L(label)
Definition: ui_command.hpp:285
void SetFocus(CRef< objects::CSeq_entry > entry)
void Merge(wxMenu &menu_1, const wxMenu &menu_2)
merges all items form menu_2 into menu_1, preserving the structure if possible
Definition: wx_utils.cpp:579
#define wxTR_GBENCH_LINES
Definition: wx_utils.hpp:69
void CleanupSeparators(wxMenu &menu)
Removes extra separators (in the begining or at the end of the menu, ot those that precede other sepa...
Definition: wx_utils.cpp:668
Modified on Sat May 25 14:16:17 2024 by modify_doxy.py rev. 669887