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

Go to the SVN repository for this file.

1 /* $Id: macro_constraint_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: Igor Filippov
27  *
28  * File Description:
29  *
30  */
31 #include <ncbi_pch.hpp>
38 
39 #include <wx/checklst.h>
40 #include <wx/button.h>
41 #include <wx/sizer.h>
42 
44 
45 IMPLEMENT_DYNAMIC_CLASS( CMacroCompoundConstraintPanel, wxPanel )
46 
47 
48 /*!
49  * CMacroCompoundConstraintPanel event table definition
50  */
51 
52 BEGIN_EVENT_TABLE( CMacroCompoundConstraintPanel, wxPanel )
58 
59 
60 /*!
61  * CMacroCompoundConstraintPanel constructors
62  */
63 
65 {
66  Init();
67 }
68 
69 CMacroCompoundConstraintPanel::CMacroCompoundConstraintPanel( wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style )
70  : m_Num(0)
71 {
72  Init();
73  Create(parent, id, pos, size, style);
74 }
75 
76 
77 /*!
78  * CMacroCompoundConstraintPanel creator
79  */
80 
81 bool CMacroCompoundConstraintPanel::Create( wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style )
82 {
83 ////@begin CMacroCompoundConstraintPanel creation
84  wxPanel::Create( parent, id, pos, size, style );
85 
87  if (GetSizer())
88  {
89  GetSizer()->SetSizeHints(this);
90  }
91  Centre();
92 ////@end CMacroCompoundConstraintPanel creation
93  return true;
94 }
95 
96 
97 /*!
98  * CMacroCompoundConstraintPanel destructor
99  */
100 
102 {
103 ////@begin CMacroCompoundConstraintPanel destruction
104 ////@end CMacroCompoundConstraintPanel destruction
105 }
106 
107 
108 /*!
109  * Member initialisation
110  */
111 
113 {
115  m_Add = NULL;
116  m_Clear = NULL;
117 }
118 
119 
120 /*!
121  * Control creation for CMacroCompoundConstraintPanel
122  */
123 
125 {
126  CMacroCompoundConstraintPanel* itemPanel1 = this;
127 
128  wxBoxSizer* itemBoxSizer2 = new wxBoxSizer(wxVERTICAL);
129  itemPanel1->SetSizer(itemBoxSizer2);
130 
131  m_CheckListBox = new wxCheckListBox(itemPanel1, ID_CONSTRAINT_LIST, wxDefaultPosition, wxDefaultSize, 0, nullptr, wxLB_HSCROLL);
132  itemBoxSizer2->Add(m_CheckListBox, 1, wxGROW|wxALL, 5);
133 
134  wxBoxSizer* itemBoxSizer12 = new wxBoxSizer(wxHORIZONTAL);
135  itemBoxSizer2->Add(itemBoxSizer12, 0, wxALIGN_CENTER_HORIZONTAL|wxALL, 0);
136 
137  m_Add = new wxButton( itemPanel1, ID_CONSTRAINT_ADD, _("Add Constraint"), wxDefaultPosition, wxDefaultSize, 0 );
138  itemBoxSizer12->Add(m_Add, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
139  m_Add->Disable();
140 
141  m_Clear = new wxButton( itemPanel1, ID_CONSTRAINT_REMOVE, _("Clear Constraints"), wxDefaultPosition, wxDefaultSize, 0 );
142  itemBoxSizer12->Add(m_Clear, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
143  m_Clear->Disable();
144 }
145 
146 
148 {
149  m_CheckListBox->Clear();
150  m_Constraints.clear();
151  m_Num = 0;
152  m_Clear->Disable();
153  m_Add->Enable(enable_add);
154 }
155 
156 /*!
157  * Should we show tooltips?
158  */
159 
161 {
162  return true;
163 }
164 
165 /*!
166  * Get bitmap resources
167  */
168 
169 wxBitmap CMacroCompoundConstraintPanel::GetBitmapResource( const wxString& name )
170 {
171  // Bitmap retrieval
172 ////@begin CMacroCompoundConstraintPanel bitmap retrieval
173  wxUnusedVar(name);
174  return wxNullBitmap;
175 ////@end CMacroCompoundConstraintPanel bitmap retrieval
176 }
177 
178 /*!
179  * Get icon resources
180  */
181 
183 {
184  // Icon retrieval
185 ////@begin CMacroCompoundConstraintPanel icon retrieval
186  wxUnusedVar(name);
187  return wxNullIcon;
188 ////@end CMacroCompoundConstraintPanel icon retrieval
189 }
190 
192 {
193  CMacroEditingActionPanel *parent = dynamic_cast<CMacroEditingActionPanel*>(GetParent());
194  if (!parent)
195  return;
196  pair<string, string> target = parent->GetForTarget();
197  if (target.first.empty())
198  return;
199  CMacroAddConstraint * dlg = new CMacroAddConstraint(this, target);
200  dlg->SetNumConstraints(m_Num++);
201  dlg->Show(true);
202 }
203 
205 {
206  Freeze();
207  wxArrayInt checked_items;
208  m_CheckListBox->GetCheckedItems(checked_items);
209  if (checked_items.IsEmpty()) {
210  auto answer = NcbiMessageBox("No items checked, remove all?", eDialog_YesNo, eIcon_Question, "Warning");
211  if (answer == eYes) {
212  ClearValues(true);
213  }
214  }
215  else {
216  set<int> to_delete;
217  for (size_t i = 0; i < checked_items.GetCount(); i++) {
218  int j = checked_items.Item(i);
219  to_delete.insert(j);
220  string label = m_CheckListBox->GetString(j).ToStdString();
221  auto constr_it = find_if(m_Constraints.begin(), m_Constraints.end(),
222  [&label](const auto& elem) { return (elem.m_Label == label); });
223  _ASSERT(constr_it != m_Constraints.end());
224  if (constr_it != m_Constraints.end()) {
225  m_Constraints.erase(constr_it);
226  }
227  }
228 
230  for (size_t index = 0; index < m_Constraints.size(); ++index) {
231  m_ConstraintMap.emplace(m_Constraints[index].m_Label, index);
232  }
233 
234  for (auto rit = to_delete.rbegin(); rit != to_delete.rend(); ++rit) {
235  m_CheckListBox->Delete(*rit);
236  }
237  }
238  Thaw();
239  Refresh();
240 
241  _ASSERT(m_Constraints.size() == m_CheckListBox->GetCount());
242 
243  CMacroEditingActionPanel *parent = dynamic_cast<CMacroEditingActionPanel*>(GetParent());
244  if (parent)
245  parent->UpdateParentFrame();
246 }
247 
248 void CMacroCompoundConstraintPanel::AddConstraint(pair<string, string> item,
249  int id, const vector<string> &vars, const string &qual_name, EMMatcherPanelType panel_type,
250  const vector<CFuncWithArgs>& func_info)
251 {
252  SMacroConstraint constr(panel_type);
253  constr.m_Label = item.first;
254  constr.m_Constraint = item.second;
255  constr.m_Variables = vars;
256  constr.m_Fieldname = qual_name;
257  constr.m_FuncInfo = func_info;
258 
259  if (id < 0) {
260  // append when it's a new item
261  m_CheckListBox->Append(wxString(item.first));
262  m_Constraints.push_back(constr);
263  }
264  else {
265  string label = m_CheckListBox->GetString(id).ToStdString();
266  auto constr_it = find_if(m_Constraints.begin(), m_Constraints.end(),
267  [&label](const auto& elem) { return (elem.m_Label == label); });
268  _ASSERT(constr_it != m_Constraints.end());
269  if (constr_it != m_Constraints.end()) {
270  //m_Constraints.erase(constr_it);
271  *constr_it = constr;
272  }
273  m_CheckListBox->SetString(id, wxString(item.first));
274  }
275 
277  for (auto index = 0; index < m_CheckListBox->GetCount(); ++index) {
278  m_ConstraintMap.emplace(m_CheckListBox->GetString(index).ToStdString(), index);
279  }
280 
281  _ASSERT(m_Constraints.size() == m_CheckListBox->GetCount());
282 
283 
284  Refresh();
285 
286  CMacroEditingActionPanel *parent = dynamic_cast<CMacroEditingActionPanel*>(GetParent());
287  if (parent)
288  parent->UpdateParentFrame();
289 }
290 
291 /// Called when a constraint is edited
292 /// It should work both when a macro is created and when a macro is edited
294 {
295  CMacroEditingActionPanel *parent = dynamic_cast<CMacroEditingActionPanel*>(GetParent());
296  if (!parent)
297  return;
298 
299  pair<string, string> target = parent->GetForTarget();
300  if (target.first.empty())
301  return;
302 
303  const string& label = event.GetString().ToStdString();
304  //int id = event.GetInt();
305 
306  unsigned id = m_ConstraintMap.at(label);
307  try {
308  CMacroAddConstraint* dlg = new CMacroAddConstraint(this, target);
309  dlg->SetConstraint(m_Constraints[id]);
310  dlg->SetEditId(id);
311  dlg->SetNumConstraints(id);
312  dlg->Show(true);
313  }
314  catch (const CException& e) {
315  LOG_POST(Error << "Constraint: " + label + "could not be edited: " + e.GetMsg());
316  NcbiErrorBox("Constraint '" + label + "' could not be edited");
317  }
318 }
319 
321 {
322  event.Enable(m_CheckListBox->GetCount() > 0);
323 }
324 
325 /// When setting constraints from a macro that's edited
326 /// 1. Select the panel type where the macro function 'belongs' to, but this page should not be
327 /// visible to the user.
328 /// 2. Generate the description and the function for the constraint
330 {
331  ClearValues(true);
332 
334  // gather the indices of functions that cannot be viewed in the constraint panel
335  vector<size_t> not_viewed;
336 
337  for (size_t index = 0; index < func_info.size(); ++index) {
339  if (match_type == EMMatcherPanelType::eMMatcher_NotSet) {
340  auto field_it = func_info[index].m_FArgs.find(NMacroArgs::kField);
341 
342  switch (func_info[index].m_FieldTypeFrom) {
348  break;
351  break;
354  break;
357  break;
360  break;
364  break;
367  break;
370  break;
373  break;
378  if (find_if(qualifier_list.begin(), qualifier_list.end(),
379  [&field_it](const string& elem) { return NStr::EqualNocase(elem, field_it->second); }) != qualifier_list.end()) {
381  }
382  else {
384  }
385  break;
386  }
387 
388  default:
389  break;
390  }
391  }
392 
393  if (match_type == EMMatcherPanelType::eMMatcher_NotSet) {
394  not_viewed.push_back(index);
395  LOG_POST(Error << "CONSTRAINT could not be viewed:\n" << func_info[index].m_FName);
396  }
397  else {
398  panel_to_constraints[match_type].push_back(func_info[index]);
399  }
400  }
401 
402  {
403  auto count = not_viewed.size();
404  if (count == 1) {
405  NcbiWarningBox("There is one constraint that cannot be viewed in the editor");
406  }
407  else if (count > 1) {
408  NcbiWarningBox("There are " + NStr::SizetToString(count) + " constraints that cannot be viewed in the editor");
409  }
410  }
411 
412  CMacroEditingActionPanel *parent = dynamic_cast<CMacroEditingActionPanel*>(GetParent());
413  if (!parent)
414  return;
415 
416  pair<string, string> target = parent->GetForTarget();
417 
418  m_Num = 0;
419  for (const auto& it : panel_to_constraints) {
420  if (it.first == EMMatcherPanelType::eMMatcher_Location ||
422  SMacroConstraint constr(it.first);
423  constr.m_FuncInfo = it.second;
424 
425  CMacroAddConstraint dlg(this, target);
426  dlg.SetNumConstraints(m_Num++);
427  dlg.SetAndUpdateConstraint(constr);
428  m_Constraints.push_back(constr);
429  m_CheckListBox->Append(wxString(constr.m_Label));
430  m_ConstraintMap.emplace(constr.m_Label, m_Constraints.size() - 1);
431  }
432  else {
433  for (const auto& constr_it : it.second) {
434  SMacroConstraint constr(it.first);
435  constr.m_FuncInfo = { constr_it };
436  // adjust for specific GUI control names
437  {
438  auto& fn = constr.m_FuncInfo.front();
439  if (fn.m_FieldTypeFrom == EMacroFieldType::eBiosourceLocation) {
440  auto field_it = fn.m_FArgs.find(NMacroArgs::kField);
441  if (field_it != fn.m_FArgs.end()) {
442  field_it->second = "genome";
443  }
444  }
445  else if (fn.m_FieldTypeFrom == EMacroFieldType::eBiosourceText) {
446  auto field_it = fn.m_FArgs.find(NMacroArgs::kField);
447  if (field_it != fn.m_FArgs.end() && field_it->second == "org.db") {
448  field_it->second = kDbXref;
449  }
450  }
451  }
452 
453  CMacroAddConstraint dlg(this, target);
454  dlg.SetNumConstraints(m_Num++);
455  dlg.SetAndUpdateConstraint(constr);
456  m_Constraints.push_back(constr);
457  m_CheckListBox->Append(wxString(constr.m_Label));
458  m_ConstraintMap.emplace(constr.m_Label, m_Constraints.size() - 1);
459  }
460  }
461  }
462  _ASSERT(m_Num == m_Constraints.size());
463  _ASSERT(m_Constraints.size() == m_CheckListBox->GetCount());
465 }
466 
468 {
469  return ! m_CheckListBox->IsEmpty();
470 }
471 
473 {
474  TStringPairsVector constraints;
475  constraints.reserve(m_CheckListBox->GetCount());
476 
477  for (auto i = 0; i < m_CheckListBox->GetCount(); i++) {
478  string label = m_CheckListBox->GetString(i).ToStdString();
479  string constraint = m_Constraints[i].m_Constraint;
480  string qual_name = m_Constraints[i].m_Fieldname;
481  if (!constraint.empty())
482  constraints.emplace_back(qual_name, constraint);
483  }
484  return constraints;
485 }
486 
488 {
489  vector<string> constraints;
490  constraints.reserve(m_CheckListBox->GetCount());
491 
492  for (auto i = 0; i < m_CheckListBox->GetCount(); i++) {
493  string label = m_CheckListBox->GetString(i).ToStdString();
494  if (!label.empty())
495  constraints.push_back(label);
496  }
497  return constraints;
498 }
499 
501  {
502  for (auto i = 0; i < m_CheckListBox->GetCount(); i++) {
503  string label = m_CheckListBox->GetString(i).ToStdString();
504  if (!m_Constraints[i].m_Variables.empty())
505  return true;
506  }
507  return false;
508  }
509 
511 {
512  string vars;
513  for (auto i = 0; i < m_CheckListBox->GetCount(); i++) {
514  string label = m_CheckListBox->GetString(i).ToStdString();
515  if (!m_Constraints[i].m_Variables.empty()) {
516  vars += NStr::Join(m_Constraints[i].m_Variables, "\n") + "\n";
517  }
518  }
519  return vars;
520 }
521 
523 {
524  LOG_POST(Info << "There are " << m_Num << " constraints");
525  LOG_POST(Info << "m_Constraints: " << m_Constraints.size());
526 }
527 
EVT_UPDATE_UI(eCmdAlnShowMethodsDlg, CAlnMultiWidget::OnUpdateShowMethodDlg) EVT_UPDATE_UI(eCmdMethodProperties
void SetAndUpdateConstraint(SMacroConstraint &constr)
void SetConstraint(const SMacroConstraint &constr)
wxIcon GetIconResource(const wxString &name)
vector< SMacroConstraint > m_Constraints
void AddConstraint(pair< string, string > item, int id, const vector< string > &vars=vector< string >(), const string &qual_name=kEmptyStr, EMMatcherPanelType panel_type=EMMatcherPanelType::eMMatcher_NotSet, const vector< CFuncWithArgs > &func_info=vector< CFuncWithArgs >())
map< string, unsigned > m_ConstraintMap
void OnAddConstraint(wxCommandEvent &event)
void OnRemoveConstraint(wxCommandEvent &event)
void OnUpdateClearButton(wxUpdateUIEvent &event)
bool Create(wxWindow *parent, wxWindowID id=wxID_ANY, const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxDefaultSize, long style=wxTAB_TRAVERSAL)
void SetConstraints(const vector< CFuncWithArgs > &)
When setting constraints from a macro that's edited 1.
wxBitmap GetBitmapResource(const wxString &name)
void OnEditConstraint(wxCommandEvent &event)
Called when a constraint is edited It should work both when a macro is created and when a macro is ed...
pair< string, string > GetForTarget()
const vector< string > & GetKeywords(EMacroFieldType type) const
static CMacroEditorContext & GetInstance()
static const EMMatcherPanelType s_GetMatcherPanels(const CFuncWithArgs &func_info)
size_type size() const
Definition: map.hpp:148
void clear()
Definition: map.hpp:169
Definition: map.hpp:338
iterator_bool insert(const value_type &val)
Definition: set.hpp:149
#define ID_CONSTRAINT_LIST
#define ID_CONSTRAINT_ADD
#define ID_CONSTRAINT_REMOVE
#define _(proto)
Definition: ct_nlmzip_i.h:78
const char * kDbXref
static void Init(void)
Definition: cursor6.c:76
#define NULL
Definition: ncbistd.hpp:225
#define LOG_POST(message)
This macro is deprecated and it's strongly recomended to move in all projects (except tests) to macro...
Definition: ncbidiag.hpp:226
void Error(CExceptionArgs_Base &args)
Definition: ncbiexpt.hpp:1197
const string & GetMsg(void) const
Get message string.
Definition: ncbiexpt.cpp:461
void Info(CExceptionArgs_Base &args)
Definition: ncbiexpt.hpp:1185
void NcbiWarningBox(const string &message, const string &title="Warning")
specialized Message Box function for reporting non-critical errors
void NcbiErrorBox(const string &message, const string &title="Error")
specialized Message Box function for reporting critical errors
EDialogReturnValue NcbiMessageBox(const string &message, TDialogType type=eDialog_Ok, EDialogIcon icon=eIcon_Exclamation, const string &title="Error", EDialogTextMode text_mode=eRaw)
Definition: message_box.cpp:48
#define END_NCBI_SCOPE
End previously defined NCBI scope.
Definition: ncbistl.hpp:103
#define BEGIN_NCBI_SCOPE
Define ncbi namespace.
Definition: ncbistl.hpp:100
static string SizetToString(size_t value, TNumToStringFlags flags=0, int base=10)
Convert size_t to string.
Definition: ncbistr.cpp:2751
vector< pair< string, string > > TStringPairsVector
Definition: ncbistr.hpp:4810
static string Join(const TContainer &arr, const CTempString &delim)
Join strings using the specified delimiter.
Definition: ncbistr.hpp:2697
static const char label[]
@ eIcon_Question
Definition: types.hpp:64
@ eDialog_YesNo
Definition: types.hpp:49
END_EVENT_TABLE()
int i
EMMatcherPanelType
Denotes the type of panel that is used to create macro constraint.
const string kField
const struct ncbi::grid::netcache::search::fields::SIZE size
vector< CFuncWithArgs > m_FuncInfo
interpreted functions with their arguments
string m_Fieldname
fieldname referred in the constraint
vector< string > m_Variables
variables used in the constraint
string m_Constraint
constraint expression, e.g., Strand() = "plus"
string m_Label
description of the constraint as it is listed in the macro editor
#define _ASSERT
Modified on Fri May 24 14:51:43 2024 by modify_doxy.py rev. 669887