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

Go to the SVN repository for this file.

1 /* $Id: compare_with_biosample.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 #include <ncbi_pch.hpp>
29 #include <corelib/ncbi_system.hpp>
30 
33 
37 #include <objmgr/seqdesc_ci.hpp>
38 #include <objmgr/util/sequence.hpp>
40 
42 
47 
48 
51 
56 
57 #include <wx/msgdlg.h>
58 #include <wx/filedlg.h>
59 #include <wx/filename.h>
60 #include <wx/dir.h>
61 #include <sstream>
62 
65 
66 IMPLEMENT_DYNAMIC_CLASS( CCompareWithBiosample, wxFrame )
67 
68 BEGIN_EVENT_TABLE( CCompareWithBiosample, wxFrame )
70  EVT_BUTTON( wxID_CANCEL, CCompareWithBiosample::OnClickCancel )
81 
83 {
84  Init();
85 }
86 
87 // https://svn.ncbi.nlm.nih.gov/viewvc/toolkit/trunk/c%2B%2B/src/app/biosample_chk/
89  CSeq_entry_Handle seh, ICommandProccessor* cmdProcessor, bool all_records,
90  wxWindowID id, const wxString& caption, const wxPoint& pos, const wxSize& size, long style )
91  : m_TopSeqEntry(seh), m_CmdProcessor(cmdProcessor), m_all_records(all_records)
92 {
93  x_LoadData();
94 
95  Init();
96  Create(parent, id, caption, pos, size, style);
98  LoadSettings();
99 }
100 
102 {
103  m_DiffVec.clear();
104  m_Cache.clear();
105  m_ids.clear();
106 
107  size_t num_processed;
108  vector<string> unprocessed_ids;
109  //bool use_dev_server(true); // DEBUG
110  bool use_dev_server(false);
111  bool compare_structured_comments(false);
112 
114  for (CBioseq_CI b_iter(m_TopSeqEntry, CSeq_inst::eMol_na); b_iter; ++b_iter)
115  {
116  biosample_util::TBiosampleFieldDiffList diff_vec = biosample_util::GetBioseqDiffs(*b_iter, kEmptyStr, num_processed, unprocessed_ids, use_dev_server, compare_structured_comments, kEmptyStr, &cache);
117  for (auto diff : diff_vec)
118  {
119  string seq_id = diff->GetSequenceId();
120  string field = diff->GetFieldName();
121  string source = diff->GetSrcVal();
122  string sample = diff->GetPureSampleVal();
123  string sample_id = diff->GetBioSample();
124 
125  set<string> set_source, set_sample;
126  tie(set_source, set_sample) = m_DiffVec[{sample_id, field}][seq_id];
127  if (!source.empty())
128  set_source.insert(source);
129  if (!sample.empty())
130  set_sample.insert(sample);
131  m_DiffVec[{sample_id, field}][seq_id] = make_pair(set_source, set_sample);
132  }
133 
134  string label;
136  vector<CRef <CSeq_id> > id_list;
137  ITERATE(CBioseq_Handle::TId, it, b_iter->GetId())
138  {
139  CConstRef<CSeq_id> ir = (*it).GetSeqId();
140  if (ir->IsGenbank())
141  {
142  id = ir;
143  }
144  CRef<CSeq_id> ic(const_cast<CSeq_id *>(ir.GetPointer()));
145  id_list.push_back(ic);
146  }
147  if (!id)
148  {
149  id = FindBestChoice(id_list, CSeq_id::BestRank);
150  }
151  if (id)
152  {
153  id->GetLabel(&label);
154  m_ids[label] = id;
155  }
156 
157  if (!m_all_records)
158  break;
159  }
160 }
161 
162 bool CCompareWithBiosample::Create( wxWindow* parent, wxWindowID id, const wxString& caption, const wxPoint& pos, const wxSize& size, long style )
163 {
164  SetExtraStyle(wxWS_EX_BLOCK_EVENTS);
165  wxFrame::Create( parent, id, caption, pos, size, style );
166  wxVisualAttributes attr = wxPanel::GetClassDefaultAttributes();
167  if (attr.colBg != wxNullColour) {
168  SetOwnBackgroundColour(attr.colBg);
169  }
170  CreateControls();
171  if (GetSizer())
172  {
173  GetSizer()->SetSizeHints(this);
174  }
175  Centre();
176  return true;
177 }
178 
179 
181 {
182  SaveSettings();
183 }
184 
185 
186 /*!
187  * Member initialisation
188  */
189 
191 {
193  m_Grid=NULL;
194  m_GridPanel = NULL;
195  m_source_col = 0;
196  m_sample_col = 0;
197  m_field_col = 0;
198  m_sample_id_col = 0;
199  m_modified_sample = false;
200  m_modified_source = false;
202 }
203 
204 
206 {
207  CCompareWithBiosample* itemDialog1 = this;
208 
209  wxBoxSizer* itemBoxSizer2 = new wxBoxSizer(wxVERTICAL);
210  itemDialog1->SetSizer(itemBoxSizer2);
211 
212  m_GridPanelSizer = new wxBoxSizer(wxHORIZONTAL);
213  itemBoxSizer2->Add(m_GridPanelSizer, 0, wxALIGN_CENTER_HORIZONTAL|wxALL, 5);
214 
215  if (m_DiffVec.empty())
216  {
217  wxMessageBox(wxT("No differences found for resolved Biosample IDs"), wxT("Info"), wxOK);
218  NCBI_THROW( CException, eUnknown, "No differences found for compare with Biosample" );
219  }
220 
222  if (values_table->GetNum_rows() < 1)
223  {
224  wxMessageBox(wxT("No differences found for resolved Biosample IDs"), wxT("Info"), wxOK);
225  NCBI_THROW( CException, eUnknown, "No differences found for compare with Biosample" );
226  }
227 
228  x_AddTablePanel(values_table);
229  wxArrayString itemChoiceStrings, itemChoiceStringsWritable;
230  int pos = 0;
231  ITERATE (CSeq_table::TColumns, it, values_table->GetColumns())
232  {
233  if (pos > 0)
234  {
235  if ((*it)->IsSetHeader() && (*it)->GetHeader().IsSetTitle() )
236  {
237  string title = (*it)->GetHeader().GetTitle();
238  if (!title.empty())
239  {
240  itemChoiceStrings.Add(wxString(title));
241  if (!IsReadOnlyColumn(title))
242  itemChoiceStringsWritable.Add(wxString(title));
243  }
244  }
245  }
246  pos++;
247  }
248 
249  wxBoxSizer* itemBoxSizer16 = new wxBoxSizer(wxHORIZONTAL);
250  itemBoxSizer2->Add(itemBoxSizer16, 0, wxALIGN_CENTER_HORIZONTAL|wxALL, 5);
251 
252  wxButton* itemButton24 = new wxButton( itemDialog1, ID_ADD_TO_SOURCE, _("+<<"), wxDefaultPosition, wxDefaultSize, 0 );
253  itemBoxSizer16->Add(itemButton24, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
254  if (ShowToolTips())
255  itemButton24->SetToolTip(_("Append to BioSource values"));
256 
257  wxButton* itemButton17 = new wxButton( itemDialog1, ID_COPY_TO_SOURCE, _("<<"), wxDefaultPosition, wxDefaultSize, 0 );
258  itemBoxSizer16->Add(itemButton17, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
259  if (ShowToolTips())
260  itemButton17->SetToolTip(_("Overwrite BioSource values"));
261 
262  wxButton* itemButton18 = new wxButton( itemDialog1, ID_SYNC, _("sync"), wxDefaultPosition, wxDefaultSize, 0 );
263  itemBoxSizer16->Add(itemButton18, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
264  if (ShowToolTips())
265  itemButton18->SetToolTip(_("Fill the blanks in either BioSample or BioSource values"));
266 
267  wxButton* itemButton19 = new wxButton( itemDialog1, ID_COPY_TO_SAMPLE, _(">>"), wxDefaultPosition, wxDefaultSize, 0 );
268  itemBoxSizer16->Add(itemButton19, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
269  if (ShowToolTips())
270  itemButton19->SetToolTip(_("Overwrite BioSample values"));
271 
272  wxButton* itemButton25 = new wxButton( itemDialog1, ID_ADD_TO_SAMPLE, _(">>+"), wxDefaultPosition, wxDefaultSize, 0 );
273  itemBoxSizer16->Add(itemButton25, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
274  if (ShowToolTips())
275  itemButton25->SetToolTip(_("Append to BioSample values"));
276 
277  wxBoxSizer* itemBoxSizer4 = new wxBoxSizer(wxHORIZONTAL);
278  itemBoxSizer2->Add(itemBoxSizer4, 0, wxALIGN_CENTER_HORIZONTAL|wxALL, 5);
279 
280  m_StringConstraintPanel = new CStringConstraintSelect( itemDialog1, m_GridPanel, itemChoiceStrings, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 );
281  itemBoxSizer4->Add(m_StringConstraintPanel, 0, wxALIGN_TOP|wxALL|wxFIXED_MINSIZE, 0);
282 
283  wxBoxSizer* itemBoxSizer5 = new wxBoxSizer(wxHORIZONTAL);
284  itemBoxSizer2->Add(itemBoxSizer5, 0, wxALIGN_CENTER_HORIZONTAL|wxALL, 5);
285 
286  m_AecrPanel = new CApplyEditconvertPanel( itemDialog1, m_GridPanel, itemChoiceStringsWritable, 0, true, wxID_ANY, wxDefaultPosition, wxSize(1128, 219));
287  itemBoxSizer5->Add(m_AecrPanel, 0, wxALIGN_TOP|wxALL|wxFIXED_MINSIZE, 1);
288 
289  wxBoxSizer* itemBoxSizer13 = new wxBoxSizer(wxHORIZONTAL);
290  itemBoxSizer2->Add(itemBoxSizer13, 0, wxALIGN_CENTER_HORIZONTAL|wxALL, 5);
291 
292  wxButton* itemButton14 = new wxButton( itemDialog1, ID_UPDATE_BIOSOURCE, _("Update BioSource"), wxDefaultPosition, wxDefaultSize, 0 );
293  itemBoxSizer13->Add(itemButton14, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
294 
295  wxButton* itemButton20 = new wxButton( itemDialog1, ID_CREATE_BIOSAMPLE, _("Create Biosample Update"), wxDefaultPosition, wxDefaultSize, 0 );
296  itemBoxSizer13->Add(itemButton20, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
297 
298  wxButton* itemButton21 = new wxButton( itemDialog1, ID_MAKE_REPORT, _("Make Report"), wxDefaultPosition, wxDefaultSize, 0 );
299  itemBoxSizer13->Add(itemButton21, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
300 
301  m_RefreshButton = new wxButton(itemDialog1, ID_REFRESH_BIOSAMPLE, _("Refresh"), wxDefaultPosition, wxDefaultSize, 0);
302  itemBoxSizer13->Add(m_RefreshButton, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
304 
305  wxButton* itemButton23 = new wxButton(itemDialog1, ID_APIKEY_BIOSAMPLE, _("Get BioSample API Key"), wxDefaultPosition, wxDefaultSize, 0);
306  itemBoxSizer13->Add(itemButton23, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
307 
308  wxButton* itemButton15 = new wxButton( itemDialog1, wxID_CANCEL, _("Close"), wxDefaultPosition, wxDefaultSize, 0 );
309  itemBoxSizer13->Add(itemButton15, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
310 }
311 
313 {
314  m_GridPanelSizer->Clear(true);
315 
316  CRef<CSeq_table> choices = GetChoices(values_table);
317  int glyph_col = GetCollapsible();
318  m_GridPanel = new CSeqTableGridPanel(this, values_table, choices, glyph_col);
319  m_GridPanelSizer->Add(m_GridPanel, 0, wxALIGN_TOP|wxALL, 5);
321  CSeqTableGrid *gridAdapter = new CSeqTableGrid(values_table);
322  m_Grid->SetTable(gridAdapter, true);
323  m_Grid->AutoSizeColumns();
324  int l_height = m_Grid->GetColLabelSize();
325  m_Grid->SetColLabelSize( 2 * l_height );
326 
327  int pos = 0;
328  ITERATE (CSeq_table::TColumns, it, values_table->GetColumns())
329  {
330  if (pos > 0)
331  {
332  if ((*it)->IsSetHeader() && (*it)->GetHeader().IsSetTitle() )
333  {
334  string title = (*it)->GetHeader().GetTitle();
335  if (IsReadOnlyColumn(title))
336  m_GridPanel->MakeColumnReadOnly(pos - 1, true);
337  }
338  }
339  pos++;
340  }
341 
342  if (glyph_col >= 0 && glyph_col+1 < m_Grid->GetNumberCols())
343  {
344  m_GridPanel->InitColumnCollapse(glyph_col+1);
345  }
346  Layout();
347  Fit();
348 }
349 
351 {
353  m_id_col->SetHeader().SetField_id(CSeqTable_column_info::eField_id_location_id);
354  m_id_col->SetHeader().SetTitle(kSequenceIdColLabel);
355 
356  CRef<CSeqTable_column> expand_col(new CSeqTable_column());
357  expand_col->SetHeader().SetTitle("");
358  expand_col->SetHeader().SetField_name("expand");
359  expand_col->SetData().SetString();
360 
362  name_col->SetHeader().SetTitle("Field");
363  name_col->SetHeader().SetField_name("field");
364  name_col->SetData().SetString();
365 
366  CRef<CSeqTable_column> source_col(new CSeqTable_column());
367  source_col->SetHeader().SetTitle("Source");
368  source_col->SetHeader().SetField_name("source");
369  source_col->SetData().SetString();
370 
371  CRef<CSeqTable_column> sample_col(new CSeqTable_column());
372  sample_col->SetHeader().SetTitle("Sample");
373  sample_col->SetHeader().SetField_name("Sample");
374  sample_col->SetData().SetString();
375 
376  CRef<CSeqTable_column> sample_id_col(new CSeqTable_column());
377  sample_id_col->SetHeader().SetTitle("Biosample Id");
378  sample_id_col->SetHeader().SetField_name("biosample_id");
379  sample_id_col->SetData().SetString();
380 
382  table->SetColumns().push_back(m_id_col);
383  table->SetColumns().push_back(expand_col);
384  table->SetColumns().push_back(name_col);
385  table->SetColumns().push_back(source_col);
386  table->SetColumns().push_back(sample_col);
387  table->SetColumns().push_back(sample_id_col);
388 
389  m_field_col = 1;
390  m_source_col = 2;
391  m_sample_col = 3;
392  m_sample_id_col = 4;
393  size_t num_rows = 0;
394  for (const auto &diff : m_DiffVec)
395  {
396  string field, sample_id;
397  tie(sample_id, field) = diff.first;
398  for (const auto &row : diff.second)
399  {
400  string seq_id = row.first;
401  set<string> set_source, set_sample;
402  tie(set_source, set_sample) = row.second;
403 
404  string source = NStr::Join(set_source, "|");
405  string sample = NStr::Join(set_sample, "|");
406 
407  CRef<CSeq_id> id;
408  if (m_ids.find(seq_id) != m_ids.end())
409  {
410  id.Reset(new CSeq_id);
411  id->Assign(*m_ids[seq_id]);
412  }
413  else
414  {
415  id.Reset(new CSeq_id(seq_id, CSeq_id::fParse_Default));
416  }
417 
418  m_id_col->SetData().SetId().push_back(id);
419  expand_col->SetData().SetString().push_back("");
420  name_col->SetData().SetString().push_back(field);
421  source_col->SetData().SetString().push_back(source);
422  sample_col->SetData().SetString().push_back(sample);
423  sample_id_col->SetData().SetString().push_back(sample_id);
424  ++num_rows;
425  }
426  }
427 
428  table->SetNum_rows(static_cast<CSeq_table::TNum_rows>(num_rows));
429 
430  return table;
431 }
432 
433 void CCompareWithBiosample::OnClickOk( wxCommandEvent& event )
434 {
435  if (!m_TopSeqEntry)
436  return;
437  CScope &scope = m_TopSeqEntry.GetScope();
439  Freeze();
440  int collapsed_col = m_GridPanel->GetCollapseColAndExpand();
441  auto num_rows = m_Grid->GetNumberRows();
442  for (auto row = 0; row < num_rows; ++row)
443  {
444  CBioseq_Handle bsh = scope.GetBioseqHandle(*m_id_col->GetData().GetId()[row]);
445  string field = m_Grid->GetCellValue(row, m_field_col).ToStdString();
446  string value = m_Grid->GetCellValue(row, m_source_col).ToStdString();
447  values[bsh][field] = value;
448  }
449  m_GridPanel->CollapseByCol(collapsed_col);
450  Thaw();
451  m_Grid->Refresh();
452 
453  CRef<CCmdComposite> composite(new CCmdComposite("Update Biosource from Biosample"));
454 
455  for (map<CBioseq_Handle, map<string, string> >::iterator it = values.begin(); it != values.end(); ++it)
456  {
457  CSeqdesc_CI src_desc_ci(it->first, CSeqdesc::e_Source);
458  CRef<CSeqdesc> new_desc(new CSeqdesc);
459  new_desc->Assign(*src_desc_ci);
460  CBioSource& biosource = new_desc->SetSource();
461 
462  for (map<string, string>::iterator fi = it->second.begin(); fi != it->second.end(); ++fi)
463  {
464  string field = fi->first;
465  string value = fi->second;
466 
467  if (NStr::EqualNocase(field, "Organism Name"))
468  {
469  if (!NStr::IsBlank(value))
470  {
471  biosource.SetOrg().SetTaxname(value);
472  }
473  else
474  {
475  biosource.SetOrg().ResetTaxname();
476  }
477  if (biosource.GetOrg().IsSetOrgname() && biosource.GetOrg().GetOrgname().IsSetName())
478  {
479  biosource.SetOrg().SetOrgname().ResetName();
480  }
481  }
482  else if (NStr::EqualNocase(field, "Tax ID"))
483  {
485  if (taxid > 0)
486  biosource.SetOrg().SetTaxId(taxid);
487  }
488  else
489  {
490  list<string> vals;
492 
493  bool found = false;
494  try
495  {
497  biosource.RemoveOrgMod(subtype);
498  for (const auto &v : vals)
499  {
500  if (CBioSource::IsStopWord(v))
501  continue;
502  if (!NStr::IsBlank(v))
503  {
504  CRef<COrgMod> mod(new COrgMod());
505  mod->SetSubtype(subtype);
506  mod->SetSubname(v);
507  biosource.SetOrg().SetOrgname().SetMod().push_back(mod);
508  }
509  }
510  found = true;
511  } catch(const CException&)
512  {
513  found = false;
514  }
515  catch (const exception&)
516  {
517  found = false;
518  }
519  if (!found)
520  {
521  try
522  {
524  biosource.RemoveSubSource(subtype);
525  for (const auto &v : vals)
526  {
527  if (CBioSource::IsStopWord(v))
528  continue;
529  if (!NStr::IsBlank(v))
530  {
531  CRef<CSubSource> sub(new CSubSource());
532  sub->SetSubtype(subtype);
533  sub->SetName(v);
534  biosource.SetSubtype().push_back(sub);
535  }
536  }
537  found = true;
538  }
539  catch(const CException&)
540  {
541  found = false;
542  }
543  catch (const exception&)
544  {
545  found = false;
546  }
547  }
548  if (!found)
549  {
550  wxMessageBox(wxT("Unknown field name ") + wxString(field), wxT("Error"), wxOK);
551  return;
552  }
553  }
554  }
555 
556  biosource.AutoFix();
557 
558  CRef<CCmdChangeSeqdesc> cmd(new CCmdChangeSeqdesc(src_desc_ci.GetSeq_entry_Handle(), *src_desc_ci, *new_desc));
559  composite->AddCommand(*cmd);
560  }
561 
562  m_CmdProcessor->Execute(composite);
563  m_modified_source = false;
564 }
565 
566 
568 {
569  return "Invalid operation in Compare with Biosample";
570 }
571 
572 
573 /*!
574  * Should we show tooltips?
575  */
576 
578 {
579  return true;
580 }
581 
582 /*!
583  * Get bitmap resources
584  */
585 
586 wxBitmap CCompareWithBiosample::GetBitmapResource( const wxString& name )
587 {
588  // Bitmap retrieval
589 ////@begin CCompareWithBiosample bitmap retrieval
590  wxUnusedVar(name);
591  return wxNullBitmap;
592 ////@end CCompareWithBiosample bitmap retrieval
593 }
594 
595 /*!
596  * Get icon resources
597  */
598 
599 wxIcon CCompareWithBiosample::GetIconResource( const wxString& name )
600 {
601  // Icon retrieval
602 ////@begin CCompareWithBiosample icon retrieval
603  wxUnusedVar(name);
604  return wxNullIcon;
605 ////@end CCompareWithBiosample icon retrieval
606 }
607 
608 void CCompareWithBiosample::OnClickCancel( wxCommandEvent& event )
609 {
611  if (modified)
612  {
613  wxMessageDialog dlg(this,_("Discard modifications?"), _("Attention"),wxOK|wxCANCEL|wxCENTRE);
614  if (dlg.ShowModal() == wxID_OK)
615  {
616  Close();
617  }
618  }
619  else {
620  Close();
621  }
622 }
623 
624 void CCompareWithBiosample::GetSelectedRows(std::set<int> &selected)
625 {
626  if (!m_Grid->IsSelection())
627  {
628  return;
629  }
630  wxArrayInt wx_selected = m_Grid->GetSelectedRows();
631  if (wx_selected.IsEmpty())
632  {
633  if (m_Grid->GetSelectionBlockTopLeft().size() == 1 && m_Grid->GetSelectionBlockTopLeft().size() == m_Grid->GetSelectionBlockBottomRight().size())
634  {
635  int top_row = m_Grid->GetSelectionBlockTopLeft()[0].GetRow();
636  int bot_row = m_Grid->GetSelectionBlockBottomRight()[0].GetRow();
637  for (int i = top_row; i <= bot_row; i++)
638  {
639  selected.insert(i);
640  }
641  }
642  }
643  else
644  {
645  for (unsigned int i = 0; i < wx_selected.GetCount(); i++)
646  {
647  selected.insert(wx_selected.Item(i));
648  }
649  }
650 }
651 
652 
653 void CCompareWithBiosample::OnSyncButtonClick( wxCommandEvent& event )
654 {
655  Freeze();
656  int collapsed_col = m_GridPanel->GetCollapseColAndExpand();
657 
658  std::set<int> selected;
659  GetSelectedRows(selected);
660  if (selected.empty())
661  {
662  wxMessageBox(wxT("Nothing selected"), wxT("Info"), wxOK);
663  m_GridPanel->CollapseByCol(collapsed_col);
664  Thaw();
665  m_Grid->Refresh();
666  return;
667  }
668 
669  for (std::set<int>::const_iterator i = selected.begin(); i != selected.end(); ++i)
670  if (m_Grid->IsRowShown(*i))
671  {
672  wxString source_value = m_Grid->GetCellValue(*i, m_source_col);
673  wxString sample_value = m_Grid->GetCellValue(*i, m_sample_col);
674 
675  if (sample_value.IsEmpty() && !source_value.IsEmpty())
676  {
677  m_Grid->SetCellTextColour(*i, m_sample_col, wxColour(255, 160, 0));
678  m_Grid->SetCellValue(*i, m_sample_col, source_value);
679  m_modified_sample = true;
680  }
681 
682  if (!sample_value.IsEmpty() && source_value.IsEmpty())
683  {
684  m_Grid->SetCellTextColour(*i, m_source_col, wxColour(255, 160, 0));
685  m_Grid->SetCellValue(*i, m_source_col, sample_value);
686  m_modified_source = true;
687  }
688  }
689 
690  m_GridPanel->CollapseByCol(collapsed_col);
691  Thaw();
692  m_Grid->Refresh();
693 }
694 
696 {
697  Freeze();
698  int collapsed_col = m_GridPanel->GetCollapseColAndExpand();
699 
700  std::set<int> selected;
701  GetSelectedRows(selected);
702  if (selected.empty())
703  {
704  wxMessageBox(wxT("Nothing selected"), wxT("Info"), wxOK);
705  m_GridPanel->CollapseByCol(collapsed_col);
706  Thaw();
707  m_Grid->Refresh();
708  return;
709  }
710 
711  for (std::set<int>::const_iterator i = selected.begin(); i != selected.end(); ++i)
712  if (m_Grid->IsRowShown(*i))
713  {
714  wxString source_value = m_Grid->GetCellValue(*i, m_source_col);
715  wxString sample_value = m_Grid->GetCellValue(*i, m_sample_col);
716 
717  if (!sample_value.IsEmpty() && source_value != sample_value)
718  {
719  m_Grid->SetCellTextColour(*i, m_source_col, wxColour(255, 160, 0));
720  m_Grid->SetCellValue(*i, m_source_col, sample_value);
721  m_modified_source = true;
722  }
723  }
724 
725  m_GridPanel->CollapseByCol(collapsed_col);
726  Thaw();
727  m_Grid->Refresh();
728 }
729 
731 {
732  Freeze();
733  int collapsed_col = m_GridPanel->GetCollapseColAndExpand();
734 
735  std::set<int> selected;
736  GetSelectedRows(selected);
737  if (selected.empty())
738  {
739  wxMessageBox(wxT("Nothing selected"), wxT("Info"), wxOK);
740  m_GridPanel->CollapseByCol(collapsed_col);
741  Thaw();
742  m_Grid->Refresh();
743  return;
744  }
745 
746  for (std::set<int>::const_iterator i = selected.begin(); i != selected.end(); ++i)
747  if (m_Grid->IsRowShown(*i))
748  {
749  wxString source_value = m_Grid->GetCellValue(*i, m_source_col);
750  wxString sample_value = m_Grid->GetCellValue(*i, m_sample_col);
751 
752  if (sample_value != source_value && !source_value.IsEmpty())
753  {
754  m_Grid->SetCellTextColour(*i, m_sample_col, wxColour(255, 160, 0));
755  m_Grid->SetCellValue(*i, m_sample_col, source_value);
756  m_modified_sample = true;
757  }
758 
759  }
760 
761  m_GridPanel->CollapseByCol(collapsed_col);
762  Thaw();
763  m_Grid->Refresh();
764 }
765 
766 void CCompareWithBiosample::OnAddToSource( wxCommandEvent& event )
767 {
768  Freeze();
769  int collapsed_col = m_GridPanel->GetCollapseColAndExpand();
770 
771  std::set<int> selected;
772  GetSelectedRows(selected);
773  if (selected.empty())
774  {
775  wxMessageBox(wxT("Nothing selected"), wxT("Info"), wxOK);
776  m_GridPanel->CollapseByCol(collapsed_col);
777  Thaw();
778  m_Grid->Refresh();
779  return;
780  }
781 
782  for (std::set<int>::const_iterator i = selected.begin(); i != selected.end(); ++i)
783  if (m_Grid->IsRowShown(*i))
784  {
785  wxString source_value = m_Grid->GetCellValue(*i, m_source_col);
786  wxString sample_value = m_Grid->GetCellValue(*i, m_sample_col);
787  wxString field = m_Grid->GetCellValue(*i, m_field_col);
788 
789  if (!sample_value.IsEmpty() && source_value != sample_value && field != _("Organism Name") && field != _("Tax ID"))
790  {
791  list<string> old_vals;
792  NStr::Split(source_value.ToStdString(), "|", old_vals, NStr::fSplit_Tokenize);
793  list<string> new_vals;
794  NStr::Split(sample_value.ToStdString(), "|", new_vals, NStr::fSplit_Tokenize);
795  set<string> vals(old_vals.begin(), old_vals.end());
796  vals.insert(new_vals.begin(), new_vals.end());
797  string new_val = NStr::Join(vals, "|");
798  if (new_val != source_value)
799  {
800  m_Grid->SetCellTextColour(*i, m_source_col, wxColour(255, 160, 0));
801  m_Grid->SetCellValue(*i, m_source_col, new_val);
802  m_modified_source = true;
803  }
804  }
805  }
806 
807  m_GridPanel->CollapseByCol(collapsed_col);
808  Thaw();
809  m_Grid->Refresh();
810 }
811 
812 void CCompareWithBiosample::OnAddToSample( wxCommandEvent& event )
813 {
814  Freeze();
815  int collapsed_col = m_GridPanel->GetCollapseColAndExpand();
816 
817  std::set<int> selected;
818  GetSelectedRows(selected);
819  if (selected.empty())
820  {
821  wxMessageBox(wxT("Nothing selected"), wxT("Info"), wxOK);
822  m_GridPanel->CollapseByCol(collapsed_col);
823  Thaw();
824  m_Grid->Refresh();
825  return;
826  }
827 
828  for (std::set<int>::const_iterator i = selected.begin(); i != selected.end(); ++i)
829  if (m_Grid->IsRowShown(*i))
830  {
831  wxString source_value = m_Grid->GetCellValue(*i, m_source_col);
832  wxString sample_value = m_Grid->GetCellValue(*i, m_sample_col);
833  wxString field = m_Grid->GetCellValue(*i, m_field_col);
834 
835  if (sample_value != source_value && !source_value.IsEmpty() && field != _("Organism Name") && field != _("Tax ID"))
836  {
837  list<string> old_vals;
838  NStr::Split(sample_value.ToStdString(), "|", old_vals, NStr::fSplit_Tokenize);
839  list<string> new_vals;
840  NStr::Split(source_value.ToStdString(), "|", new_vals, NStr::fSplit_Tokenize);
841  set<string> vals(old_vals.begin(), old_vals.end());
842  vals.insert(new_vals.begin(), new_vals.end());
843  string new_val = NStr::Join(vals, "|");
844  if (new_val != sample_value)
845  {
846  m_Grid->SetCellTextColour(*i, m_sample_col, wxColour(255, 160, 0));
847  m_Grid->SetCellValue(*i, m_sample_col, new_val);
848  m_modified_sample = true;
849  }
850  }
851 
852  }
853 
854  m_GridPanel->CollapseByCol(collapsed_col);
855  Thaw();
856  m_Grid->Refresh();
857 }
858 
859 void CCompareWithBiosample::MakeReport(wxCommandEvent& event)
860 {
861  wxString msg;
862  msg << "Seq-id\tField\tSource\tSample\tBiosample Id\n";
863  for (const auto &diff : m_DiffVec)
864  {
865  string field, sample_id;
866  tie(sample_id, field) = diff.first;
867  for (const auto &row : diff.second)
868  {
869  string seq_id = row.first;
870  set<string> set_source, set_sample;
871  tie(set_source, set_sample) = row.second;
872 
873  string source = NStr::Join(set_source, "|");
874  string sample = NStr::Join(set_sample, "|");
875 
876  msg << seq_id <<"\t"<<field<<"\t"<<source<<"\t"<<sample<<"\t"<<sample_id<<"\n";
877  }
878  }
879 
880  CGenericReportDlg* report = new CGenericReportDlg(NULL);
881  report->SetTitle(wxT("Compare with Biosample Report"));
882  report->SetText(msg);
883  report->Show(true);
884 }
885 
886 
887 static const char* kRegPath = "Dialogs.Edit.CompareWithBiosample";
888 static const char* kApiKeyPath = "APIKEY_Path";
889 
891 {
892  if (m_PathToApiKey.empty())
893  return;
894 
896  CRegistryWriteView view = gui_reg.GetWriteView(kRegPath);
897 
899 }
900 
902 {
904  CRegistryReadView view = gui_reg.GetReadView(kRegPath);
905 
908 }
909 
910 static const int chunk_size = 100;
911 
913 {
914  if (m_BioSampleApiKey.empty()) {
916  }
917 
918  if (m_BioSampleApiKey.empty()) {
919  wxMessageBox(wxT("Current BioSample API key is empty. Please specify a new one."), wxT("Error"), wxOK);
920  return;
921  }
922 
923  wxString msg;
924  {
925  wxBusyCursor wait;
926  map<pair<string, string>, list<string> > new_values;
927  {
928  Freeze();
929  int collapsed_col = m_GridPanel->GetCollapseColAndExpand();
930  auto num_rows = m_Grid->GetNumberRows();
931  for (auto row = 0; row < num_rows; ++row)
932  {
933  string seq_id_str = m_id_col->GetData().GetId()[row]->GetSeqIdString();
934  string field = m_Grid->GetCellValue(row, m_field_col).ToStdString();
935  string sample = m_Grid->GetCellValue(row, m_sample_col).ToStdString();
936  string sample_id = m_Grid->GetCellValue(row, m_sample_id_col).ToStdString();
937  list<string> sample_list;
938  NStr::Split(sample, "|", sample_list, NStr::fSplit_Tokenize);
939  sample_list.sort();
940  new_values[pair<string, string>(sample_id, field)] = sample_list;
941  }
942  m_GridPanel->CollapseByCol(collapsed_col);
943  Thaw();
944  m_Grid->Refresh();
945  }
946 
947  unordered_map<string, map<string, vector<string> > > delete_value, add_value;
948  set<string> ids;
949  unordered_map<string, string> change_organism;
950  for (const auto &diff : m_DiffVec)
951  {
952  string field, sample_id;
953  tie(sample_id, field) = diff.first;
954  list<string> new_sample;
955  if (new_values.find(diff.first) != new_values.end())
956  new_sample = new_values[diff.first];
957 
958  set<string> set_source, old_sample;
959  tie(set_source, old_sample) = diff.second.begin()->second;
960 
961 
962  NStr::ReplaceInPlace(field, "-", "_");
963 
964  vector<string> deleted_values;
965  set_difference(old_sample.begin(), old_sample.end(), new_sample.begin(), new_sample.end(), inserter(deleted_values, deleted_values.end()));
966 
967  vector<string> added_values;
968  set_difference(new_sample.begin(), new_sample.end(), old_sample.begin(), old_sample.end(), inserter(added_values, added_values.end()));
969 
970  if (field == "Organism Name")
971  {
972  if (added_values.size() == 1 && deleted_values.size() == 1)
973  {
974  change_organism[sample_id] = added_values.front();
975  ids.insert(sample_id);
976  }
977  continue;
978  }
979  if (!deleted_values.empty())
980  {
981  delete_value[sample_id][field] = deleted_values;
982  ids.insert(sample_id);
983  }
984 
985  if (!added_values.empty())
986  {
987  add_value[sample_id][field] = added_values;
988  ids.insert(sample_id);
989  }
990  }
991  for (const auto &diff : new_values)
992  {
993  string field, sample_id;
994  tie(sample_id, field) = diff.first;
995  vector<string> new_sample(diff.second.begin(), diff.second.end());
996 
997  if (m_DiffVec.find(diff.first) != m_DiffVec.end())
998  {
999  continue;
1000  }
1001 
1002  if (new_sample.empty())
1003  {
1004  continue;
1005  }
1006 
1007  NStr::ReplaceInPlace(field, "-", "_");
1008  add_value[sample_id][field] = new_sample;
1009  ids.insert(sample_id);
1010  }
1011  int response_timeout = CGuiRegistry::GetInstance().GetInt("GBENCH.System.SeqConfigTimeout", 40);
1012  //string sUrl = "https://dev-api-int.ncbi.nlm.nih.gov/biosample/update/"; // DEBUG
1013  string sUrl = "https://api-int.ncbi.nlm.nih.gov/biosample/update/";
1014  string sContentType = "application/json; charset=utf-8";
1015 
1016  auto sample_id_it = ids.begin();
1017  while (sample_id_it != ids.end())
1018  {
1019  int count = 0;
1020  CJson_Document req;
1021  CJson_Object top_obj = req.SetObject();
1022  CJson_Array biosample_array = top_obj.insert_array("update");
1023  for (; sample_id_it != ids.end() && count < chunk_size; ++sample_id_it)
1024  {
1025  auto sample_id = *sample_id_it;
1026  CJson_Object obj1 = biosample_array.push_back_object();
1027  obj1.insert("samples", sample_id);
1028  if (!delete_value[sample_id].empty())
1029  {
1030  CJson_Array del_arr = obj1.insert_object("delete").insert_array("attribute");
1031  for (const auto &kv : delete_value[sample_id])
1032  {
1033  const string &field = kv.first;
1034  for (const auto &v : kv.second)
1035  {
1036  CJson_Object obj2 = del_arr.push_back_object();
1037  obj2.insert("name", field);
1038  obj2.insert("old_value", v);
1039  count++;
1040  }
1041  }
1042  }
1043  if ( !change_organism[sample_id].empty())
1044  {
1045  CJson_Object chg_obj = obj1.insert_object("change");
1046  CJson_Object chg_org = chg_obj.insert_object("organism");
1047  chg_org.insert("new_value", change_organism[sample_id]);
1048  count++;
1049  }
1050  if (!add_value[sample_id].empty())
1051  {
1052  CJson_Array add_arr = obj1.insert_object("add").insert_array("attribute");
1053  for (const auto &kv : add_value[sample_id])
1054  {
1055  const string &field = kv.first;
1056  for (const auto &v : kv.second)
1057  {
1058  CJson_Object obj2 = add_arr.push_back_object();
1059  obj2.insert("name", field);
1060  obj2.insert("new_value", v);
1061  count++;
1062  }
1063  }
1064  }
1065  }
1066  top_obj.insert_object("options").insert("attribute_synonyms", true);
1067 
1068  string sData = req.ToString();
1069  //cout << "REQUEST" << endl;
1070  //cout << sData << endl;
1071 
1072  CUrl curl(sUrl);
1073  CHttpHeaders headers;
1074  headers.SetValue("NCBI-BioSample-Authorization", m_BioSampleApiKey);
1075  CHttpResponse response = g_HttpPost(curl, headers, sData, sContentType); // send biosample request
1076  if (response.GetStatusCode() != 200) {
1077  stringstream ss;
1078  NcbiStreamCopy(ss, response.ErrorStream());
1079  string err = ss.str();
1080  if (err.empty())
1081  err = "Unable to connect - server down?";
1082  wxMessageBox(wxString(err), wxT("Error"), wxOK);
1083  break;
1084  }
1085 
1086  stringstream ss;
1087  NcbiStreamCopy(ss, response.ContentStream());
1088  bool has_error = false;
1089  auto rep_update = x_ReportBiosampleUpdate(ss.str(), has_error);
1090  if (has_error) {
1091  wxMessageBox(wxT("Current BioSample API key was not recognized. Please specify a new one."), wxT("Error"), wxOK);
1092  break;
1093  }
1094  else {
1095  msg << rep_update;
1096  }
1097  }
1098  }
1099 
1100  m_modified_sample = false;
1101  if (!msg.IsEmpty()) {
1102  CGenericReportDlg *report = new CGenericReportDlg(this);
1103  report->SetTitle(wxT("Biosample Update Report"));
1104  report->SetText(msg);
1105  report->Show(true);
1106  report->Raise();
1107  wxYieldIfNeeded();
1108  }
1109  else {
1110  wxWindow *win = FindWindowByLabel(wxT("Biosample Update Report"), this);
1111  if (win) {
1112  CGenericReportDlg *report = dynamic_cast<CGenericReportDlg *>(win);
1113  if (report)
1114  report->Close();
1115  }
1116  }
1117  x_ReloadTable();
1118 
1119 }
1120 
1121 void CCompareWithBiosample::OnNewAPIKey(wxCommandEvent& event)
1122 {
1123  x_DoUpdateAPIKey();
1124 }
1125 
1127 {
1128  CFileLocDialog dlg(this);
1129  if (dlg.ShowModal() == wxID_OK) {
1130  m_PathToApiKey = dlg.GetFilename();
1132  }
1133 }
1134 
1136 {
1137  CNcbiIfstream istr(m_PathToApiKey.data());
1138  if (istr.good()) {
1139  istr >> m_BioSampleApiKey;
1140  }
1141 }
1142 
1144 {
1145 /*
1146  int collapsed_col = m_GridPanel->GetCollapseColAndExpand();
1147  vector<pair<wxString, wxColour> > redo_values;
1148  for (int row = 0; row < m_Grid->GetNumberRows(); row++) {
1149  if (!m_Grid->IsReadOnly(row, m_source_col) && m_Grid->IsRowShown(row)) {
1150  redo_values.push_back(make_pair(m_Grid->GetCellValue(row, m_source_col),
1151  m_Grid->GetCellTextColour(row, m_source_col)));
1152  }
1153  }
1154 */
1155 
1156 
1157  x_LoadData();
1158 
1159  if (m_DiffVec.empty())
1160  {
1161  wxMessageBox(wxT("No differences found for resolved Biosample IDs"), wxT("Info"), wxOK);
1162  Close();
1163  return;
1164  }
1166  if (values_table->GetNum_rows() < 1)
1167  {
1168  wxMessageBox(wxT("No differences found for resolved Biosample IDs"), wxT("Info"), wxOK);
1169  Close();
1170  return;
1171  }
1172  x_AddTablePanel(values_table);
1173 /*
1174  for (int row = 0; row < redo_values.size(); row++)
1175  {
1176  wxString val = redo_values[row].first;
1177  wxColour colour = redo_values[row].second;
1178  m_Grid->SetCellTextColour(row, m_source_col, colour);
1179  m_Grid->SetCellValue(row, m_source_col, val);
1180  }
1181  m_GridPanel->CollapseByCol(collapsed_col);
1182 */
1183 }
1184 
1185 void CCompareWithBiosample::OnRefresh(wxCommandEvent& event)
1186 {
1187  wxWindow *win = FindWindowByLabel(wxT("Biosample Update Report"), this);
1188  if (win)
1189  {
1190  CGenericReportDlg *report = dynamic_cast<CGenericReportDlg *>(win);
1191  if (report)
1192  report->Close();
1193  }
1194 
1195  if (m_timer.IsRunning()) {
1196  m_timer.Stop();
1197  }
1198  m_RefreshButton->Disable();
1199  x_ReloadTable();
1200  if (!m_timer.IsRunning()) {
1201  m_timer.Start(3000);
1202  }
1203 }
1204 
1205 wxString CCompareWithBiosample::x_ReportBiosampleUpdate(const string &str, bool& has_error)
1206 {
1207  //cout << "REPLY" <<endl;
1208  //cout << str << endl;
1209  has_error = false;
1210  wxString report;
1211  CJson_Document doc;
1212  doc.ParseString(str);
1213 
1214  if (!doc.ReadSucceeded() || !doc.IsObject())
1215  return report;
1216 
1217  CJson_ConstObject obj = doc.GetObject();
1218 
1219  auto error_it = obj.find("has_error");
1220  if (error_it != obj.end() && error_it->value.GetValue().GetBool() == true) {
1221  auto msg_it = obj.find("messages");
1222  if (msg_it != obj.end() && msg_it->value.IsArray() && !msg_it->value.GetArray().empty()) {
1223  const auto& messages = msg_it->value.GetArray();
1224  for (const auto& resp_it : messages) {
1225  if (resp_it.IsObject()) {
1226  const auto& resp_obj = resp_it.GetObject();
1227  auto level_it = resp_obj.find("level");
1228  auto message_it = resp_obj.find("message");
1229  if ((level_it != resp_obj.end()) &&
1230  (message_it != resp_obj.end()) &&
1231  (level_it->value.GetValue().GetString() == "error") &&
1232  (NStr::StartsWith(message_it->value.GetValue().GetString(), "Please sign in to NCBI", NStr::eNocase))){
1233  has_error = true;
1234  return report;
1235  }
1236  }
1237  }
1238  }
1239  }
1240 
1241  CJson_ConstObject::const_iterator it = obj.find("messages");
1242  if (it == obj.end() || !it->value.IsArray() || it->value.GetArray().empty())
1243  return report;
1244 
1245  unordered_map<string, vector<string> > messages;
1246  for ( CJson_ConstArray::const_iterator it2 = it->value.GetArray().begin(); it2 != it->value.GetArray().end(); ++it2)
1247  {
1248  CJson_ConstObject obj2 = it2->GetObject();
1249  if (obj2.find("level") != obj2.end() && obj2.find("message") != obj2.end())
1250  {
1251  string level = obj2["level"].GetValue().GetString();
1252  string msg = obj2["message"].GetValue().GetString();
1253  messages[level].push_back(msg);
1254  }
1255  }
1256 
1257 
1258  it = obj.find("validation_report");
1259  if (it != obj.end() && it->value.IsObject() && !it->value.GetObject().empty())
1260  {
1261  map<string, map<string, string> > validation_error, validation_warning;
1262  for ( CJson_ConstObject::const_iterator it2 = it->value.GetObject().begin(); it2 != it->value.GetObject().end(); ++it2)
1263  {
1264  string name(it2->name);
1265  for ( CJson_ConstArray::const_iterator it3 = it2->value.GetArray().begin(); it3 != it2->value.GetArray().end(); ++it3)
1266  {
1267  CJson_ConstObject obj2 = it3->GetObject();
1268  if (obj2.find("message") == obj2.end())
1269  {
1270  continue;
1271  }
1272 
1273  string validation_msg;
1274  if (obj2.find("type") != obj2.end())
1275  {
1276  string type = obj2["type"].GetValue().GetString();
1277  if (type == "attribute_error" && obj2.find("attribute_name") != obj2.end())
1278  {
1279  string attribute_name = obj2["attribute_name"].GetValue().GetString();
1280  validation_msg += " " + attribute_name;
1281  if (obj2.find("attribute_value") != obj2.end())
1282  {
1283  string attribute_value = obj2["attribute_value"].GetValue().GetString();
1284  if (!attribute_value.empty())
1285  validation_msg += ":" + attribute_value;
1286  }
1287  }
1288  }
1289 
1290  string msg = obj2["message"].GetValue().GetString();
1291  bool is_warning = false;
1292  if (obj2.find("is_warning") != obj2.end())
1293  is_warning = obj2["is_warning"].GetValue().GetBool();
1294  if (obj2.find("name") != obj2.end())
1295  {
1296  string short_name = obj2["name"].GetValue().GetString();
1297  msg += " (" + short_name + ")";
1298  if (short_name == "taxonomy_error_warning" || short_name == "tax_consult_warning" || short_name == "taxonomy_service_failure_warning")
1299  {
1300  wxMessageBox(wxString(msg), wxT("Taxonomy Consult Warning"), wxOK);
1301  }
1302  }
1303  if (is_warning)
1304  validation_warning[msg][name] = validation_msg;
1305  else
1306  validation_error[msg][name] = validation_msg;
1307  }
1308  }
1309  for (const auto &m : validation_error)
1310  {
1311  messages["error"].push_back(m.first);
1312  for (const auto &name : m.second)
1313  {
1314  string str = name.first;
1315  if (!name.second.empty())
1316  str += " - " + name.second;
1317  messages["error"].push_back(str);
1318  }
1319  }
1320  for (const auto &m : validation_warning)
1321  {
1322  messages["warning"].push_back(m.first);
1323  for (const auto &name : m.second)
1324  {
1325  string str = name.first;
1326  if (!name.second.empty())
1327  str += " - " + name.second;
1328  messages["warning"].push_back(str);
1329  }
1330  }
1331  }
1332 
1333  if (messages.empty())
1334  return report;
1335 
1336  if (!messages["error"].empty())
1337  {
1338  report << "Error:\n";
1339  for (const auto &m : messages["error"])
1340  report << m << "\n";
1341  report << "\n";
1342  }
1343  if (!messages["warning"].empty())
1344  {
1345  report << "Warning:\n";
1346  for (const auto &m : messages["warning"])
1347  report << m << "\n";
1348  report << "\n";
1349  }
1350  if (!messages["info"].empty())
1351  {
1352  report << "Info:\n";
1353  for (const auto &m : messages["info"])
1354  report << m << "\n";
1355  report << "\n";
1356  }
1357  return report;
1358 }
1359 
1360 
1361 /*
1362  * CFileLocDialog type definition
1363  */
1364 
1365 IMPLEMENT_DYNAMIC_CLASS(CFileLocDialog, wxDialog)
1366 
1367 
1368 /*
1369  * CFileLocDialog event table definition
1370  */
1371 
1372 BEGIN_EVENT_TABLE(CFileLocDialog, wxDialog)
1373 
1375 
1376 
1378 {
1379  Init();
1380 }
1381 
1382 CFileLocDialog::CFileLocDialog(wxWindow* parent, wxWindowID id, const wxString& caption, const wxPoint& pos, const wxSize& size, long style)
1383 {
1384  Init();
1385  Create(parent, id, caption, pos, size, style);
1386 }
1387 
1388 bool CFileLocDialog::Create(wxWindow* parent, wxWindowID id, const wxString& caption, const wxPoint& pos, const wxSize& size, long style)
1389 {
1390  ////@begin CFileLocDialog creation
1391  SetExtraStyle(wxWS_EX_BLOCK_EVENTS);
1392  wxDialog::Create(parent, id, caption, pos, size, style);
1393 
1394  CreateControls();
1395  if (GetSizer())
1396  {
1397  GetSizer()->SetSizeHints(this);
1398  }
1399  Centre();
1400  ////@end CFileLocDialog creation
1401  return true;
1402 }
1403 
1405 {
1406  m_Filename = nullptr;
1407 }
1408 
1410 {
1411  CFileLocDialog* itemDialog1 = this;
1412 
1413  wxBoxSizer* itemBoxSizer2 = new wxBoxSizer(wxVERTICAL);
1414  itemDialog1->SetSizer(itemBoxSizer2);
1415 
1416  wxBoxSizer* itemBoxSizer4 = new wxBoxSizer(wxHORIZONTAL);
1417  itemBoxSizer2->Add(itemBoxSizer4, 0, wxEXPAND | wxALL, 0);
1418 
1419  m_Filename = new wxTextCtrl(itemDialog1, ID_FILELOCTEXTCTRL, wxEmptyString, wxDefaultPosition, wxSize(300, -1), 0);
1420  itemBoxSizer4->Add(m_Filename, 1, wxALIGN_LEFT | wxALL, 5);
1421 
1422  wxButton* itemButton5 = new wxBitmapButton(itemDialog1, wxID_ANY, wxArtProvider::GetBitmap(wxT("menu::open")), wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW);
1423  itemButton5->SetToolTip(wxT("Choose a file..."));
1424  itemBoxSizer4->Add(itemButton5, 0, wxALIGN_CENTER_VERTICAL | wxTOP |wxBOTTOM | wxRIGHT, 5);
1425  itemButton5->Bind(wxEVT_BUTTON, &CFileLocDialog::OnOpenFile, this);
1426 
1427 
1428  wxBoxSizer* itemBoxSizer6 = new wxBoxSizer(wxHORIZONTAL);
1429  itemBoxSizer2->Add(itemBoxSizer6, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
1430 
1431  wxButton* itemButton7 = new wxButton(itemDialog1, wxID_OK, _("OK"), wxDefaultPosition, wxDefaultSize, 0);
1432  itemBoxSizer6->Add(itemButton7, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
1433 
1434  wxButton* itemButton8 = new wxButton(itemDialog1, wxID_CANCEL, _("Cancel"), wxDefaultPosition, wxDefaultSize, 0);
1435  itemBoxSizer6->Add(itemButton8, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
1436 }
1437 
1438 void CFileLocDialog::OnOpenFile(wxCommandEvent& event)
1439 {
1440  wxFileDialog dlg(this, wxT("Select file"), wxEmptyString, wxEmptyString, _("All files (*.*)|*.*"), wxFD_OPEN | wxFD_FILE_MUST_EXIST);
1441 
1442  if (dlg.ShowModal() == wxID_OK) {
1443  auto mapped_path = GetAbsolutePath(dlg.GetPath());
1444  m_Filename->SetValue(mapped_path);
1445  }
1446 }
1447 
1449 {
1450  return ToStdString(m_Filename->GetValue());
1451 }
1452 
1453 
1454 /*
1455  * Should we show tooltips?
1456  */
1457 
1459 {
1460  return true;
1461 }
1462 
1463 /*
1464  * Get bitmap resources
1465  */
1466 
1467 wxBitmap CFileLocDialog::GetBitmapResource(const wxString& name)
1468 {
1469  // Bitmap retrieval
1470 ////@begin CLoginDialog bitmap retrieval
1471  wxUnusedVar(name);
1472  return wxNullBitmap;
1473  ////@end CLoginDialog bitmap retrieval
1474 }
1475 
1476 /*
1477  * Get icon resources
1478  */
1479 
1480 wxIcon CFileLocDialog::GetIconResource(const wxString& name)
1481 {
1482  // Icon retrieval
1483 ////@begin CLoginDialog icon retrieval
1484  wxUnusedVar(name);
1485  return wxNullIcon;
1486  ////@end CLoginDialog icon retrieval
1487 }
1488 
1489 //TODO: deal with fields which can appear multiple times within the same bioseq.
1490 
1491 
1492 
vector< CRef< CBiosampleFieldDiff > > TBiosampleFieldDiffList
map< string, CRef< CSeq_descr > > TBioSamples
TBiosampleFieldDiffList GetBioseqDiffs(CBioseq_Handle bh, const string &biosample_accession, size_t &num_processed, vector< string > &unprocessed_ids, bool use_dev_server=false, bool compare_structured_comments=false, const string &expected_prefix="", TBioSamples *cache=NULL)
void AutoFix()
Definition: BioSource.cpp:1392
static bool IsStopWord(const string &value)
Definition: BioSource.cpp:1382
bool RemoveOrgMod(int subtype)
Definition: BioSource.cpp:1636
bool RemoveSubSource(int subtype)
Definition: BioSource.cpp:1591
CBioseq_CI –.
Definition: bioseq_ci.hpp:69
CBioseq_Handle –.
void AddCommand(IEditCommand &command)
void OnAddToSample(wxCommandEvent &event)
void OnAddToSource(wxCommandEvent &event)
CRef< objects::CSeq_table > GetChoices(CRef< objects::CSeq_table > values_table)
CStringConstraintSelect * m_StringConstraintPanel
void OnSyncButtonClick(wxCommandEvent &event)
bool Create(wxWindow *parent, wxWindowID id=wxID_ANY, const wxString &caption=_("Compare with Biosample"), const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxDefaultSize, long style=wxMINIMIZE_BOX|wxMAXIMIZE_BOX|wxCLOSE_BOX|wxCAPTION|wxCLIP_CHILDREN)
Creation.
ICommandProccessor * m_CmdProcessor
void CreateBiosampleUpdateWebService(wxCommandEvent &event)
wxIcon GetIconResource(const wxString &name)
Retrieves icon resources.
CRef< objects::CSeq_table > GetValuesTableFromSeqEntry()
CRef< objects::CSeqTable_column > m_id_col
void OnRefresh(wxCommandEvent &event)
void OnClickCancel(wxCommandEvent &event)
void x_AddTablePanel(CRef< objects::CSeq_table > values_table)
map< pair< string, string >, unordered_map< string, pair< set< string >, set< string > > > > m_DiffVec
void Init()
Initialises member variables.
CSeqTableGridPanel * m_GridPanel
void OnCopyToSourceButtonClick(wxCommandEvent &event)
void OnNewAPIKey(wxCommandEvent &event)
map< string, CConstRef< CSeq_id > > m_ids
wxString x_ReportBiosampleUpdate(const string &str, bool &has_error)
bool IsReadOnlyColumn(string column_name)
void GetSelectedRows(std::set< int > &selected)
biosample_util::TBioSamples m_Cache
void CreateControls()
Creates the controls and sizers.
void OnCopyToSampleButtonClick(wxCommandEvent &event)
CApplyEditconvertPanel * m_AecrPanel
wxBitmap GetBitmapResource(const wxString &name)
Retrieves bitmap resources.
void MakeReport(wxCommandEvent &event)
void OnClickOk(wxCommandEvent &event)
static bool ShowToolTips()
Should we show tooltips?
void OnOpenFile(wxCommandEvent &event)
wxBitmap GetBitmapResource(const wxString &name)
Retrieves bitmap resources.
CFileLocDialog()
Constructors.
wxIcon GetIconResource(const wxString &name)
Retrieves icon resources.
static bool ShowToolTips()
Should we show tooltips?
void CreateControls()
Creates the controls and sizers.
void Init()
Initialises member variables.
bool Create(wxWindow *parent, wxWindowID id=13000, const wxString &caption=_("Select File with BioSample API Key"), const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxSize(400, 300), long style=wxCAPTION|wxRESIZE_BORDER|wxSYSTEM_MENU|wxCLOSE_BOX|wxTAB_TRAVERSAL)
Creation.
void SetText(const wxString &text)
CRegistryWriteView GetWriteView(const string &section)
get a read-write view at a particular level.
Definition: registry.cpp:462
static CGuiRegistry & GetInstance()
access the application-wide singleton
Definition: registry.cpp:400
CRegistryReadView GetReadView(const string &section) const
get a read-only view at a particular level.
Definition: registry.cpp:428
int GetInt(const string &key, int default_val=0) const
retrieve values by section and key.
Definition: registry.cpp:133
HTTP response.
CJson_Object push_back_object(void)
Add object type element to the end of the array.
Random-access iterator to access const JSON array element.
const_iterator begin(void) const
Return a random-access iterator to the first element in the array.
bool empty(void) const
Test if the array is empty.
const_iterator end(void) const
Return a random-access iterator that points just beyond the end of the array.
bool IsObject(void) const
CJson_ConstObject GetObject(void) const
Get JSON object contents of the node.
bool IsArray(void) const
CJson_ConstArray GetArray(void) const
Get JSON array contents of the node.
std::string ToString(TJson_Write_Flags flags=fJson_Write_IndentWithSpace, unsigned int indent_char_count=4) const
Convert the contents of the node into string.
CJson_ConstValue GetValue(void) const
Get JSON value contents of the node.
Bidirectional iterator to access const JSON object element.
const CJson_ConstNode value
CJson_Object.
bool empty(void) const
Test if the object is empty.
const_iterator find(const CJson_Node::TKeyType &name) const
Return an iterator that points to the location of the element.
const_iterator begin(void) const
Return an iterator that points to the first element in the object.
const_iterator end(void) const
Return an iterator that points to the location after the last element.
bool GetBool(void) const
Get primitive value data.
TStringType GetString(void) const
bool ParseString(const TStringType &v)
Read JSON data from a UTF8 string.
bool ReadSucceeded(void) const
Test if the most recent read was successful.
CJson_Object SetObject(void)
Get JSON object contents of the node.
CJson_Array insert_array(const CJson_Node::TKeyType &name)
Insert array type element into the object.
void insert(const CJson_Node::TKeyType &name)
Insert null element into the object.
CJson_Object insert_object(const CJson_Node::TKeyType &name)
Insert object type element into the object.
@OrgMod.hpp User-defined methods of the data storage class.
Definition: OrgMod.hpp:54
static TSubtype GetSubtypeValue(const string &str, EVocabulary vocabulary=eVocabulary_raw)
Definition: OrgMod.cpp:62
class CRegistryReadView provides a nested hierarchical view at a particular key.
Definition: reg_view.hpp:58
string GetString(const string &key, const string &default_val=kEmptyStr) const
Definition: reg_view.cpp:246
void Set(const string &key, int val)
access a named key at this level, with no recursion
Definition: reg_view.cpp:533
CScope –.
Definition: scope.hpp:92
void MakeColumnReadOnly(int pos, bool val=true)
void CollapseByCol(int col)
int GetCollapseColAndExpand(void)
wxGrid * GetGrid(void)
void InitColumnCollapse(int col)
CSeq_entry_Handle –.
CSeqdesc_CI –.
Definition: seqdesc_ci.hpp:65
static TSubtype GetSubtypeValue(const string &str, EVocabulary vocabulary=eVocabulary_raw)
Definition: SubSource.cpp:128
CUrl –.
Definition: ncbi_url.hpp:353
Undo/Redo interface for editing operations.
virtual void Execute(IEditCommand *command, wxWindow *window=0)=0
const_iterator begin() const
Definition: map.hpp:151
const_iterator end() const
Definition: map.hpp:152
bool empty() const
Definition: map.hpp:149
void clear()
Definition: map.hpp:169
const_iterator find(const key_type &key) const
Definition: map.hpp:153
Definition: map.hpp:338
iterator_bool insert(const value_type &val)
Definition: set.hpp:149
const_iterator begin() const
Definition: set.hpp:135
const_iterator end() const
Definition: set.hpp:136
USING_SCOPE(objects)
static const int chunk_size
static const char * kRegPath
static const char * kApiKeyPath
#define ID_COPY_TO_SAMPLE
#define ID_ADD_TO_SOURCE
#define ID_CREATE_BIOSAMPLE
#define ID_UPDATE_BIOSOURCE
#define ID_FILELOCTEXTCTRL
#define ID_SYNC
#define ID_ADD_TO_SAMPLE
#define ID_REFRESH_BIOSAMPLE
#define ID_COPY_TO_SOURCE
#define ID_MAKE_REPORT
#define ID_APIKEY_BIOSAMPLE
#define _(proto)
Definition: ct_nlmzip_i.h:78
#define wxFIXED_MINSIZE
const char * kSequenceIdColLabel
static CS_COMMAND * cmd
Definition: ct_dynamic.c:26
static void Init(void)
Definition: cursor6.c:76
static const char * str(char *buf, int n)
Definition: stats.c:84
#define ITERATE(Type, Var, Cont)
ITERATE macro to sequence through container elements.
Definition: ncbimisc.hpp:815
#define NULL
Definition: ncbistd.hpp:225
#define NCBI_THROW(exception_class, err_code, message)
Generic macro to throw an exception, given the exception class, error code and message string.
Definition: ncbiexpt.hpp:704
virtual void Assign(const CSerialObject &source, ESerialRecursionMode how=eRecursive)
Set object to copy of another one.
CNcbiIstream & ContentStream(void) const
Get input stream.
int GetStatusCode(void) const
Get response status code.
void SetValue(CHeaderNameConverter name, CTempString value)
Remove all existing values with the name, set the new value.
CNcbiIstream & ErrorStream(void) const
Get input stream containing error message (e.g.
CHttpResponse g_HttpPost(const CUrl &url, CTempString data, const CHttpParam &param=CHttpParam())
Shortcut for POST request.
static int BestRank(const CRef< CSeq_id > &id)
Definition: Seq_id.hpp:774
@ fParse_Default
By default in ParseIDs and IsValid, allow raw parsable non-numeric accessions and plausible local acc...
Definition: Seq_id.hpp:102
CBioseq_Handle GetBioseqHandle(const CSeq_id &id)
Get bioseq handle by seq-id.
Definition: scope.cpp:95
vector< CSeq_id_Handle > TId
CScope & GetScope(void) const
Get scope this handle belongs to.
CSeq_entry_Handle GetSeq_entry_Handle(void) const
Definition: seqdesc_ci.cpp:326
TObjectType * GetPointer(void) const THROWS_NONE
Get pointer,.
Definition: ncbiobj.hpp:1684
void Reset(void)
Reset reference object.
Definition: ncbiobj.hpp:773
#define END_NCBI_SCOPE
End previously defined NCBI scope.
Definition: ncbistl.hpp:103
#define BEGIN_NCBI_SCOPE
Define ncbi namespace.
Definition: ncbistl.hpp:100
IO_PREFIX::ifstream CNcbiIfstream
Portable alias for ifstream.
Definition: ncbistre.hpp:439
bool NcbiStreamCopy(CNcbiOstream &os, CNcbiIstream &is)
Copy the entire contents of stream "is" to stream "os".
Definition: ncbistre.cpp:211
#define kEmptyStr
Definition: ncbistr.hpp:123
static int StringToInt(const CTempString str, TStringToNumFlags flags=0, int base=10)
Convert string to int.
Definition: ncbistr.cpp:630
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:3461
static bool IsBlank(const CTempString str, SIZE_TYPE pos=0)
Check if a string is blank (has no text).
Definition: ncbistr.cpp:106
static string Join(const TContainer &arr, const CTempString &delim)
Join strings using the specified delimiter.
Definition: ncbistr.hpp:2697
static bool StartsWith(const CTempString str, const CTempString start, ECase use_case=eCase)
Check if a string starts with a specified prefix value.
Definition: ncbistr.hpp:5412
static bool EqualNocase(const CTempString s1, SIZE_TYPE pos, SIZE_TYPE n, const char *s2)
Case-insensitive equality of a substring with another string.
Definition: ncbistr.hpp:5353
static string & ReplaceInPlace(string &src, const string &search, const string &replace, SIZE_TYPE start_pos=0, SIZE_TYPE max_replace=0, SIZE_TYPE *num_replace=0)
Replace occurrences of a substring within a string.
Definition: ncbistr.cpp:3405
@ fConvErr_NoThrow
Do not throw an exception on error.
Definition: ncbistr.hpp:285
@ fSplit_Tokenize
All delimiters are merged and trimmed, to get non-empty tokens only.
Definition: ncbistr.hpp:2508
@ eNocase
Case insensitive compare.
Definition: ncbistr.hpp:1206
C::value_type FindBestChoice(const C &container, F score_func)
Find the best choice (lowest score) for values in a container.
Definition: ncbiutil.hpp:250
static const char label[]
void SetSubtype(TSubtype value)
Assign a value to Subtype data member.
Definition: SubSource_.hpp:319
const TOrg & GetOrg(void) const
Get the Org member data.
Definition: BioSource_.hpp:509
void SetOrg(TOrg &value)
Assign a value to Org data member.
Definition: BioSource_.cpp:108
void SetName(const TName &value)
Assign a value to Name data member.
Definition: SubSource_.hpp:359
TSubtype & SetSubtype(void)
Assign a value to Subtype data member.
Definition: BioSource_.hpp:545
bool IsSetOrgname(void) const
Check if a value has been assigned to Orgname data member.
Definition: Org_ref_.hpp:529
bool IsSetName(void) const
Check if a value has been assigned to Name data member.
Definition: OrgName_.hpp:759
const TOrgname & GetOrgname(void) const
Get the Orgname member data.
Definition: Org_ref_.hpp:541
const TColumns & GetColumns(void) const
Get the Columns member data.
Definition: Seq_table_.hpp:433
void SetHeader(THeader &value)
Assign a value to Header data member.
vector< CRef< CSeqTable_column > > TColumns
Definition: Seq_table_.hpp:92
void SetData(TData &value)
Assign a value to Data data member.
TNum_rows GetNum_rows(void) const
Get the Num_rows member data.
Definition: Seq_table_.hpp:393
bool IsGenbank(void) const
Check if variant Genbank is selected.
Definition: Seq_id_.hpp:841
TSource & SetSource(void)
Select the variant.
Definition: Seqdesc_.cpp:572
@ e_Source
source of materials, includes Org-ref
Definition: Seqdesc_.hpp:133
@ eMol_na
just a nucleic acid
Definition: Seq_inst_.hpp:113
<!DOCTYPE HTML >< html > n< header > n< title > PubSeq Gateway Help Page</title > n< style > n table
END_EVENT_TABLE()
int i
#define wxT(x)
Definition: muParser.cpp:41
void ReportUsage(const wxString &dialog_name)
Report opening & accepting events in the editing package.
constexpr bool empty(list< Ts... >) noexcept
const struct ncbi::grid::netcache::search::fields::SIZE size
const GenericPointer< typename T::ValueType > T2 value
Definition: pointer.h:1227
const CharType(& source)[N]
Definition: pointer.h:1149
Int mod(Int i, Int j)
Definition: njn_integer.hpp:67
#define fi
static static static wxID_ANY
#define row(bind, expected)
Definition: string_bind.c:73
Definition: type.c:6
wxString GetAbsolutePath(const wxString &localpath)
Definition: wx_utils.cpp:188
string ToStdString(const wxString &s)
Definition: wx_utils.hpp:161
Modified on Mon Apr 22 04:04:09 2024 by modify_doxy.py rev. 669887