1 #include "creaImageIOWxDescriptorPanel.h"
2 #include <creaImageIOSystem.h>
4 #include <gdcmGlobal.h>
5 #include <gdcmDictSet.h>
7 #include <boost/algorithm/string.hpp>
9 #include <boost/algorithm/string.hpp>
15 WxDescriptorPanel::WxDescriptorPanel(wxWindow *parent, const std::string path)
16 : wxDialog(parent, -1,_T("Descriptor Creation"), wxDefaultPosition, wxSize(550,550)) , m_path(path)
20 GimmickDebugMessage(1,"WxDescriptorPanel::WxDescriptorPanel"
24 ownatt["FullFileName"] = "Full_File_Name";
25 ownatt["FullFileDirectory"] = "Full_File_Directory";
29 wxButton *NewDescriptor = new wxButton(this, -1,_T("Create a new descriptor"), wxPoint(10,7) );
30 Connect( NewDescriptor->GetId(), wxEVT_COMMAND_BUTTON_CLICKED , (wxObjectEventFunction) &WxDescriptorPanel::OnNew );
32 wxButton *LoadDescriptor = new wxButton(this, -1,_T("Load a descriptor"), wxPoint(150,7) );
33 Connect( LoadDescriptor->GetId(), wxEVT_COMMAND_BUTTON_CLICKED , (wxObjectEventFunction) &WxDescriptorPanel::OnLoad );
35 wxStaticLine *line1 = new wxStaticLine(this, -1, wxPoint(5,40), wxSize(540,2));
38 wxStaticText * LevelText=new wxStaticText(this,-1,_T(" Level: "), wxPoint(5,50));
39 LevelCtrl=new wxTextCtrl(this, ID_GR_CTRL,_T("patient"), wxPoint(50,50), wxSize(50,25));
40 wxButton *addLevel = new wxButton(this, ID_LEVEL_ADD,_T("add a level"), wxPoint(150,50) );
41 Connect( addLevel->GetId(), wxEVT_COMMAND_BUTTON_CLICKED , (wxObjectEventFunction) &WxDescriptorPanel::OnAddLevel );
43 wxStaticLine *line2 = new wxStaticLine(this, -1, wxPoint(5,75), wxSize(540,2));
47 wxStaticText * GR=new wxStaticText(this,-1,_T(" DICOM Group: "), wxPoint(5,110));
48 GRCtrl=new wxTextCtrl(this, ID_GR_CTRL,_T("0x0010"), wxPoint(82,110), wxSize(50,25));
49 Connect( GRCtrl->GetId(), wxEVT_COMMAND_TEXT_UPDATED , (wxObjectEventFunction) &WxDescriptorPanel::OnDicomAttribute );
51 wxStaticText * EL=new wxStaticText(this,-1,_T(" DICOM Element: "), wxPoint(140,110));
52 ELCtrl=new wxTextCtrl(this, ID_EL_CTRL,_T("0x0010"), wxPoint(230,110), wxSize(50,25));
53 Connect( ELCtrl->GetId(), wxEVT_COMMAND_TEXT_UPDATED , (wxObjectEventFunction) &WxDescriptorPanel::OnDicomAttribute );
57 choices[0] = _T("Unknow Attribute");
58 std::map<std::string, std::string>::iterator it_att =ownatt.begin();
59 for(int i = 1; it_att != ownatt.end(); it_att++, i++)
61 choices[i] = crea::std2wx(it_att->second);
65 AttributeCombo = new wxComboBox(this, ID_ATTRIBUTE_CTRL,_T(""),wxPoint(300,110), wxSize(120,25),3,choices, wxCB_READONLY);
66 AttributeCombo->SetSelection(0);
69 wxButton *addAttribute = new wxButton(this, ID_ATTRIBUTE_ADD,_T("add an attribute"), wxPoint(440,110) );
70 Connect( addAttribute->GetId(), wxEVT_COMMAND_BUTTON_CLICKED , (wxObjectEventFunction) &WxDescriptorPanel::OnAddAttribute );
72 wxStaticLine *line3 = new wxStaticLine(this, -1, wxPoint(5,140), wxSize(540,2));
76 ResultCtrl=new wxTextCtrl(this, ID_EL_CTRL,_T(""), wxPoint(5,150), wxSize(250,310), wxTE_READONLY| wxMac | wxTE_MULTILINE | wxTE_RICH );
77 wxButton *RemoveCtrl = new wxButton(this, ID_REMOVE_ADD,_T("Remove an entry"), wxPoint(280,200) );
78 Connect( RemoveCtrl->GetId(), wxEVT_COMMAND_BUTTON_CLICKED , (wxObjectEventFunction) &WxDescriptorPanel::OnRemove );
80 wxStaticLine *line4 = new wxStaticLine(this, -1, wxPoint(5,470), wxSize(540,2));
82 wxButton *Ok = new wxButton(this, -1,_T("OK"), wxPoint(10,480) );
83 Connect( Ok->GetId(), wxEVT_COMMAND_BUTTON_CLICKED , (wxObjectEventFunction) &WxDescriptorPanel::OnOK );
85 wxButton *Apply = new wxButton(this, -1,_T("APPLY"), wxPoint(150,480) );
86 Connect( Apply->GetId(), wxEVT_COMMAND_BUTTON_CLICKED , (wxObjectEventFunction) &WxDescriptorPanel::OnApply );
88 wxButton *Cancel = new wxButton(this, wxID_CANCEL,_T("CANCEL"), wxPoint(250,480) );
89 // Connect( Cancel->GetId(), wxEVT_COMMAND_BUTTON_CLICKED , (wxCloseEvent) &wxWindow::Close );
96 WxDescriptorPanel::~WxDescriptorPanel()
98 GimmickDebugMessage(1,"WxCustomizeConfigPanel::~WxCustomizeConfigPanel"
102 //////////////////////////////////////////////////////////
103 // Add an attribute //
104 // @param event : Wxevent //
106 //////////////////////////////////////////////////
107 void WxDescriptorPanel::OnAddAttribute(wxCommandEvent& event)
110 std::string name_att;
111 if (AttributeCombo->GetSelection() == 0)
113 name_att = "D" + crea::wx2std(GRCtrl->GetValue()) + "_" + crea::wx2std(ELCtrl->GetValue());
117 wxString wd = AttributeCombo->GetValue();
118 std::string st = crea::wx2std(wd);
119 name_att = OwnAttribute(st);
121 onAddAttribute(crea::wx2std(AttributeCombo->GetValue()), name_att);
123 //////////////////////////////////////////////////////////
124 // add an attribute //
125 // @param att : attribute //
126 // @param name_att : 's name //
127 // @param level : level to add the attribute //
129 //////////////////////////////////////////////////
130 void WxDescriptorPanel::onAddAttribute( const std::string &att, const std::string &name_att,std::string level )
134 wxMessageBox(_T("Need a level first!"),crea::std2wx("WARNING"),wxOK,this);
140 // Find Name of level
146 if (!addAtribute(level, name_att))
148 wxMessageBox(_T("Attribute already used in this level"),crea::std2wx("WARNING"),wxOK,this);
152 ResultCtrl->SetInsertionPoint(InsertPt);
153 for (int i = 1; i<=lv;i++)
155 ResultCtrl->WriteText(_T(" "));
157 ResultCtrl->WriteText(_T("| - "));
158 ResultCtrl->WriteText(crea::std2wx(att));
159 wxTextAttr ResultAttr(ResultCtrl->GetDefaultStyle());
160 ResultAttr.SetTextColour(*wxWHITE);
161 ResultCtrl->SetDefaultStyle(ResultAttr);
162 std::string text = " ";
163 ResultCtrl->WriteText(crea::std2wx(" " + name_att));
164 ResultAttr.SetTextColour(*wxBLACK);
165 ResultCtrl->SetDefaultStyle(ResultAttr);
166 ResultCtrl->WriteText(_T("\n"));
168 InsertPt = ResultCtrl->GetInsertionPoint();
173 //////////////////////////////////////////////////////////
175 // @param event : Wxevent //
177 //////////////////////////////////////////////////
178 void WxDescriptorPanel::OnAddLevel(wxCommandEvent& event)
180 if( !LevelCtrl->GetValue().IsEmpty() )
182 onAddLevel(crea::wx2std(LevelCtrl->GetValue()));
186 //////////////////////////////////////////////////////////
188 // @param level : level's name //
190 //////////////////////////////////////////////////
191 void WxDescriptorPanel::onAddLevel(const std::string &level)
195 wxMessageBox(_T("Level already used"),crea::std2wx(("WARNING")),wxOK,this);
200 ResultCtrl->SetInsertionPoint(InsertPt);
201 for (int i = 1; i<lv;i++)
203 ResultCtrl->WriteText(_T(" "));
206 { ResultCtrl->WriteText(_T("| \n"));
207 for (int i = 1; i<lv;i++)
209 ResultCtrl->WriteText(_T(" "));
211 ResultCtrl->WriteText(_T("|_"));
214 wxTextAttr ResultAttr(ResultCtrl->GetDefaultStyle());
215 ResultAttr.SetTextColour(*wxRED);
216 ResultCtrl->SetDefaultStyle(ResultAttr);
217 ResultCtrl->WriteText(crea::std2wx(level));
218 ResultAttr.SetTextColour(*wxBLACK);
219 ResultCtrl->SetDefaultStyle(ResultAttr);
220 ResultCtrl->WriteText(_T("\n"));
221 InsertPt = ResultCtrl->GetInsertionPoint();
225 //////////////////////////////////////////////////////////
226 // Find a DICOM attribute from group and element values //
227 // @param event : Wxevent //
229 //////////////////////////////////////////////////
230 void WxDescriptorPanel::OnDicomAttribute(wxCommandEvent& event)
233 if(!GRCtrl->GetValue().IsEmpty() && !ELCtrl->GetValue().IsEmpty()
234 && GRCtrl->GetValue().Len() == 6 && ELCtrl->GetValue().Len() == 6 && AttributeCombo->GetSelection() == 0)
237 std::string gr = crea::wx2std(GRCtrl->GetValue());
238 std::string el = crea::wx2std(ELCtrl->GetValue());
239 std::stringstream val;
241 unsigned short group;
242 unsigned short element;
243 val << std::dec << gr ;
244 val >> std::hex >> group;
246 val << std::dec << el ;
247 val >> std::hex >> element;
248 #if defined(USE_GDCM)
249 // Retrieve the name from gdcm dict
250 GDCM_NAME_SPACE::DictEntry* entry = GDCM_NAME_SPACE::Global::GetDicts()->GetDefaultPubDict()->GetEntry(group, element);
251 // AttributeCombo->Clear();
254 AttributeCombo->Delete(0);
255 AttributeCombo->Insert(crea::std2wx(entry->GetName()), 0);
259 AttributeCombo->Delete(0);
260 AttributeCombo->Insert(_T("Unknown Attribute"),0);
263 AttributeCombo->SetSelection(0);
270 //////////////////////////////////////////////////////////
271 // determine values for own attributes //
272 // @param name : attribute's name //
273 // @param key : indicates key map or not //
275 //////////////////////////////////////////////////
276 std::string WxDescriptorPanel::OwnAttribute(const std::string name)
280 std::map<std::string, std::string>::iterator it_att = ownatt.begin();
281 for(; it_att != ownatt.end(); it_att++)
283 if(it_att->second == name)
285 result = it_att->first.c_str();
292 //////////////////////////////////////////////////////////
293 // Find a level in function of position in Return Ctrl //
296 //////////////////////////////////////////////////
297 std::string WxDescriptorPanel::findLevel()
302 ResultCtrl->PositionToXY( ResultCtrl->GetInsertionPoint(),&column, &line);
303 std::string tx(crea::wx2std(ResultCtrl->GetRange(0, ResultCtrl->XYToPosition(0,line+1))).c_str());
304 std::string::size_type level_pos_start = tx.rfind("|_");
305 if(level_pos_start == -1)
311 level_pos_start += 2;
314 std::string::size_type level_pos_end = tx.find_first_of("\n",level_pos_start);
315 return tx.substr(level_pos_start,level_pos_end - level_pos_start);
318 //////////////////////////////////////////////////////
320 // @param event : Wxevent //
322 //////////////////////////////////////////////////
323 void WxDescriptorPanel::OnRemove(wxCommandEvent& event)
330 pos_start = ResultCtrl->GetInsertionPoint();
331 ResultCtrl->PositionToXY( pos_start,&column, &line);
334 std::string name("root");
341 wxString text = ResultCtrl->GetLineText(line);
342 if ( text.Find(_T("|_")) == -1)
344 std::string level = findLevel();
345 // find GR and EL values to remove
346 std::string tx = crea::wx2std(text);
347 std::string::size_type EL_start_pos = tx.find_last_of(" ");
348 RemoveAttribute(level, tx.substr(EL_start_pos+1,tx.size() - EL_start_pos));
349 ResultCtrl->Remove( ResultCtrl->XYToPosition(0,line), ResultCtrl->XYToPosition(0,line+1));
353 RemoveLevel(crea::wx2std(text.AfterFirst('_')));
354 lv = text.Find(_T("|"))/3;
355 pos_start= ResultCtrl->XYToPosition(0,line-1);
356 ResultCtrl->SetInsertionPointEnd();
357 pos_end = ResultCtrl->GetInsertionPoint();
358 ResultCtrl->Remove(pos_start, pos_end);
363 //////////////////////////////////////////////
364 // create a descriptor structure //
365 // @param name : level's name to add //
366 // @return : boolean result //
367 //////////////////////////////////////////////////
368 void WxDescriptorPanel::CreateDescriptor(int type)
370 if(type == 0) // First initialization
373 outDscp += "<level>";
377 outDscp += "O Name Name 4";
384 outDscp += "O NumberOfChildren ";
385 outDscp += crea::wx2std(LevelCtrl->GetValue());
389 outDscp += "<level>";
391 outDscp += crea::wx2std(LevelCtrl->GetValue());
399 outDscp += crea::wx2std(GRCtrl->GetValue());
401 outDscp += crea::wx2std(ELCtrl->GetValue());
411 //////////////////////////////////////////////////////
413 // @param name : level's name to add //
414 // @return : boolean result //
415 //////////////////////////////////////////////////
416 bool WxDescriptorPanel::addLevel(const std::string &name)
419 std::map<std::string, std::vector <std::string> >::iterator it_tree = DscpTree.begin();
420 for (;it_tree != DscpTree.end(); it_tree++)
422 if(it_tree->first == name)
431 std::vector <std::string> branch;
432 DscpTree[name] = branch;
437 //////////////////////////////////////////////////////
439 // @param name : level's name to remove //
440 // @return : boolean result //
441 //////////////////////////////////////////////////
442 bool WxDescriptorPanel::RemoveLevel(const std::string &name)
444 bool bresult = false;
445 std::map<int, std::string>::iterator it_list= lvlist.begin();
446 for(; it_list != lvlist.end(); it_list++)
448 if(it_list->second == name)
453 std::map<int, std::string>::iterator it_list2 = it_list;
454 for(;it_list != lvlist.end(); it_list++)
456 std::map<std::string, std::vector <std::string> >::iterator it_tree = DscpTree.begin();
457 for (;it_tree != DscpTree.end(); it_tree++)
459 if(it_tree->first == name)
461 DscpTree.erase(it_tree);
466 lvlist.erase(it_list2, lvlist.end());
471 //////////////////////////////////////////////////////
472 // add an attribute in a level //
473 // @param level : level's name to add attribute //
474 // @param name : attribute's name //
475 // @return : boolean result //
476 //////////////////////////////////////////////////
477 bool WxDescriptorPanel::addAtribute(const std::string &level, const std::string &name)
480 std::map<std::string, std::vector <std::string> >::iterator it_tree = DscpTree.begin();
481 for (;it_tree != DscpTree.end(); it_tree++)
483 if (it_tree->first.c_str() == level)
485 std::vector<std::string>::iterator it_branch = it_tree->second.begin();
486 for(;it_branch != it_tree->second.end(); it_branch++)
488 if(it_branch->c_str() == name)
495 it_tree->second.push_back(name);
503 //////////////////////////////////////////////////////
504 // remove an attribute from a level //
505 // @param level : level's name to remove attribute //
506 // @param name : attribute's name //
507 // @return : boolean result //
508 //////////////////////////////////////////////////
509 bool WxDescriptorPanel::RemoveAttribute(const std::string &level, const std::string &name)
511 bool bresult = false;
512 std::map<std::string, std::vector <std::string> >::iterator it_tree = DscpTree.begin();
513 for (;it_tree != DscpTree.end(); it_tree++)
515 if(it_tree->first == level)
517 std::vector<std::string>::iterator it_branch = it_tree->second.begin();
518 cout << it_tree->second.size();
519 for(;it_branch != it_tree->second.end(); it_branch++)
521 if(it_branch->c_str() == name)
524 it_tree->second.erase(it_branch);
533 //////////////////////////////////////////////////
534 // create a new descriptor //
535 // @param event : WxEvent //
537 //////////////////////////////////////////////////
538 void WxDescriptorPanel::OnNew(wxCommandEvent &Event)
540 LevelCtrl->SetValue(_T("patient"));
546 //////////////////////////////////////////////////
547 // Load a descriptor file //
548 // @param event : WxEvent //
550 //////////////////////////////////////////////////
551 void WxDescriptorPanel::OnLoad(wxCommandEvent &Event)
553 long style = wxOPEN | wxFILE_MUST_EXIST;
554 LevelCtrl->SetValue(_T("patient"));
559 std::string wc("*.dscp");
560 wxFileDialog* FD = new wxFileDialog( 0,
562 crea::std2wx(m_path),
567 if (FD->ShowModal()==wxID_OK)
569 loadDescriptor(crea::wx2std(FD->GetPath()).c_str());
574 //////////////////////////////////////////////////
575 // Save a descriptor //
576 // @param event : WxEvent //
578 //////////////////////////////////////////////////
579 void WxDescriptorPanel::OnOK(wxCommandEvent &Event)
585 /////////////////////////////////////////////////////
586 // Save a descriptor and apply it (create a new DB//
587 // @param event : WxEvent //
589 /////////////////////////////////////////////////////
590 void WxDescriptorPanel::OnApply(wxCommandEvent &Event)
592 m_DscpFile = saveDescriptor();
594 SetReturnCode(ID_DSCP_APPLY);
597 const std::string WxDescriptorPanel::saveDescriptor()
599 std::string file = "";
601 std::string wc("*.dscp");
602 wxFileDialog* FD = new wxFileDialog( 0,
611 if (FD->ShowModal()==wxID_OK)
613 createDescriptorFile();
614 file = crea::wx2std(FD->GetPath()).c_str();
615 std::ofstream ofs(file.c_str());
623 ///////////////////////////////////////////////////////
625 // @param event : WxEvent //
627 ///////////////////////////////////////////////////////
629 void WxDescriptorPanel::OnCancel(wxCommandEvent& event)
633 ///////////////////////////////////////////////////////
634 // create a descriptor file //
637 ///////////////////////////////////////////////////////
638 void WxDescriptorPanel::createDescriptorFile()
642 outDscp += "<level>";
646 outDscp += "O Name Name 4";
648 std::map<std::string, std::vector <std::string> >::iterator it_tree = DscpTree.begin();
649 std::map<int, std::string >::iterator it_lv_nb = lvlist.begin();
650 std::map<int, std::string >::iterator it_lv = lvlist.begin();
652 for (;it_lv != lvlist.end(); it_lv++)
656 outDscp += it_lv->second.c_str();
658 if(it_lv_nb != lvlist.end())
660 outDscp += "O NumberOfChildren ";
661 outDscp += it_lv_nb->second.c_str();
666 std::vector<std::string>::iterator it_branch = DscpTree[it_lv->second.c_str()].begin();
667 for(;it_branch != DscpTree[it_lv->second.c_str()].end(); it_branch++)
669 std::string att = it_branch->c_str();
670 if(att[0] == 'D' && att[7] == '_' && att.size() == 14)
673 outDscp += att.substr(1,6) + " "; // GR
674 outDscp += att.substr(8,6) + " ";// EL
681 outDscp += it_branch->c_str();
683 outDscp += ownatt[att];
694 ///////////////////////////////////////////////////////
695 // load a descriptor //
696 // @param i_name : file name to load //
698 /////////////////////////////////////////////////////
699 void WxDescriptorPanel::loadDescriptor(const std::string i_name)
701 std::ifstream i_file(i_name.c_str());
702 std::stringstream buffer;
703 buffer << i_file.rdbuf();
711 while(std::getline(buffer, line))
714 { //increment levels.
720 // For each level, a name to describe it
730 // split line to find all tags
731 std::vector<std::string> descriptors;
732 std::string separator = " ";
733 std::string::size_type last_pos = line.find_first_not_of(separator);
734 //find first separator
735 std::string::size_type pos = line.find_first_of(separator, last_pos);
736 while(std::string::npos != pos || std::string::npos != last_pos)
738 descriptors.push_back(line.substr(last_pos, pos - last_pos));
739 last_pos = line.find_first_not_of(separator, pos);
740 pos = line.find_first_of(separator, last_pos);
743 // By default, the last tag is at zero and not recorded but if take in count
744 unsigned int flag = 0;
745 if(descriptors.size() == 4)
747 std::stringstream val;
748 val << std::dec << descriptors[3];
752 // if Dicom tag, use "group" and "element" descriptor
753 if(descriptors[0] == "D")
754 { std::stringstream val, val2;
755 unsigned short group;
756 unsigned short element;
757 val << std::dec << descriptors[1] ;
758 val >> std::hex >> group;
759 val2 << std::dec << descriptors[2];
760 val2 >> std::hex >> element;
761 std::string compose = "D";
762 compose += descriptors[1];
764 compose += descriptors[2];
765 #if defined(USE_GDCM)
766 GDCM_NAME_SPACE::DictEntry* entry = GDCM_NAME_SPACE::Global::GetDicts()->GetDefaultPubDict()->GetEntry(group, element);
769 onAddAttribute( entry->GetName(),compose, level);
773 else if(descriptors[0].find("#") != -1)
775 // commented line continue to next line
777 else // "O" means if user's own tag.
779 boost::algorithm::replace_all(descriptors[2],"_"," ");
780 if(ilevel>0 && descriptors[1] != "NumberOfChildren" )
782 onAddAttribute( descriptors[2].c_str(),descriptors[1].c_str(), level);
789 //======================================================================
791 //======================================================================
793 } // EO namespace creaImageIO