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

Go to the SVN repository for this file.

1 /* $Id: bulk_miscfeat_edit.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: Andrea Asztalos, based on a file written by Igor Filippov
27  */
28 #include <ncbi_pch.hpp>
31 #include <objmgr/feat_ci.hpp>
32 
38 
41 
42 
43 IMPLEMENT_DYNAMIC_CLASS(CBulkMiscFeat, wxDialog )
44 
45 BEGIN_EVENT_TABLE(CBulkMiscFeat, wxDialog )
46 
47  EVT_BUTTON( wxID_OK, CBulkMiscFeat::OnClickOk )
48 
49  EVT_BUTTON( wxID_CANCEL, CBulkMiscFeat::OnClickCancel )
50 
51 
53 
55 {
56  Init();
57 }
58 
59 CBulkMiscFeat::CBulkMiscFeat( wxWindow* parent, CSeq_entry_Handle seh, IWorkbench* workbench,
60  CConstRef<CSeq_submit> seqSubmit, wxWindowID id, const wxString& caption, const wxPoint& pos,
61  const wxSize& size, long style )
62 {
63  this->m_Workbench = workbench;
64  this->m_SeqSubmit = seqSubmit;
65 
67  for ( ; fi ; ++fi ) {
68  m_FeatHandles.push_back(fi->GetSeq_feat_Handle());
69  }
70 
71  Init();
72  Create(parent, id, caption, pos, size, style);
73 }
74 
75 CBulkMiscFeat::CBulkMiscFeat( wxWindow* parent, const vector<CSeq_feat_Handle> &feat_handles,
76  IWorkbench* workbench, wxWindowID id, const wxString& caption, const wxPoint& pos,
77  const wxSize& size, long style )
78  : m_FeatHandles(feat_handles)
79 {
80  this->m_Workbench = workbench;
81 
82  Init();
83  Create(parent, id, caption, pos, size, style);
84 }
85 
86 
87 bool CBulkMiscFeat::Create( wxWindow* parent, wxWindowID id, const wxString& caption,
88  const wxPoint& pos, const wxSize& size, long style )
89 {
90  SetExtraStyle(wxWS_EX_BLOCK_EVENTS);
91  SetLayoutAdaptationMode(wxDIALOG_ADAPTATION_MODE_ENABLED);
92  wxDialog::Create( parent, id, caption, pos, size, style );
93 
95  if (GetSizer())
96  {
97  GetSizer()->SetSizeHints(this);
98  }
99  Centre();
100  return true;
101 }
102 
103 /*!
104  * Member initialisation
105  */
106 
108 {
109  m_Grid = nullptr;
110  m_AecrPanel = nullptr;
111  m_GridPanel = nullptr;
112 }
113 
114 
116 {
117  CBulkMiscFeat* itemDialog1 = this;
118 
119  wxBoxSizer* itemBoxSizer2 = new wxBoxSizer(wxVERTICAL);
120  itemDialog1->SetSizer(itemBoxSizer2);
121 
122  wxBoxSizer* itemBoxSizer3 = new wxBoxSizer(wxHORIZONTAL);
123  itemBoxSizer2->Add(itemBoxSizer3, 0, wxALIGN_CENTER_HORIZONTAL|wxALL, 5);
124 
125  wxArrayString itemChoiceStrings, itemChoiceStringsWritable;
126 
127  string error_msg = "No Misc features were found";
128  if (m_FeatHandles.empty()) {
129  wxMessageBox(ToWxString(error_msg), wxT("Error"), wxOK | wxICON_ERROR);
130  NCBI_THROW( CException, eUnknown, error_msg );
131  }
132 
134  if (values_table->GetNum_rows() < 1) {
135  wxMessageBox(ToWxString(error_msg), wxT("Error"), wxOK | wxICON_ERROR);
136  NCBI_THROW( CException, eUnknown, error_msg );
137  }
138 
139  CRef<CSeq_table> choices = GetChoices(values_table);
140  int glyph_col = GetCollapsible();
141  m_GridPanel = new CSeqTableGridPanel(this, values_table, choices, glyph_col);
142  itemBoxSizer3->Add(m_GridPanel, 0, wxALIGN_TOP|wxALL, 5);
143 
145  CSeqTableGrid *gridAdapter = new CSeqTableGrid(values_table);
146  m_Grid->SetTable(gridAdapter, true);
147  m_Grid->AutoSizeColumns();
148 
149  int l_height = m_Grid->GetColLabelSize();
150  m_Grid->SetColLabelSize( 2 * l_height );
152 
153  int pos = 0;
154  for (auto&& it: values_table->GetColumns()) {
155  if (pos > 0) {
156  if (it->IsSetHeader() && it->GetHeader().IsSetTitle()) {
157  string title = it->GetHeader().GetTitle();
158  if (!title.empty()) {
159  itemChoiceStrings.Add(wxString(title));
160  if (!IsReadOnlyColumn(title))
161  itemChoiceStringsWritable.Add(wxString(title));
162  }
163  if (IsReadOnlyColumn(title))
164  m_GridPanel->MakeColumnReadOnly(pos - 1, true);
165  }
166  }
167  ++pos;
168  }
169 
170  if (glyph_col >= 0 && glyph_col+1 < m_Grid->GetNumberCols()) {
171  m_GridPanel->InitColumnCollapse(glyph_col+1);
172  }
173 
174  CStringConstraintSelect *itemStringConstraintPanel = new CStringConstraintSelect( itemDialog1, m_GridPanel, itemChoiceStrings, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 );
175  itemBoxSizer2->Add(itemStringConstraintPanel, 0, wxALIGN_CENTER_HORIZONTAL|wxALL|wxFIXED_MINSIZE, 0);
176 
177  m_AecrPanel = new CApplyEditconvertPanel( itemDialog1, m_GridPanel, itemChoiceStringsWritable, 0, true, wxID_ANY, wxDefaultPosition, wxSize(1046, 219));
178  itemBoxSizer2->Add(m_AecrPanel, 0, wxALIGN_CENTER_HORIZONTAL|wxALL|wxFIXED_MINSIZE, 1);
179 
180  wxBoxSizer* itemBoxSizer13 = new wxBoxSizer(wxHORIZONTAL);
181  itemBoxSizer2->Add(itemBoxSizer13, 0, wxALIGN_CENTER_HORIZONTAL|wxALL, 5);
182 
183  wxButton* itemButton14 = new wxButton( itemDialog1, wxID_OK, _("Accept"), wxDefaultPosition, wxDefaultSize, 0 );
184  itemBoxSizer13->Add(itemButton14, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
185 
186  wxButton* itemButton15 = new wxButton( itemDialog1, wxID_CANCEL, _("Cancel"), wxDefaultPosition, wxDefaultSize, 0 );
187  itemBoxSizer13->Add(itemButton15, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
188 }
189 
190 
192 {
195  id_col->SetHeader().SetTitle(kSequenceIdColLabel);
196 
197  CRef<CSeqTable_column> expand_col(new CSeqTable_column());
198  expand_col->SetHeader().SetTitle("");
199  expand_col->SetHeader().SetField_name("expand");
200  expand_col->SetData().SetString();
201 
202  CRef<CSeqTable_column> comment_col(new CSeqTable_column());
203  comment_col->SetHeader().SetTitle("comment");
204  comment_col->SetHeader().SetField_name("comment");
205  comment_col->SetData().SetString();
206 
208  loc_col->SetHeader().SetTitle("location");
209  loc_col->SetHeader().SetField_name("location");
210  loc_col->SetData().SetString();
211 
212  // bogus column to include last, otherwise deletion of the previous column will not work
213  CRef<CSeqTable_column> bogus_col(new CSeqTable_column());
214  bogus_col->SetHeader().SetTitle("");
215  bogus_col->SetHeader().SetField_name("");
216  bogus_col->SetData().SetString();
217 
219  table->SetColumns().push_back(id_col);
220  table->SetColumns().push_back(expand_col);
221  table->SetColumns().push_back(comment_col);
222  table->SetColumns().push_back(loc_col);
223 
226  partial_start_col->SetHeader().SetField_name(kPartialStart);
227 
230  partial_stop_col->SetHeader().SetField_name(kPartialStop);
231 
232  table->SetColumns().push_back(bogus_col);
233 
234  size_t row = 0;
235  for (vector<CSeq_feat_Handle>::iterator fi = m_FeatHandles.begin(); fi != m_FeatHandles.end() ; ++fi ) {
236  string loc,comment;
237 
238  const CSeq_feat &feat = *fi->GetOriginalSeq_feat();
239 
240  if (feat.IsSetComment())
241  comment = feat.GetComment();
242  if (feat.IsSetLocation())
243  feat.GetLocation().GetLabel(&loc);
244 
245  CRef<CSeq_id> id(new CSeq_id());
246  id->SetLocal().SetId(static_cast<CObject_id::TId>(row));
247  id_col->SetData().SetId().push_back(id);
248  expand_col->SetData().SetString().push_back("");
249  comment_col->SetData().SetString().push_back(comment);
250  loc_col->SetData().SetString().push_back(loc);
251 
252  AddValueToColumn(partial_start_col, partial_start_feat_col->GetFromFeat(feat), row);
253  AddValueToColumn(partial_stop_col, partial_stop_feat_col->GetFromFeat(feat), row);
254  bogus_col->SetData().SetString().push_back("");
255  row++;
256  }
257 
258  table->SetNum_rows(static_cast<CSeq_table::TNum_rows>(row));
259  return table;
260 }
261 
262 
264 {
265  CRef<CCmdComposite> cmd(new CCmdComposite("Bulk Mic Feature Edit"));
268 
269  m_Modified = false;
270  size_t row = 0;
271  for ( vector<CSeq_feat_Handle>::iterator fi = m_FeatHandles.begin(); fi != m_FeatHandles.end() ; ++fi ) {
272  const CSeq_feat &feat = *fi->GetOriginalSeq_feat();
273  CRef<CSeq_feat> new_feat(new CSeq_feat());
274  new_feat->Assign(feat);
275 
276  string loc,comment;
277  bool modified = false;
278  if (feat.IsSetComment())
279  comment = feat.GetComment();
280  if (feat.IsSetLocation())
281  feat.GetLocation().GetLabel(&loc);
282 
283  string new_comment;
284  try {
285  if (row < values_table->GetColumn("comment").GetData().GetString().size())
286  new_comment = values_table->GetColumn("comment").GetData().GetString()[row];
287  } catch(const CSeqTableException&) {}
288 
289  if (new_comment != comment) {
290  if (new_comment.empty())
291  new_feat->ResetComment();
292  else
293  new_feat->SetComment() = new_comment;
294  modified = true;
295  }
296 
297  string partial_start_val = partial_start_feat_col->GetFromFeat(feat);
298  string new_partial_start_val;
299  try {
300  if (row < values_table->GetColumn(kPartialStart).GetData().GetString().size())
301  new_partial_start_val = values_table->GetColumn(kPartialStart).GetData().GetString()[row];
302  } catch(const CSeqTableException&) {}
303 
304  if (new_partial_start_val != partial_start_val) {
305  if (new_partial_start_val.empty())
306  partial_start_feat_col->ClearInFeature(*new_feat);
307  else
308  partial_start_feat_col->AddToFeature(*new_feat, new_partial_start_val, edit::eExistingText_replace_old);
309  modified = true;
310  }
311 
312  string partial_stop_val = partial_stop_feat_col->GetFromFeat(feat);
313  string new_partial_stop_val;
314  try {
315  if (row < values_table->GetColumn(kPartialStop).GetData().GetString().size())
316  new_partial_stop_val = values_table->GetColumn(kPartialStop).GetData().GetString()[row];
317  } catch(const CSeqTableException&) {}
318 
319  if (new_partial_stop_val != partial_stop_val) {
320  if (new_partial_stop_val.empty())
321  partial_stop_feat_col->ClearInFeature(*new_feat);
322  else
323  partial_stop_feat_col->AddToFeature(*new_feat, new_partial_stop_val, edit::eExistingText_replace_old);
324  modified = true;
325  }
326 
327  if (modified)
328  cmd->AddCommand(*CRef<CCmdChangeSeq_feat>(new CCmdChangeSeq_feat(*fi,*new_feat)));
329  m_Modified |= modified;
330  row++;
331  }
332 
333  return cmd;
334 }
335 
336 
338 {
339  CRef<CSeq_table> values_table = m_GridPanel->GetValuesTable();
340  return GetCommandFromValuesTable(values_table);
341 }
342 
344 {
345  return "Invalid operation in Bulk Misc Feature Edit";
346 }
347 
348 
349 /*!
350  * Should we show tooltips?
351  */
352 
354 {
355  return true;
356 }
357 
358 /*!
359  * Get bitmap resources
360  */
361 
362 wxBitmap CBulkMiscFeat::GetBitmapResource( const wxString& name )
363 {
364  // Bitmap retrieval
365 ////@begin CBulkGene bitmap retrieval
366  wxUnusedVar(name);
367  return wxNullBitmap;
368 ////@end CBulkGene bitmap retrieval
369 }
370 
371 /*!
372  * Get icon resources
373  */
374 
375 wxIcon CBulkMiscFeat::GetIconResource( const wxString& name )
376 {
377  // Icon retrieval
378 ////@begin CBulkGene icon retrieval
379  wxUnusedVar(name);
380  return wxNullIcon;
381 ////@end CBulkGene icon retrieval
382 }
383 
384 /*!
385  * wxEVT_COMMAND_BUTTON_CLICKED event handler for ID_BUTTON
386  */
387 
388 void CBulkMiscFeat::OnClickOk( wxCommandEvent& event )
389 {
390  event.Skip();
391 }
392 
393 /*!
394  * wxEVT_COMMAND_BUTTON_CLICKED event handler for ID_BUTTON1
395  */
396 
397 void CBulkMiscFeat::OnClickCancel( wxCommandEvent& event )
398 {
399  bool modified = m_GridPanel->GetModified() | m_AecrPanel->GetModified();
400  if (modified) {
401  wxMessageDialog dlg(this,_("Discard modifications?"), _("Attention"),wxOK|wxCANCEL|wxCENTRE);
402  if (dlg.ShowModal() == wxID_OK) {
403  event.Skip();
404  }
405  }
406  else
407  event.Skip();
408 }
409 
411 {
412  objects.clear();
413  const CObject* obj = nullptr;
414 
415  if (row < m_FeatHandles.size()) {
416  if (m_FeatHandles[row].GetOriginalSeq_feat()->IsSetLocation()) {
417  bsh = m_FeatHandles[row].GetScope().GetBioseqHandle(m_FeatHandles[row].GetOriginalSeq_feat()->GetLocation());
418  if (bsh) {
419  if (m_SeqSubmit)
420  objects.push_back(SConstScopedObject(m_SeqSubmit,&bsh.GetScope()));
421  else
423  obj = bsh.GetBioseqCore().GetPointer();
424  }
425  }
426  }
427  return obj;
428 }
429 
430 
USING_SCOPE(objects)
CBioseq_Handle –.
bool IsReadOnlyColumn(string column_name)
bool Create(wxWindow *parent, wxWindowID id=wxID_ANY, const wxString &caption=_("Misc Feature Editing"), const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxDefaultSize, long style=wxCAPTION|wxRESIZE_BORDER|wxSYSTEM_MENU|wxCLOSE_BOX|wxTAB_TRAVERSAL)
Creation.
CRef< CCmdComposite > GetCommand()
wxBitmap GetBitmapResource(const wxString &name)
CRef< CCmdComposite > GetCommandFromValuesTable(CRef< objects::CSeq_table >)
void CreateControls()
Creates the controls and sizers.
vector< CSeq_feat_Handle > m_FeatHandles
CSeqTableGridPanel * m_GridPanel
CRef< objects::CSeq_table > GetValuesTableFromSeqEntry()
void OnClickCancel(wxCommandEvent &event)
CBulkMiscFeat()
Constructors.
virtual const CObject * RowToScopedObjects(int row, TConstScopedObjects &objects, CBioseq_Handle &bsh)
CRef< objects::CSeq_table > GetChoices(CRef< objects::CSeq_table > values_table)
void Init()
Initialises member variables.
CApplyEditconvertPanel * m_AecrPanel
static bool ShowToolTips()
Should we show tooltips?
void OnClickOk(wxCommandEvent &event)
wxIcon GetIconResource(const wxString &name)
Retrieves icon resources.
CFeat_CI –.
Definition: feat_ci.hpp:64
static CRef< CFeatureSeqTableColumnBase > Create(const string &sTitle, objects::CSeqFeatData::ESubtype subtype=objects::CSeqFeatData::eSubtype_any)
virtual void ClearInFeature(objects::CSeq_feat &in_out_feat)
virtual string GetFromFeat(const objects::CSeq_feat &in_out_feat)
virtual bool AddToFeature(objects::CSeq_feat &in_out_feat, const string &newValue, objects::edit::EExistingText existing_text)
CObject –.
Definition: ncbiobj.hpp:180
CConstRef< objects::CSeq_submit > m_SeqSubmit
Seq-loc and seq-align mapper exceptions.
void MakeColumnReadOnly(int pos, bool val=true)
wxGrid * GetGrid(void)
void InitColumnCollapse(int col)
CRef< objects::CSeq_table > GetValuesTable()
CSeq_entry_Handle –.
namespace ncbi::objects::
Definition: Seq_feat.hpp:58
const CSeqTable_column & GetColumn(CTempString column_name) const
Definition: Seq_table.cpp:65
IWorkbench is the central interface in the application framework.
Definition: workbench.hpp:113
#define _(proto)
Definition: ct_nlmzip_i.h:78
#define wxFIXED_MINSIZE
const string kPartialStart
const string kPartialStop
const char * kSequenceIdColLabel
static CS_COMMAND * cmd
Definition: ct_dynamic.c:26
static void Init(void)
Definition: cursor6.c:76
#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
vector< SConstScopedObject > TConstScopedObjects
Definition: objects.hpp:65
virtual void Assign(const CSerialObject &source, ESerialRecursionMode how=eRecursive)
Set object to copy of another one.
void GetLabel(string *label) const
Appends a label suitable for display (e.g., error messages) label must point to an existing string ob...
Definition: Seq_loc.cpp:3467
TBioseqCore GetBioseqCore(void) const
Get bioseq core structure.
CConstRef< CSeq_entry > GetCompleteSeq_entry(void) const
Complete and get const reference to the seq-entry.
CScope & GetScope(void) const
Get scope this handle belongs to.
CSeq_entry_Handle GetTopLevelEntry(void) const
Get top level Seq-entry handle.
TObjectType * GetPointer(void) const THROWS_NONE
Get pointer,.
Definition: ncbiobj.hpp:1684
#define END_NCBI_SCOPE
End previously defined NCBI scope.
Definition: ncbistl.hpp:103
#define BEGIN_NCBI_SCOPE
Define ncbi namespace.
Definition: ncbistl.hpp:100
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.
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
const TString & GetString(void) const
Get the variant data.
const TData & GetData(void) const
Get the Data member data.
bool IsSetComment(void) const
Check if a value has been assigned to Comment data member.
Definition: Seq_feat_.hpp:1037
void SetComment(const TComment &value)
Assign a value to Comment data member.
Definition: Seq_feat_.hpp:1058
const TLocation & GetLocation(void) const
Get the Location member data.
Definition: Seq_feat_.hpp:1117
void ResetComment(void)
Reset Comment data member.
Definition: Seq_feat_.cpp:99
const TComment & GetComment(void) const
Get the Comment member data.
Definition: Seq_feat_.hpp:1049
bool IsSetLocation(void) const
feature made from Check if a value has been assigned to Location data member.
Definition: Seq_feat_.hpp:1105
<!DOCTYPE HTML >< html > n< header > n< title > PubSeq Gateway Help Page</title > n< style > n table
END_EVENT_TABLE()
#define wxT(x)
Definition: muParser.cpp:41
const struct ncbi::grid::netcache::search::fields::SIZE size
#define fi
static static static wxID_ANY
CRef< CSeqTable_column > AddStringColumnToTable(CRef< CSeq_table > table, string label)
void AddValueToColumn(CRef< CSeqTable_column > column, string value, size_t row, edit::EExistingText existing_text=edit::eExistingText_replace_old)
#define row(bind, expected)
Definition: string_bind.c:73
@ eExistingText_replace_old
SAnnotSelector –.
wxString ToWxString(const string &s)
Definition: wx_utils.hpp:173
Modified on Mon Apr 22 04:05:36 2024 by modify_doxy.py rev. 669887