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

Go to the SVN repository for this file.

1 /* $Id: blast_db_dialog.cpp 36594 2016-10-12 20:17:36Z 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: Andrey Yazhuk
27  *
28  * File Description:
29  * A dialog for browsing BLAST Databases.
30  */
31 
32 
33 #include <ncbi_pch.hpp>
34 
35 
38 
39 #include <wx/sizer.h>
40 #include <wx/bitmap.h>
41 #include <wx/icon.h>
42 #include <wx/button.h>
43 #include <wx/textctrl.h>
44 #include <wx/stattext.h>
45 #include <wx/treectrl.h>
46 #include <wx/wupdlock.h>
47 
48 
49 ////@begin XPM images
50 ////@end XPM images
51 
52 
54 
55 class CBLASTDlgItemData : public wxTreeItemData
56 {
57 public:
59 
61 };
62 
63 ///////////////////////////////////////////////////////////////////////////////
64 ///
66 : m_LabelPos(string::npos),
67  m_LabelLength(0),
68  m_Visible(true),
69  m_Expanded(false),
70  m_Parent(NULL),
71  m_ChildItems(NULL)
72 {
73 }
74 
75 CBLAST_Dlg_Item::CBLAST_Dlg_Item(const string& label, const string& path, bool is_database)
76 : //m_Label(label),
77  m_Path(path),
78  m_IsDatabase(is_database),
79  m_Visible(true),
80  m_Expanded(false),
81  m_Parent(NULL),
82  m_ChildItems(NULL)
83 {
84  m_LabelPos = path.find(label);
85  _ASSERT(m_LabelPos != string::npos);
86  m_LabelLength = label.size();
87 
88 }
89 
90 wxString CBLAST_Dlg_Item::GetLabel() const {
91  if (m_LabelLength == 0)
92  return wxT("");
93  return wxString(&m_Path[m_LabelPos], m_LabelLength);
94 }
95 
96 
98 {
99  m_Parent = NULL;
100  delete m_ChildItems;
101 }
102 
104 {
105  if(m_ChildItems) {
106  string l = label;
108  if(it != m_ChildItems->end()) {
109  return it->second;
110  }
111  }
112  return NULL;
113 }
114 
115 
117 {
118  _ASSERT(item.m_Parent == NULL);
119 // _ASSERT(m_ChildItems == NULL || m_ChildItems->find(item.m_Label) == m_ChildItems->end());
121 
122  if(m_ChildItems == NULL) {
124  }
126 // m_ChildItems->insert(TNameToItemMap::value_type(item.m_Label, CRef<CBLAST_Dlg_Item>(&item)));
127  item.m_Parent = this;
128 }
129 
130 
131 ///////////////////////////////////////////////////////////////////////////////
132 ///
133 IMPLEMENT_DYNAMIC_CLASS( CBLAST_DB_Dialog, CDialog )
134 
135 BEGIN_EVENT_TABLE( CBLAST_DB_Dialog, CDialog )
136 ////@begin CBLAST_DB_Dialog event table entries
137  EVT_INIT_DIALOG( CBLAST_DB_Dialog::OnInitDialog )
138 
139  EVT_TEXT( ID_SEARCH, CBLAST_DB_Dialog::OnSearchTextUpdated )
140 
141  EVT_BUTTON( ID_RESET_BTN, CBLAST_DB_Dialog::OnResetBtnClick )
142 
143  EVT_TREE_SEL_CHANGED( ID_TREECTRL, CBLAST_DB_Dialog::OnTreectrlSelChanged )
144  EVT_TREE_ITEM_ACTIVATED( ID_TREECTRL, CBLAST_DB_Dialog::OnTreectrlItemActivated )
145  EVT_TREE_ITEM_COLLAPSED( ID_TREECTRL, CBLAST_DB_Dialog::OnTreectrlItemCollapsed )
146  EVT_TREE_ITEM_EXPANDED( ID_TREECTRL, CBLAST_DB_Dialog::OnTreectrlItemExpanded )
147 
148  EVT_BUTTON( wxID_OK, CBLAST_DB_Dialog::OnOkClick )
149 
150 ////@end CBLAST_DB_Dialog event table entries
152 
153 
154 CBLAST_DB_Dialog::CBLAST_DB_Dialog()
155 {
156  Init();
157 }
158 
159 
160 CBLAST_DB_Dialog::CBLAST_DB_Dialog( wxWindow* parent, wxWindowID id, const wxString& caption, const wxPoint& pos, const wxSize& size, long style )
161 {
162  Init();
163  Create(parent, id, caption, pos, size, style);
164 }
165 
166 
167 bool CBLAST_DB_Dialog::Create( wxWindow* parent, wxWindowID id, const wxString& caption, const wxPoint& pos, const wxSize& size, long style )
168 {
169 ////@begin CBLAST_DB_Dialog creation
170  SetExtraStyle(wxWS_EX_BLOCK_EVENTS);
171  CDialog::Create( parent, id, caption, pos, size, style );
172 
173  CreateControls();
174  if (GetSizer())
175  {
176  GetSizer()->SetSizeHints(this);
177  }
178  Centre();
179 ////@end CBLAST_DB_Dialog creation
180  return true;
181 }
182 
183 
185 {
186 ////@begin CBLAST_DB_Dialog destruction
187 ////@end CBLAST_DB_Dialog destruction
188 }
189 
190 
192 {
193 ////@begin CBLAST_DB_Dialog member initialisation
194  m_SearchCtrl = NULL;
195  m_StatusText = NULL;
196  m_TreeCtrl = NULL;
197  m_OKBtn = NULL;
198 ////@end CBLAST_DB_Dialog member initialisation
199  m_DbMap = NULL;
200 }
201 
202 
204 {
205 ////@begin CBLAST_DB_Dialog content construction
206  CBLAST_DB_Dialog* itemCDialog1 = this;
207 
208  wxBoxSizer* itemBoxSizer2 = new wxBoxSizer(wxVERTICAL);
209  itemCDialog1->SetSizer(itemBoxSizer2);
210 
211  wxFlexGridSizer* itemFlexGridSizer3 = new wxFlexGridSizer(2, 2, 0, 0);
212  itemFlexGridSizer3->AddGrowableCol(1);
213  itemBoxSizer2->Add(itemFlexGridSizer3, 0, wxGROW|wxLEFT|wxRIGHT|wxTOP, 5);
214 
215  wxStaticText* itemStaticText4 = new wxStaticText( itemCDialog1, wxID_STATIC, _("Filter:"), wxDefaultPosition, wxDefaultSize, 0 );
216  itemFlexGridSizer3->Add(itemStaticText4, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 5);
217 
218  wxBoxSizer* itemBoxSizer5 = new wxBoxSizer(wxHORIZONTAL);
219  itemFlexGridSizer3->Add(itemBoxSizer5, 0, wxGROW|wxALIGN_CENTER_VERTICAL, 5);
220 
221  m_SearchCtrl = new wxTextCtrl( itemCDialog1, ID_SEARCH, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
222  itemBoxSizer5->Add(m_SearchCtrl, 1, wxGROW|wxALL, 5);
223 
224  wxButton* itemButton7 = new wxButton( itemCDialog1, ID_RESET_BTN, _("Clear"), wxDefaultPosition, wxDefaultSize, 0 );
225  itemBoxSizer5->Add(itemButton7, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
226 
227  itemFlexGridSizer3->Add(7, 8, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 5);
228 
229  m_StatusText = new wxStaticText( itemCDialog1, wxID_STATUS, _("Filter:"), wxDefaultPosition, wxDefaultSize, 0 );
230  itemFlexGridSizer3->Add(m_StatusText, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5);
231 
232  m_TreeCtrl = new wxTreeCtrl( itemCDialog1, ID_TREECTRL, wxDefaultPosition, itemCDialog1->ConvertDialogToPixels(wxSize(240, 160)), wxTR_HAS_BUTTONS |wxTR_FULL_ROW_HIGHLIGHT|wxTR_LINES_AT_ROOT|wxTR_HIDE_ROOT|wxTR_SINGLE );
233  itemBoxSizer2->Add(m_TreeCtrl, 1, wxGROW|wxALL, 5);
234 
235  wxStdDialogButtonSizer* itemStdDialogButtonSizer11 = new wxStdDialogButtonSizer;
236 
237  itemBoxSizer2->Add(itemStdDialogButtonSizer11, 0, wxALIGN_RIGHT|wxALL, 5);
238  m_OKBtn = new wxButton( itemCDialog1, wxID_OK, _("&OK"), wxDefaultPosition, wxDefaultSize, 0 );
239  itemStdDialogButtonSizer11->AddButton(m_OKBtn);
240 
241  wxButton* itemButton13 = new wxButton( itemCDialog1, wxID_CANCEL, _("&Cancel"), wxDefaultPosition, wxDefaultSize, 0 );
242  itemStdDialogButtonSizer11->AddButton(itemButton13);
243 
244  itemStdDialogButtonSizer11->Realize();
245 
246 ////@end CBLAST_DB_Dialog content construction
247 }
248 
249 
251 {
252  return true;
253 }
254 
255 
256 wxBitmap CBLAST_DB_Dialog::GetBitmapResource( const wxString& name )
257 {
258  // Bitmap retrieval
259 ////@begin CBLAST_DB_Dialog bitmap retrieval
260  wxUnusedVar(name);
261  return wxNullBitmap;
262 ////@end CBLAST_DB_Dialog bitmap retrieval
263 }
264 
265 
266 wxIcon CBLAST_DB_Dialog::GetIconResource( const wxString& name )
267 {
268  // Icon retrieval
269 ////@begin CBLAST_DB_Dialog icon retrieval
270  wxUnusedVar(name);
271  return wxNullIcon;
272 ////@end CBLAST_DB_Dialog icon retrieval
273 }
274 
275 
276 void CBLAST_DB_Dialog::SetToolName(const string& tool)
277 {
278  string s = tool + " - Select BLAST Databases";
279  SetTitle(ToWxString(s));
280 }
281 
282 
284 {
285  m_DbMap = &map;
286 }
287 
288 
289 void CBLAST_DB_Dialog::SelectDatabases(vector<string>& databases)
290 {
291  if( ! databases.empty()) {
292  m_SelDatabase = databases[0];
293  }
294 }
295 
296 
297 void CBLAST_DB_Dialog::GetSelectedDatabases(vector<string>& databases)
298 {
299  databases.push_back(m_SelDatabase);
300 }
301 
302 
303 void CBLAST_DB_Dialog::OnSearchTextUpdated( wxCommandEvent& event )
304 {
305  wxString s_val = m_SearchCtrl->GetValue();
306 
307  string query = ToStdString(s_val);
308  x_FilterItems(query);
309 }
310 
311 
312 void CBLAST_DB_Dialog::OnResetBtnClick( wxCommandEvent& event )
313 {
314  m_SearchCtrl->SetValue(wxT(""));
316 }
317 
318 
319 void CBLAST_DB_Dialog::OnInitDialog( wxInitDialogEvent& event )
320 {
321  CDialog::OnInitDialog(event);
322 
323  x_CreateItems();
324 
326 
327  // select databases
329  CBLAST_Dlg_Item& ch_item = **it;
330  if(ch_item.GetPath() == m_SelDatabase) {
331  m_TreeCtrl->SelectItem(ch_item.GetId());
332  }
333  }
334 }
335 
336 
338 {
339  if(m_DP.m_DbMap) {
340  vector<string> tokens;
341 
342  // build the new item hierarchy
343  ITERATE(TDbMap, it, *(m_DP.m_DbMap)) {
344  const string& path = it->first;
345  tokens.clear();
346  NStr::Split(path, "/", tokens);
348  CBLAST_Dlg_Item* new_item = NULL;
349  size_t n = tokens.size();
350  for ( size_t i = 0; i < n; ++i) {
351  const string& label = tokens[i];
352  if(i < n - 1) {
353  // try to find the item for category
354  new_item = item->GetChildByLabel(label);
355  if(new_item == NULL) {
356  // create a category item
357  new_item = new CBLAST_Dlg_Item(label, path);
358  item->AddChild(*new_item);
359  m_DP.m_CatItems.push_back(new_item);
360  }
361  } else {
362  // last item - create a DB item
363  new_item = new CBLAST_Dlg_Item(label, path, true);
364  item->AddChild(*new_item);
365  m_DP.m_DbItems.push_back(new_item);
366  }
367  item = new_item;
368  }
369  }
370  }
371 }
372 
373 
375 {
376  // clean old data, this should delete all previously created items
378  m_CatItems.clear();
379  m_DbItems.clear();
380 
381  CExecuteAsync_CreateItems exec(*this);
382  CAsyncCall::Execute(exec);
383 
384 }
385 
386 
388 {
389  if(item.IsVisible()) {
390  const CBLAST_Dlg_Item* parent = item.GetParent();
391 // const string& label = item.GetLabel();
392  wxString label = item.GetLabel();
393 
394  // create wxTreeItem for this item
395  wxTreeItemId id;
396  CBLASTDlgItemData* data = new CBLASTDlgItemData(&item);
397  if(parent) {
398  id = m_TreeCtrl->AppendItem(parent->GetId(), label,
399  -1, -1, data);
400  item.SetId(id);
401  } else {
402  id = m_TreeCtrl->AddRoot(label, -1, -1, data);
403  item.SetId(id);
404  }
405 
406  // process child items recursively
408  if(items) {
410  CBLAST_Dlg_Item& ch_item = *it->second;
411  if(ch_item.IsVisible()) {
412  x_BuildTreeItems(ch_item);
413  }
414  }
415  if(parent) {
416  if(item.IsExpanded()) {
417  m_TreeCtrl->Expand(id);
418  } else {
419  m_TreeCtrl->Collapse(id);
420  }
421  }
422  }
423  }
424 }
425 
426 
427 // completely rebuilds all wxTreeItems in the Tree Control
429 {
430  wxWindowUpdateLocker locker(m_TreeCtrl);
431 
432  if(m_Root) {
433  m_TreeCtrl->UnselectAll();
434  m_TreeCtrl->DeleteAllItems();
435 
437  }
438 }
439 
440 
442 {
443  if(m_Root) {
444  wxBusyCursor wait;
445  wxWindowUpdateLocker locker(m_TreeCtrl);
446  bool reset = query.empty();
447  int n_vis = 0;
448 
449  // make all categories invisible by default
451  CBLAST_Dlg_Item& ch_item = **it;
452  ch_item.SetVisible(false);
453  }
454 
455  // iterate on all DB items and set Visible flag
457  CBLAST_Dlg_Item& ch_item = **it;
458  bool vis = true;
459  if( ! reset) {
460  // const string& label = ch_item.GetLabel();
461  string label = ToStdString(ch_item.GetLabel());
462 
463  vis = (NStr::FindNoCase(label, query) != string::npos);
464  }
465  ch_item.SetVisible(vis);
466 
467  if(vis) {
468  n_vis++;
469 
470  // mark parent category items as visible
471  CBLAST_Dlg_Item* parent = ch_item.GetParent();
472  while(parent && ! parent->IsVisible()) {
473  parent->SetVisible(true);
474  parent = parent->GetParent();
475  }
476  }
477  }
478 
480 
481  x_UpdateFilterStatusText(reset, n_vis);
482  }
483 }
484 
485 
487 {
488  string status = reset ? "All " : "Filtered - ";
489  if( ! reset && n == 0) {
490  status += "no matches";
491  } else {
492  status += NStr::IntToString(n);
493  status += " Database";
494  status += (n != 1 ? "s are shown" : " is shown");
495  }
496 
497  m_StatusText->SetLabel(ToWxString(status));
498 }
499 
500 
502 {
503  x_UpdateCollapsedState(event.GetItem());
504 }
505 
506 
508 {
509  x_UpdateCollapsedState(event.GetItem());
510 }
511 
512 
513 void CBLAST_DB_Dialog::OnTreectrlSelChanged( wxTreeEvent& event )
514 {
515  bool db_item = false;
516 
517  wxTreeItemId id = m_TreeCtrl->GetSelection();
518  if(id.IsOk()) {
519  wxTreeItemData* data = m_TreeCtrl->GetItemData(id);
520  CBLASTDlgItemData* ex_data = dynamic_cast<CBLASTDlgItemData*>(data);
521  db_item = ex_data->m_Item->IsDatabase();
522  }
523 
524  m_OKBtn->Enable(db_item);
525 }
526 
527 
529 {
531 }
532 
533 
534 void CBLAST_DB_Dialog::OnOkClick( wxCommandEvent& event )
535 {
537 }
538 
539 
541 {
543  if(item) {
544  m_SelDatabase = item->GetPath();
545  EndModal(wxID_OK);
546  }
547 }
548 
549 
551 {
552  wxTreeItemId id = m_TreeCtrl->GetSelection();
553 
554  if(id.IsOk()) {
555  wxTreeItemData* data = m_TreeCtrl->GetItemData(id);
556  CBLASTDlgItemData* ex_data = dynamic_cast<CBLASTDlgItemData*>(data);
557  CBLAST_Dlg_Item* item = ex_data->m_Item.GetPointer();
558  if (item->IsDatabase())
559  return item;
560  }
561  return NULL;
562 }
563 
564 
566 {
567  bool open = m_TreeCtrl->IsExpanded(id);
568 
569  wxTreeItemData* data = m_TreeCtrl->GetItemData(id);
570  CBLASTDlgItemData* ex_data = dynamic_cast<CBLASTDlgItemData*>(data);
571  ex_data->m_Item->Expand(open);
572 }
573 
574 
const string & GetPath() const
iterator_bool insert(const value_type &val)
Definition: map.hpp:165
#define NON_CONST_ITERATE(Type, Var, Cont)
Non constant version of ITERATE macro.
Definition: ncbimisc.hpp:802
void SetToolName(const string &tool)
bool IsExpanded() const
TNameToItemMap * m_ChildItems
bool IsVisible() const
bool IsDatabase() const
TObjectType * GetPointer(void) THROWS_NONE
Get pointer,.
Definition: ncbiobj.hpp:989
CBLAST_Dlg_Item * x_GetSelectedDBItem()
container_type::iterator iterator
Definition: map.hpp:54
END_EVENT_TABLE()
void Expand(bool expand)
wxString ToWxString(const char *s)
Definition: wx_utils.hpp:159
CBLAST_Dlg_Item * m_Parent
const TDbMap * m_DbMap
wxTextCtrl * m_SearchCtrl
string
Definition: cgiapp.hpp:514
static SIZE_TYPE FindNoCase(const CTempString str, const CTempString pattern, SIZE_TYPE start, SIZE_TYPE end, EOccurrence which=eFirst)
Find the pattern in the specified range of a string using a case insensitive search.
Definition: ncbistr.cpp:2888
wxString GetLabel() const
#define NULL
Definition: ncbistd.hpp:225
#define kEmptyStr
Definition: ncbistr.hpp:121
#define ID_TREECTRL
#define ITERATE(Type, Var, Cont)
ITERATE macro to sequence through container elements.
Definition: ncbimisc.hpp:795
wxTreeCtrl * m_TreeCtrl
int i
void Execute()
Definition: async_call.cpp:197
void OnInitDialog(wxInitDialogEvent &event)
static string IntToString(int value, TNumToStringFlags flags=0, int base=10)
Convert int to string.
Definition: ncbistr.hpp:4808
#define END_NCBI_SCOPE
End previously defined NCBI scope.
Definition: ncbistl.hpp:101
const wxTreeItemId & GetId() const
const_iterator end() const
Definition: map.hpp:152
map< wxString, CRef< CBLAST_Dlg_Item > > TNameToItemMap
void AddChild(CBLAST_Dlg_Item &item)
void x_UpdateFilterStatusText(bool reset, int n)
void OnSearchTextUpdated(wxCommandEvent &event)
const_iterator find(const key_type &key) const
Definition: map.hpp:153
deque< CBLAST_Dlg_Item * > TItemDeque
void x_FilterItems(const string &query)
static string query
static bool ShowToolTips()
void SelectDatabases(vector< string > &databases)
wxStaticText * m_StatusText
CBLASTDatabases::TDbMap TDbMap
wxIcon GetIconResource(const wxString &name)
CBLAST_Dlg_Item * GetParent()
CDialog.
Definition: dialog.hpp:46
static void Init(void)
Definition: cursor6.c:76
void x_BuildTreeItems(CBLAST_Dlg_Item &item)
static const char label[]
int size
Definition: map.hpp:337
void OnTreectrlSelChanged(wxTreeEvent &event)
TNameToItemMap * GetChildItems()
Private async class to off-load GUI.
void x_UpdateCollapsedState(wxTreeItemId id)
void OnResetBtnClick(wxCommandEvent &event)
EVT_BUTTON(ID_CREATE_BIOSAMPLE, CCompareWithBiosample::CreateBiosampleUpdate) CCompareWithBiosample
virtual void EndModal(int retCode)
Definition: dialog.cpp:103
wxBitmap GetBitmapResource(const wxString &name)
CBLAST_DB_Dialog.
CRef< CBLAST_Dlg_Item > m_Item
CBLAST_Dlg_Item * GetChildByLabel(const string &label)
void SetDBMap(const TDbMap &map)
CRef< CBLAST_Dlg_Item > m_Root
void SetId(const wxTreeItemId &id)
#define _(proto)
Definition: ct_nlmzip_i.h:78
static void SetTitle(CRef< CSeq_entry > entry, string title)
container_type::value_type value_type
Definition: map.hpp:52
#define wxT(x)
Definition: muParser.cpp:41
yy_size_t n
#define _ASSERT
void SetVisible(bool visible)
void OnOkClick(wxCommandEvent &event)
static list< string > & Split(const CTempString str, const CTempString delim, list< string > &arr, TSplitFlags flags=0, vector< SIZE_TYPE > *token_pos=NULL)
Split a string using specified delimiters.
Definition: ncbistr.cpp:3362
void GetSelectedDatabases(vector< string > &databases)
void OnTreectrlItemCollapsed(wxTreeEvent &event)
Definition: dbpivot.c:60
void OnTreectrlItemActivated(wxTreeEvent &event)
bool Create(wxWindow *parent, wxWindowID id=ID_CBLAST_DB_DIALOG, const wxString &caption=wxEmptyString, const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxSize(400, 300), long style=wxCAPTION|wxRESIZE_BORDER|wxSYSTEM_MENU|wxCLOSE_BOX|wxTAB_TRAVERSAL)
Definition: dbpivot.c:60
CBLASTDlgItemData(CBLAST_Dlg_Item *item)
string ToStdString(const wxString &s)
Definition: wx_utils.hpp:147
#define BEGIN_NCBI_SCOPE
Define ncbi namespace.
Definition: ncbistl.hpp:98
void Reset(void)
Reset reference object.
Definition: ncbiobj.hpp:768
void OnTreectrlItemExpanded(wxTreeEvent &event)
Modified on Fri Apr 20 12:40:47 2018 by modify_doxy.py rev. 546573