1 #include "creaImageIOWxDescriptorPanel.h"
2 #include <creaImageIOSystem.h>
3 #include <gdcmGlobal.h>
4 #include <gdcmDictSet.h>
5 #include <boost/algorithm/string.hpp>
7 #include <boost/algorithm/string.hpp>
13 WxDescriptorPanel::WxDescriptorPanel(wxWindow *parent, const std::string path)
14 : wxDialog(parent, -1,_T("Descriptor Creation"), wxDefaultPosition, wxSize(550,550)) , m_path(path)
18 GimmickDebugMessage(1,"WxDescriptorPanel::WxDescriptorPanel"
22 ownatt["FullFileName"] = "Full_File_Name";
23 ownatt["FullFileDirectory"] = "Full_File_Directory";
27 wxButton *NewDescriptor = new wxButton(this, -1,_T("Create a new descriptor"), wxPoint(10,7) );
28 Connect( NewDescriptor->GetId(), wxEVT_COMMAND_BUTTON_CLICKED , (wxObjectEventFunction) &WxDescriptorPanel::OnNew );
30 wxButton *LoadDescriptor = new wxButton(this, -1,_T("Load a descriptor"), wxPoint(150,7) );
31 Connect( LoadDescriptor->GetId(), wxEVT_COMMAND_BUTTON_CLICKED , (wxObjectEventFunction) &WxDescriptorPanel::OnLoad );
33 wxStaticLine *line1 = new wxStaticLine(this, -1, wxPoint(5,40), wxSize(540,2));
36 wxStaticText * LevelText=new wxStaticText(this,-1,_T(" Level: "), wxPoint(5,50));
37 LevelCtrl=new wxTextCtrl(this, ID_GR_CTRL,_T("patient"), wxPoint(50,50), wxSize(50,25));
38 wxButton *addLevel = new wxButton(this, ID_LEVEL_ADD,_T("add a level"), wxPoint(150,50) );
39 Connect( addLevel->GetId(), wxEVT_COMMAND_BUTTON_CLICKED , (wxObjectEventFunction) &WxDescriptorPanel::OnAddLevel );
41 wxStaticLine *line2 = new wxStaticLine(this, -1, wxPoint(5,75), wxSize(540,2));
45 wxStaticText * GR=new wxStaticText(this,-1,_T(" DICOM Group: "), wxPoint(5,110));
46 GRCtrl=new wxTextCtrl(this, ID_GR_CTRL,_T("0x0010"), wxPoint(82,110), wxSize(50,25));
47 Connect( GRCtrl->GetId(), wxEVT_COMMAND_TEXT_UPDATED , (wxObjectEventFunction) &WxDescriptorPanel::OnDicomAttribute );
49 wxStaticText * EL=new wxStaticText(this,-1,_T(" DICOM Element: "), wxPoint(140,110));
50 ELCtrl=new wxTextCtrl(this, ID_EL_CTRL,_T("0x0010"), wxPoint(230,110), wxSize(50,25));
51 Connect( ELCtrl->GetId(), wxEVT_COMMAND_TEXT_UPDATED , (wxObjectEventFunction) &WxDescriptorPanel::OnDicomAttribute );
55 choices[0] = _T("Unknow Attribute");
56 std::map<std::string, std::string>::iterator it_att =ownatt.begin();
57 for(int i = 1; it_att != ownatt.end(); it_att++, i++)
59 choices[i] = crea::std2wx(it_att->second);
63 AttributeCombo = new wxComboBox(this, ID_ATTRIBUTE_CTRL,_T(""),wxPoint(300,110), wxSize(120,25),3,choices, wxCB_READONLY);
64 AttributeCombo->SetSelection(0);
67 wxButton *addAttribute = new wxButton(this, ID_ATTRIBUTE_ADD,_T("add an attribute"), wxPoint(440,110) );
68 Connect( addAttribute->GetId(), wxEVT_COMMAND_BUTTON_CLICKED , (wxObjectEventFunction) &WxDescriptorPanel::OnAddAttribute );
70 wxStaticLine *line3 = new wxStaticLine(this, -1, wxPoint(5,140), wxSize(540,2));
74 ResultCtrl=new wxTextCtrl(this, ID_EL_CTRL,_T(""), wxPoint(5,150), wxSize(250,310), wxTE_READONLY| wxMac | wxTE_MULTILINE | wxTE_RICH );
75 wxButton *RemoveCtrl = new wxButton(this, ID_REMOVE_ADD,_T("Remove an entry"), wxPoint(280,200) );
76 Connect( RemoveCtrl->GetId(), wxEVT_COMMAND_BUTTON_CLICKED , (wxObjectEventFunction) &WxDescriptorPanel::OnRemove );
78 wxStaticLine *line4 = new wxStaticLine(this, -1, wxPoint(5,470), wxSize(540,2));
80 wxButton *Ok = new wxButton(this, -1,_T("OK"), wxPoint(10,480) );
81 Connect( Ok->GetId(), wxEVT_COMMAND_BUTTON_CLICKED , (wxObjectEventFunction) &WxDescriptorPanel::OnOK );
83 wxButton *Apply = new wxButton(this, -1,_T("APPLY"), wxPoint(150,480) );
84 Connect( Apply->GetId(), wxEVT_COMMAND_BUTTON_CLICKED , (wxObjectEventFunction) &WxDescriptorPanel::OnApply );
86 wxButton *Cancel = new wxButton(this, wxID_CANCEL,_T("CANCEL"), wxPoint(250,480) );
87 // Connect( Cancel->GetId(), wxEVT_COMMAND_BUTTON_CLICKED , (wxCloseEvent) &wxWindow::Close );
94 WxDescriptorPanel::~WxDescriptorPanel()
96 GimmickDebugMessage(1,"WxCustomizeConfigPanel::~WxCustomizeConfigPanel"
100 //////////////////////////////////////////////////////////
101 // Add an attribute //
102 // @param event : Wxevent //
104 //////////////////////////////////////////////////
105 void WxDescriptorPanel::OnAddAttribute(wxCommandEvent& event)
108 std::string name_att;
109 if (AttributeCombo->GetSelection() == 0)
111 name_att = "D" + crea::wx2std(GRCtrl->GetValue()) + "_" + crea::wx2std(ELCtrl->GetValue());
115 wxString wd = AttributeCombo->GetValue();
116 std::string st = crea::wx2std(wd);
117 name_att = OwnAttribute(st);
119 onAddAttribute(crea::wx2std(AttributeCombo->GetValue()), name_att);
121 //////////////////////////////////////////////////////////
122 // add an attribute //
123 // @param att : attribute //
124 // @param name_att : 's name //
125 // @param level : level to add the attribute //
127 //////////////////////////////////////////////////
128 void WxDescriptorPanel::onAddAttribute( const std::string &att, const std::string &name_att,std::string level )
132 wxMessageBox(_T("Need a level first!"),crea::std2wx("WARNING"),wxOK,this);
138 // Find Name of level
144 if (!addAtribute(level, name_att))
146 wxMessageBox(_T("Attribute already used in this level"),crea::std2wx("WARNING"),wxOK,this);
150 ResultCtrl->SetInsertionPoint(InsertPt);
151 for (int i = 1; i<=lv;i++)
153 ResultCtrl->WriteText(_T(" "));
155 ResultCtrl->WriteText(_T("| - "));
156 ResultCtrl->WriteText(crea::std2wx(att));
157 wxTextAttr ResultAttr(ResultCtrl->GetDefaultStyle());
158 ResultAttr.SetTextColour(*wxWHITE);
159 ResultCtrl->SetDefaultStyle(ResultAttr);
160 std::string text = " ";
161 ResultCtrl->WriteText(crea::std2wx(" " + name_att));
162 ResultAttr.SetTextColour(*wxBLACK);
163 ResultCtrl->SetDefaultStyle(ResultAttr);
164 ResultCtrl->WriteText(_T("\n"));
166 InsertPt = ResultCtrl->GetInsertionPoint();
171 //////////////////////////////////////////////////////////
173 // @param event : Wxevent //
175 //////////////////////////////////////////////////
176 void WxDescriptorPanel::OnAddLevel(wxCommandEvent& event)
178 if( !LevelCtrl->GetValue().IsEmpty() )
180 onAddLevel(crea::wx2std(LevelCtrl->GetValue()));
184 //////////////////////////////////////////////////////////
186 // @param level : level's name //
188 //////////////////////////////////////////////////
189 void WxDescriptorPanel::onAddLevel(const std::string &level)
193 wxMessageBox(_T("Level already used"),crea::std2wx(("WARNING")),wxOK,this);
198 ResultCtrl->SetInsertionPoint(InsertPt);
199 for (int i = 1; i<lv;i++)
201 ResultCtrl->WriteText(_T(" "));
204 { ResultCtrl->WriteText(_T("| \n"));
205 for (int i = 1; i<lv;i++)
207 ResultCtrl->WriteText(_T(" "));
209 ResultCtrl->WriteText(_T("|_"));
212 wxTextAttr ResultAttr(ResultCtrl->GetDefaultStyle());
213 ResultAttr.SetTextColour(*wxRED);
214 ResultCtrl->SetDefaultStyle(ResultAttr);
215 ResultCtrl->WriteText(crea::std2wx(level));
216 ResultAttr.SetTextColour(*wxBLACK);
217 ResultCtrl->SetDefaultStyle(ResultAttr);
218 ResultCtrl->WriteText(_T("\n"));
219 InsertPt = ResultCtrl->GetInsertionPoint();
223 //////////////////////////////////////////////////////////
224 // Find a DICOM attribute from group and element values //
225 // @param event : Wxevent //
227 //////////////////////////////////////////////////
228 void WxDescriptorPanel::OnDicomAttribute(wxCommandEvent& event)
231 if(!GRCtrl->GetValue().IsEmpty() && !ELCtrl->GetValue().IsEmpty()
232 && GRCtrl->GetValue().Len() == 6 && ELCtrl->GetValue().Len() == 6 && AttributeCombo->GetSelection() == 0)
235 std::string gr = crea::wx2std(GRCtrl->GetValue());
236 std::string el = crea::wx2std(ELCtrl->GetValue());
237 std::stringstream val;
239 unsigned short group;
240 unsigned short element;
241 val << std::dec << gr ;
242 val >> std::hex >> group;
244 val << std::dec << el ;
245 val >> std::hex >> element;
247 // Retrieve the name from gdcm dict
248 GDCM_NAME_SPACE::DictEntry* entry = GDCM_NAME_SPACE::Global::GetDicts()->GetDefaultPubDict()->GetEntry(group, element);
249 // AttributeCombo->Clear();
252 AttributeCombo->Delete(0);
253 AttributeCombo->Insert(crea::std2wx(entry->GetName()), 0);
257 AttributeCombo->Delete(0);
258 AttributeCombo->Insert(_T("Unknown Attribute"),0);
260 AttributeCombo->SetSelection(0);
267 //////////////////////////////////////////////////////////
268 // determine values for own attributes //
269 // @param name : attribute's name //
270 // @param key : indicates key map or not //
272 //////////////////////////////////////////////////
273 std::string WxDescriptorPanel::OwnAttribute(const std::string name)
277 std::map<std::string, std::string>::iterator it_att = ownatt.begin();
278 for(; it_att != ownatt.end(); it_att++)
280 if(it_att->second == name)
282 result = it_att->first.c_str();
289 //////////////////////////////////////////////////////////
290 // Find a level in function of position in Return Ctrl //
293 //////////////////////////////////////////////////
294 std::string WxDescriptorPanel::findLevel()
299 ResultCtrl->PositionToXY( ResultCtrl->GetInsertionPoint(),&column, &line);
300 std::string tx(crea::wx2std(ResultCtrl->GetRange(0, ResultCtrl->XYToPosition(0,line+1))).c_str());
301 std::string::size_type level_pos_start = tx.rfind("|_");
302 if(level_pos_start == -1)
308 level_pos_start += 2;
311 std::string::size_type level_pos_end = tx.find_first_of("\n",level_pos_start);
312 return tx.substr(level_pos_start,level_pos_end - level_pos_start);
315 //////////////////////////////////////////////////////
317 // @param event : Wxevent //
319 //////////////////////////////////////////////////
320 void WxDescriptorPanel::OnRemove(wxCommandEvent& event)
327 pos_start = ResultCtrl->GetInsertionPoint();
328 ResultCtrl->PositionToXY( pos_start,&column, &line);
331 std::string name("root");
338 wxString text = ResultCtrl->GetLineText(line);
339 if ( text.Find(_T("|_")) == -1)
341 std::string level = findLevel();
342 // find GR and EL values to remove
343 std::string tx = crea::wx2std(text);
344 std::string::size_type EL_start_pos = tx.find_last_of(" ");
345 RemoveAttribute(level, tx.substr(EL_start_pos+1,tx.size() - EL_start_pos));
346 ResultCtrl->Remove( ResultCtrl->XYToPosition(0,line), ResultCtrl->XYToPosition(0,line+1));
350 RemoveLevel(crea::wx2std(text.AfterFirst('_')));
351 lv = text.Find(_T("|"))/3;
352 pos_start= ResultCtrl->XYToPosition(0,line-1);
353 ResultCtrl->SetInsertionPointEnd();
354 pos_end = ResultCtrl->GetInsertionPoint();
355 ResultCtrl->Remove(pos_start, pos_end);
360 //////////////////////////////////////////////
361 // create a descriptor structure //
362 // @param name : level's name to add //
363 // @return : boolean result //
364 //////////////////////////////////////////////////
365 void WxDescriptorPanel::CreateDescriptor(int type)
367 if(type == 0) // First initialization
370 outDscp += "<level>";
374 outDscp += "O Name Name 4";
381 outDscp += "O NumberOfChildren ";
382 outDscp += crea::wx2std(LevelCtrl->GetValue());
386 outDscp += "<level>";
388 outDscp += crea::wx2std(LevelCtrl->GetValue());
396 outDscp += crea::wx2std(GRCtrl->GetValue());
398 outDscp += crea::wx2std(ELCtrl->GetValue());
408 //////////////////////////////////////////////////////
410 // @param name : level's name to add //
411 // @return : boolean result //
412 //////////////////////////////////////////////////
413 bool WxDescriptorPanel::addLevel(const std::string &name)
416 std::map<std::string, std::vector <std::string> >::iterator it_tree = DscpTree.begin();
417 for (;it_tree != DscpTree.end(); it_tree++)
419 if(it_tree->first == name)
428 std::vector <std::string> branch;
429 DscpTree[name] = branch;
434 //////////////////////////////////////////////////////
436 // @param name : level's name to remove //
437 // @return : boolean result //
438 //////////////////////////////////////////////////
439 bool WxDescriptorPanel::RemoveLevel(const std::string &name)
441 bool bresult = false;
442 std::map<int, std::string>::iterator it_list= lvlist.begin();
443 for(; it_list != lvlist.end(); it_list++)
445 if(it_list->second == name)
450 std::map<int, std::string>::iterator it_list2 = it_list;
451 for(;it_list != lvlist.end(); it_list++)
453 std::map<std::string, std::vector <std::string> >::iterator it_tree = DscpTree.begin();
454 for (;it_tree != DscpTree.end(); it_tree++)
456 if(it_tree->first == name)
458 DscpTree.erase(it_tree);
463 lvlist.erase(it_list2, lvlist.end());
468 //////////////////////////////////////////////////////
469 // add an attribute in a level //
470 // @param level : level's name to add attribute //
471 // @param name : attribute's name //
472 // @return : boolean result //
473 //////////////////////////////////////////////////
474 bool WxDescriptorPanel::addAtribute(const std::string &level, const std::string &name)
477 std::map<std::string, std::vector <std::string> >::iterator it_tree = DscpTree.begin();
478 for (;it_tree != DscpTree.end(); it_tree++)
480 if (it_tree->first.c_str() == level)
482 std::vector<std::string>::iterator it_branch = it_tree->second.begin();
483 for(;it_branch != it_tree->second.end(); it_branch++)
485 if(it_branch->c_str() == name)
492 it_tree->second.push_back(name);
500 //////////////////////////////////////////////////////
501 // remove an attribute from a level //
502 // @param level : level's name to remove attribute //
503 // @param name : attribute's name //
504 // @return : boolean result //
505 //////////////////////////////////////////////////
506 bool WxDescriptorPanel::RemoveAttribute(const std::string &level, const std::string &name)
508 bool bresult = false;
509 std::map<std::string, std::vector <std::string> >::iterator it_tree = DscpTree.begin();
510 for (;it_tree != DscpTree.end(); it_tree++)
512 if(it_tree->first == level)
514 std::vector<std::string>::iterator it_branch = it_tree->second.begin();
515 cout << it_tree->second.size();
516 for(;it_branch != it_tree->second.end(); it_branch++)
518 if(it_branch->c_str() == name)
521 it_tree->second.erase(it_branch);
530 //////////////////////////////////////////////////
531 // create a new descriptor //
532 // @param event : WxEvent //
534 //////////////////////////////////////////////////
535 void WxDescriptorPanel::OnNew(wxCommandEvent &Event)
537 LevelCtrl->SetValue(_T("patient"));
543 //////////////////////////////////////////////////
544 // Load a descriptor file //
545 // @param event : WxEvent //
547 //////////////////////////////////////////////////
548 void WxDescriptorPanel::OnLoad(wxCommandEvent &Event)
550 long style = wxOPEN | wxFILE_MUST_EXIST;
551 LevelCtrl->SetValue(_T("patient"));
556 std::string wc("*.dscp");
557 wxFileDialog* FD = new wxFileDialog( 0,
559 crea::std2wx(m_path),
564 if (FD->ShowModal()==wxID_OK)
566 loadDescriptor(crea::wx2std(FD->GetPath()).c_str());
571 //////////////////////////////////////////////////
572 // Save a descriptor //
573 // @param event : WxEvent //
575 //////////////////////////////////////////////////
576 void WxDescriptorPanel::OnOK(wxCommandEvent &Event)
582 /////////////////////////////////////////////////////
583 // Save a descriptor and apply it (create a new DB//
584 // @param event : WxEvent //
586 /////////////////////////////////////////////////////
587 void WxDescriptorPanel::OnApply(wxCommandEvent &Event)
589 m_DscpFile = saveDescriptor();
591 SetReturnCode(ID_DSCP_APPLY);
594 const std::string WxDescriptorPanel::saveDescriptor()
596 std::string file = "";
598 std::string wc("*.dscp");
599 wxFileDialog* FD = new wxFileDialog( 0,
608 if (FD->ShowModal()==wxID_OK)
610 createDescriptorFile();
611 file = crea::wx2std(FD->GetPath()).c_str();
612 std::ofstream ofs(file.c_str());
620 ///////////////////////////////////////////////////////
622 // @param event : WxEvent //
624 ///////////////////////////////////////////////////////
626 void WxDescriptorPanel::OnCancel(wxCommandEvent& event)
630 ///////////////////////////////////////////////////////
631 // create a descriptor file //
634 ///////////////////////////////////////////////////////
635 void WxDescriptorPanel::createDescriptorFile()
639 outDscp += "<level>";
643 outDscp += "O Name Name 4";
645 std::map<std::string, std::vector <std::string> >::iterator it_tree = DscpTree.begin();
646 std::map<int, std::string >::iterator it_lv_nb = lvlist.begin();
647 std::map<int, std::string >::iterator it_lv = lvlist.begin();
649 for (;it_lv != lvlist.end(); it_lv++)
653 outDscp += it_lv->second.c_str();
655 if(it_lv_nb != lvlist.end())
657 outDscp += "O NumberOfChildren ";
658 outDscp += it_lv_nb->second.c_str();
663 std::vector<std::string>::iterator it_branch = DscpTree[it_lv->second.c_str()].begin();
664 for(;it_branch != DscpTree[it_lv->second.c_str()].end(); it_branch++)
666 std::string att = it_branch->c_str();
667 if(att[0] == 'D' && att[7] == '_' && att.size() == 14)
670 outDscp += att.substr(1,6) + " "; // GR
671 outDscp += att.substr(8,6) + " ";// EL
678 outDscp += it_branch->c_str();
680 outDscp += ownatt[att];
691 ///////////////////////////////////////////////////////
692 // load a descriptor //
693 // @param i_name : file name to load //
695 /////////////////////////////////////////////////////
696 void WxDescriptorPanel::loadDescriptor(const std::string i_name)
698 std::ifstream i_file(i_name.c_str());
699 std::stringstream buffer;
700 buffer << i_file.rdbuf();
708 while(std::getline(buffer, line))
711 { //increment levels.
717 // For each level, a name to describe it
727 // split line to find all tags
728 std::vector<std::string> descriptors;
729 std::string separator = " ";
730 std::string::size_type last_pos = line.find_first_not_of(separator);
731 //find first separator
732 std::string::size_type pos = line.find_first_of(separator, last_pos);
733 while(std::string::npos != pos || std::string::npos != last_pos)
735 descriptors.push_back(line.substr(last_pos, pos - last_pos));
736 last_pos = line.find_first_not_of(separator, pos);
737 pos = line.find_first_of(separator, last_pos);
740 // By default, the last tag is at zero and not recorded but if take in count
741 unsigned int flag = 0;
742 if(descriptors.size() == 4)
744 std::stringstream val;
745 val << std::dec << descriptors[3];
749 // if Dicom tag, use "group" and "element" descriptor
750 if(descriptors[0] == "D")
751 { std::stringstream val, val2;
752 unsigned short group;
753 unsigned short element;
754 val << std::dec << descriptors[1] ;
755 val >> std::hex >> group;
756 val2 << std::dec << descriptors[2];
757 val2 >> std::hex >> element;
758 std::string compose = "D";
759 compose += descriptors[1];
761 compose += descriptors[2];
762 GDCM_NAME_SPACE::DictEntry* entry = GDCM_NAME_SPACE::Global::GetDicts()->GetDefaultPubDict()->GetEntry(group, element);
765 onAddAttribute( entry->GetName(),compose, level);
768 else if(descriptors[0].find("#") != -1)
770 // commented line continue to next line
772 else // "O" means if user's own tag.
774 boost::algorithm::replace_all(descriptors[2],"_"," ");
775 if(ilevel>0 && descriptors[1] != "NumberOfChildren" )
777 onAddAttribute( descriptors[2].c_str(),descriptors[1].c_str(), level);
784 //======================================================================
786 //======================================================================
788 } // EO namespace creaImageIO