1 #include "creaImageIOWxDescriptorPanel.h"
2 #include <creaImageIOSystem.h>
4 #include <gdcmGlobal.h>
5 #include <gdcmDictSet.h>
9 #include <gdcmGlobal.h>
10 #include <gdcmDicts.h>
13 #include <boost/algorithm/string.hpp>
19 WxDescriptorPanel::WxDescriptorPanel(wxWindow *parent, const std::string path)
20 : wxDialog(parent, -1,_T("Descriptor Creation"), wxDefaultPosition, wxSize(550,550)) , m_path(path)
24 GimmickDebugMessage(1,"WxDescriptorPanel::WxDescriptorPanel"
28 ownatt["FullFileName"] = "Full_File_Name";
29 ownatt["FullFileDirectory"] = "Full_File_Directory";
33 wxButton *NewDescriptor = new wxButton(this, -1,_T("Create a new descriptor"), wxPoint(10,7) );
34 Connect( NewDescriptor->GetId(), wxEVT_COMMAND_BUTTON_CLICKED , (wxObjectEventFunction) &WxDescriptorPanel::OnNew );
36 wxButton *LoadDescriptor = new wxButton(this, -1,_T("Load a descriptor"), wxPoint(150,7) );
37 Connect( LoadDescriptor->GetId(), wxEVT_COMMAND_BUTTON_CLICKED , (wxObjectEventFunction) &WxDescriptorPanel::OnLoad );
39 /// \TODO fix warning: unused variable line1
40 wxStaticLine *line1 = new wxStaticLine(this, -1, wxPoint(5,40), wxSize(540,2));
43 /// \TODO fix warning: unused variable LevelText
44 wxStaticText * LevelText=new wxStaticText(this,-1,_T(" Level: "), wxPoint(5,50));
45 LevelCtrl=new wxTextCtrl(this, ID_GR_CTRL,_T("patient"), wxPoint(50,50), wxSize(50,25));
46 wxButton *addLevel = new wxButton(this, ID_LEVEL_ADD,_T("add a level"), wxPoint(150,50) );
47 Connect( addLevel->GetId(), wxEVT_COMMAND_BUTTON_CLICKED , (wxObjectEventFunction) &WxDescriptorPanel::OnAddLevel );
49 /// \TODO fix warning: unused variable line2
50 wxStaticLine *line2 = new wxStaticLine(this, -1, wxPoint(5,75), wxSize(540,2));
54 /// \TODO fix warning: unused variable GR
55 wxStaticText * GR=new wxStaticText(this,-1,_T(" DICOM Group: "), wxPoint(5,110));
56 GRCtrl=new wxTextCtrl(this, ID_GR_CTRL,_T("0x0010"), wxPoint(82,110), wxSize(50,25));
57 Connect( GRCtrl->GetId(), wxEVT_COMMAND_TEXT_UPDATED , (wxObjectEventFunction) &WxDescriptorPanel::OnDicomAttribute );
59 /// \TODO fix warning: unused variable EL
60 wxStaticText * EL=new wxStaticText(this,-1,_T(" DICOM Element: "), wxPoint(140,110));
61 ELCtrl=new wxTextCtrl(this, ID_EL_CTRL,_T("0x0010"), wxPoint(230,110), wxSize(50,25));
62 Connect( ELCtrl->GetId(), wxEVT_COMMAND_TEXT_UPDATED , (wxObjectEventFunction) &WxDescriptorPanel::OnDicomAttribute );
65 choices[0] = _T("Unknow Attribute");
66 std::map<std::string, std::string>::iterator it_att =ownatt.begin();
67 for(int i = 1; it_att != ownatt.end(); it_att++, i++)
69 choices[i] = crea::std2wx(it_att->second);
73 AttributeCombo = new wxComboBox(this, ID_ATTRIBUTE_CTRL,_T(""),wxPoint(300,110), wxSize(120,25),3,choices, wxCB_READONLY);
74 AttributeCombo->SetSelection(0);
77 wxButton *addAttribute = new wxButton(this, ID_ATTRIBUTE_ADD,_T("add an attribute"), wxPoint(440,110) );
78 Connect( addAttribute->GetId(), wxEVT_COMMAND_BUTTON_CLICKED , (wxObjectEventFunction) &WxDescriptorPanel::OnAddAttribute );
79 /// \TODO fix warning: unused variable line3
80 wxStaticLine *line3 = new wxStaticLine(this, -1, wxPoint(5,140), wxSize(540,2));
84 ResultCtrl=new wxTextCtrl(this, ID_EL_CTRL,_T(""), wxPoint(5,150), wxSize(250,310), wxTE_READONLY| wxMac | wxTE_MULTILINE | wxTE_RICH );
85 wxButton *RemoveCtrl = new wxButton(this, ID_REMOVE_ADD,_T("Remove an entry"), wxPoint(280,200) );
86 Connect( RemoveCtrl->GetId(), wxEVT_COMMAND_BUTTON_CLICKED , (wxObjectEventFunction) &WxDescriptorPanel::OnRemove );
88 /// \TODO fix warning: unused variable line4
89 wxStaticLine *line4 = new wxStaticLine(this, -1, wxPoint(5,470), wxSize(540,2));
91 wxButton *Ok = new wxButton(this, -1,_T("OK"), wxPoint(10,480) );
92 Connect( Ok->GetId(), wxEVT_COMMAND_BUTTON_CLICKED , (wxObjectEventFunction) &WxDescriptorPanel::OnOK );
94 wxButton *Apply = new wxButton(this, -1,_T("APPLY"), wxPoint(150,480) );
95 Connect( Apply->GetId(), wxEVT_COMMAND_BUTTON_CLICKED , (wxObjectEventFunction) &WxDescriptorPanel::OnApply );
97 /// \TODO fix warning: unused variable Cancel
98 wxButton *Cancel = new wxButton(this, wxID_CANCEL,_T("CANCEL"), wxPoint(250,480) );
99 // Connect( Cancel->GetId(), wxEVT_COMMAND_BUTTON_CLICKED , (wxCloseEvent) &wxWindow::Close );
106 WxDescriptorPanel::~WxDescriptorPanel()
108 GimmickDebugMessage(1,"WxCustomizeConfigPanel::~WxCustomizeConfigPanel"
112 //////////////////////////////////////////////////////////
113 // Add an attribute //
114 // @param event : Wxevent //
116 //////////////////////////////////////////////////
117 void WxDescriptorPanel::OnAddAttribute(wxCommandEvent& event)
120 std::string name_att;
121 if (AttributeCombo->GetSelection() == 0)
123 name_att = "D" + crea::wx2std(GRCtrl->GetValue()) + "_" + crea::wx2std(ELCtrl->GetValue());
127 wxString wd = AttributeCombo->GetValue();
128 std::string st = crea::wx2std(wd);
129 name_att = OwnAttribute(st);
131 onAddAttribute(crea::wx2std(AttributeCombo->GetValue()), name_att);
133 //////////////////////////////////////////////////////////
134 // add an attribute //
135 // @param att : attribute //
136 // @param name_att : 's name //
137 // @param level : level to add the attribute //
139 //////////////////////////////////////////////////
140 void WxDescriptorPanel::onAddAttribute( const std::string &att, const std::string &name_att,std::string level )
144 wxMessageBox(_T("Need a level first!"),crea::std2wx("WARNING"),wxOK,this);
150 // Find Name of level
156 if (!addAtribute(level, name_att))
158 wxMessageBox(_T("Attribute already used in this level"),crea::std2wx("WARNING"),wxOK,this);
162 ResultCtrl->SetInsertionPoint(InsertPt);
163 for (int i = 1; i<=lv;i++)
165 ResultCtrl->WriteText(_T(" "));
167 ResultCtrl->WriteText(_T("| - "));
168 ResultCtrl->WriteText(crea::std2wx(att));
169 wxTextAttr ResultAttr(ResultCtrl->GetDefaultStyle());
170 ResultAttr.SetTextColour(*wxWHITE);
171 ResultCtrl->SetDefaultStyle(ResultAttr);
172 std::string text = " ";
173 ResultCtrl->WriteText(crea::std2wx(" " + name_att));
174 ResultAttr.SetTextColour(*wxBLACK);
175 ResultCtrl->SetDefaultStyle(ResultAttr);
176 ResultCtrl->WriteText(_T("\n"));
178 InsertPt = ResultCtrl->GetInsertionPoint();
183 //////////////////////////////////////////////////////////
185 // @param event : Wxevent //
187 //////////////////////////////////////////////////
188 void WxDescriptorPanel::OnAddLevel(wxCommandEvent& event)
190 if( !LevelCtrl->GetValue().IsEmpty() )
192 onAddLevel(crea::wx2std(LevelCtrl->GetValue()));
196 //////////////////////////////////////////////////////////
198 // @param level : level's name //
200 //////////////////////////////////////////////////
201 void WxDescriptorPanel::onAddLevel(const std::string &level)
205 wxMessageBox(_T("Level already used"),crea::std2wx(("WARNING")),wxOK,this);
210 ResultCtrl->SetInsertionPoint(InsertPt);
211 for (int i = 1; i<lv;i++)
213 ResultCtrl->WriteText(_T(" "));
216 { ResultCtrl->WriteText(_T("| \n"));
217 for (int i = 1; i<lv;i++)
219 ResultCtrl->WriteText(_T(" "));
221 ResultCtrl->WriteText(_T("|_"));
224 wxTextAttr ResultAttr(ResultCtrl->GetDefaultStyle());
225 ResultAttr.SetTextColour(*wxRED);
226 ResultCtrl->SetDefaultStyle(ResultAttr);
227 ResultCtrl->WriteText(crea::std2wx(level));
228 ResultAttr.SetTextColour(*wxBLACK);
229 ResultCtrl->SetDefaultStyle(ResultAttr);
230 ResultCtrl->WriteText(_T("\n"));
231 InsertPt = ResultCtrl->GetInsertionPoint();
235 //////////////////////////////////////////////////////////
236 // Find a DICOM attribute from group and element values //
237 // @param event : Wxevent //
239 //////////////////////////////////////////////////
240 void WxDescriptorPanel::OnDicomAttribute(wxCommandEvent& event)
243 if(!GRCtrl->GetValue().IsEmpty() && !ELCtrl->GetValue().IsEmpty()
244 && GRCtrl->GetValue().Len() == 6 && ELCtrl->GetValue().Len() == 6 && AttributeCombo->GetSelection() == 0)
247 std::string gr = crea::wx2std(GRCtrl->GetValue());
248 std::string el = crea::wx2std(ELCtrl->GetValue());
249 std::stringstream val;
251 unsigned short group;
252 unsigned short element;
253 val << std::dec << gr ;
254 val >> std::hex >> group;
256 val << std::dec << el ;
257 val >> std::hex >> element;
258 #if defined(USE_GDCM)
259 // Retrieve the name from gdcm dict
260 GDCM_NAME_SPACE::DictEntry* entry = GDCM_NAME_SPACE::Global::GetDicts()->GetDefaultPubDict()->GetEntry(group, element);
261 // AttributeCombo->Clear();
264 AttributeCombo->Delete(0);
265 AttributeCombo->Insert(crea::std2wx(entry->GetName()), 0);
269 AttributeCombo->Delete(0);
270 AttributeCombo->Insert(_T("Unknown Attribute"),0);
273 AttributeCombo->SetSelection(0);
280 //////////////////////////////////////////////////////////
281 // determine values for own attributes //
282 // @param name : attribute's name //
283 // @param key : indicates key map or not //
285 //////////////////////////////////////////////////
286 std::string WxDescriptorPanel::OwnAttribute(const std::string name)
290 std::map<std::string, std::string>::iterator it_att = ownatt.begin();
291 for(; it_att != ownatt.end(); it_att++)
293 if(it_att->second == name)
295 result = it_att->first.c_str();
302 //////////////////////////////////////////////////////////
303 // Find a level in function of position in Return Ctrl //
306 //////////////////////////////////////////////////
307 std::string WxDescriptorPanel::findLevel()
312 ResultCtrl->PositionToXY( ResultCtrl->GetInsertionPoint(),&column, &line);
313 std::string tx(crea::wx2std(ResultCtrl->GetRange(0, ResultCtrl->XYToPosition(0,line+1))).c_str());
314 std::string::size_type level_pos_start = tx.rfind("|_");
315 if(level_pos_start == -1)
321 level_pos_start += 2;
324 std::string::size_type level_pos_end = tx.find_first_of("\n",level_pos_start);
325 return tx.substr(level_pos_start,level_pos_end - level_pos_start);
328 //////////////////////////////////////////////////////
330 // @param event : Wxevent //
332 //////////////////////////////////////////////////
333 void WxDescriptorPanel::OnRemove(wxCommandEvent& event)
340 pos_start = ResultCtrl->GetInsertionPoint();
341 ResultCtrl->PositionToXY( pos_start,&column, &line);
344 std::string name("root");
351 wxString text = ResultCtrl->GetLineText(line);
352 if ( text.Find(_T("|_")) == -1)
354 std::string level = findLevel();
355 // find GR and EL values to remove
356 std::string tx = crea::wx2std(text);
357 std::string::size_type EL_start_pos = tx.find_last_of(" ");
358 RemoveAttribute(level, tx.substr(EL_start_pos+1,tx.size() - EL_start_pos));
359 ResultCtrl->Remove( ResultCtrl->XYToPosition(0,line), ResultCtrl->XYToPosition(0,line+1));
363 RemoveLevel(crea::wx2std(text.AfterFirst('_')));
364 lv = text.Find(_T("|"))/3;
365 pos_start= ResultCtrl->XYToPosition(0,line-1);
366 ResultCtrl->SetInsertionPointEnd();
367 pos_end = ResultCtrl->GetInsertionPoint();
368 ResultCtrl->Remove(pos_start, pos_end);
373 //////////////////////////////////////////////
374 // create a descriptor structure //
375 // @param name : level's name to add //
376 // @return : boolean result //
377 //////////////////////////////////////////////////
378 void WxDescriptorPanel::CreateDescriptor(int type)
380 if(type == 0) // First initialization
383 outDscp += "<level>";
387 outDscp += "O Name Name 4";
394 outDscp += "O NumberOfChildren ";
395 outDscp += crea::wx2std(LevelCtrl->GetValue());
399 outDscp += "<level>";
401 outDscp += crea::wx2std(LevelCtrl->GetValue());
409 outDscp += crea::wx2std(GRCtrl->GetValue());
411 outDscp += crea::wx2std(ELCtrl->GetValue());
421 //////////////////////////////////////////////////////
423 // @param name : level's name to add //
424 // @return : boolean result //
425 //////////////////////////////////////////////////
426 bool WxDescriptorPanel::addLevel(const std::string &name)
429 std::map<std::string, std::vector <std::string> >::iterator it_tree = DscpTree.begin();
430 for (;it_tree != DscpTree.end(); it_tree++)
432 if(it_tree->first == name)
441 std::vector <std::string> branch;
442 DscpTree[name] = branch;
447 //////////////////////////////////////////////////////
449 // @param name : level's name to remove //
450 // @return : boolean result //
451 //////////////////////////////////////////////////
452 bool WxDescriptorPanel::RemoveLevel(const std::string &name)
454 bool bresult = false;
455 std::map<int, std::string>::iterator it_list= lvlist.begin();
456 for(; it_list != lvlist.end(); it_list++)
458 if(it_list->second == name)
463 std::map<int, std::string>::iterator it_list2 = it_list;
464 for(;it_list != lvlist.end(); it_list++)
466 std::map<std::string, std::vector <std::string> >::iterator it_tree = DscpTree.begin();
467 for (;it_tree != DscpTree.end(); it_tree++)
469 if(it_tree->first == name)
471 DscpTree.erase(it_tree);
476 lvlist.erase(it_list2, lvlist.end());
481 //////////////////////////////////////////////////////
482 // add an attribute in a level //
483 // @param level : level's name to add attribute //
484 // @param name : attribute's name //
485 // @return : boolean result //
486 //////////////////////////////////////////////////
487 bool WxDescriptorPanel::addAtribute(const std::string &level, const std::string &name)
490 std::map<std::string, std::vector <std::string> >::iterator it_tree = DscpTree.begin();
491 for (;it_tree != DscpTree.end(); it_tree++)
493 if (it_tree->first.c_str() == level)
495 std::vector<std::string>::iterator it_branch = it_tree->second.begin();
496 for(;it_branch != it_tree->second.end(); it_branch++)
498 if(it_branch->c_str() == name)
505 it_tree->second.push_back(name);
513 //////////////////////////////////////////////////////
514 // remove an attribute from a level //
515 // @param level : level's name to remove attribute //
516 // @param name : attribute's name //
517 // @return : boolean result //
518 //////////////////////////////////////////////////
519 bool WxDescriptorPanel::RemoveAttribute(const std::string &level, const std::string &name)
521 bool bresult = false;
522 std::map<std::string, std::vector <std::string> >::iterator it_tree = DscpTree.begin();
523 for (;it_tree != DscpTree.end(); it_tree++)
525 if(it_tree->first == level)
527 std::vector<std::string>::iterator it_branch = it_tree->second.begin();
528 cout << it_tree->second.size();
529 for(;it_branch != it_tree->second.end(); it_branch++)
531 if(it_branch->c_str() == name)
534 it_tree->second.erase(it_branch);
543 //////////////////////////////////////////////////
544 // create a new descriptor //
545 // @param event : WxEvent //
547 //////////////////////////////////////////////////
548 void WxDescriptorPanel::OnNew(wxCommandEvent &Event)
550 LevelCtrl->SetValue(_T("patient"));
556 //////////////////////////////////////////////////
557 // Load a descriptor file //
558 // @param event : WxEvent //
560 //////////////////////////////////////////////////
561 void WxDescriptorPanel::OnLoad(wxCommandEvent &Event)
563 long style = wxOPEN | wxFILE_MUST_EXIST;
564 LevelCtrl->SetValue(_T("patient"));
569 std::string wc("*.dscp");
570 wxFileDialog* FD = new wxFileDialog( 0,
572 crea::std2wx(m_path),
577 if (FD->ShowModal()==wxID_OK)
579 loadDescriptor(crea::wx2std(FD->GetPath()).c_str());
584 //////////////////////////////////////////////////
585 // Save a descriptor //
586 // @param event : WxEvent //
588 //////////////////////////////////////////////////
589 void WxDescriptorPanel::OnOK(wxCommandEvent &Event)
595 /////////////////////////////////////////////////////
596 // Save a descriptor and apply it (create a new DB//
597 // @param event : WxEvent //
599 /////////////////////////////////////////////////////
600 void WxDescriptorPanel::OnApply(wxCommandEvent &Event)
602 m_DscpFile = saveDescriptor();
604 SetReturnCode(ID_DSCP_APPLY);
607 const std::string WxDescriptorPanel::saveDescriptor()
609 std::string file = "";
611 std::string wc("*.dscp");
612 wxFileDialog* FD = new wxFileDialog( 0,
621 if (FD->ShowModal()==wxID_OK)
623 createDescriptorFile();
624 file = crea::wx2std(FD->GetPath()).c_str();
625 std::ofstream ofs(file.c_str());
633 ///////////////////////////////////////////////////////
635 // @param event : WxEvent //
637 ///////////////////////////////////////////////////////
639 void WxDescriptorPanel::OnCancel(wxCommandEvent& event)
643 ///////////////////////////////////////////////////////
644 // create a descriptor file //
647 ///////////////////////////////////////////////////////
648 void WxDescriptorPanel::createDescriptorFile()
652 outDscp += "<level>";
656 outDscp += "O Name Name 4";
658 std::map<std::string, std::vector <std::string> >::iterator it_tree = DscpTree.begin();
659 std::map<int, std::string >::iterator it_lv_nb = lvlist.begin();
660 std::map<int, std::string >::iterator it_lv = lvlist.begin();
662 for (;it_lv != lvlist.end(); it_lv++)
666 outDscp += it_lv->second.c_str();
668 if(it_lv_nb != lvlist.end())
670 outDscp += "O NumberOfChildren ";
671 outDscp += it_lv_nb->second.c_str();
676 std::vector<std::string>::iterator it_branch = DscpTree[it_lv->second.c_str()].begin();
677 for(;it_branch != DscpTree[it_lv->second.c_str()].end(); it_branch++)
679 std::string att = it_branch->c_str();
680 if(att[0] == 'D' && att[7] == '_' && att.size() == 14)
683 outDscp += att.substr(1,6) + " "; // GR
684 outDscp += att.substr(8,6) + " ";// EL
691 outDscp += it_branch->c_str();
693 outDscp += ownatt[att];
704 ///////////////////////////////////////////////////////
705 // load a descriptor //
706 // @param i_name : file name to load //
708 /////////////////////////////////////////////////////
709 void WxDescriptorPanel::loadDescriptor(const std::string i_name)
711 std::ifstream i_file(i_name.c_str());
712 std::stringstream buffer;
713 buffer << i_file.rdbuf();
717 #if defined(USE_GDCM2)
718 const gdcm::Global& g = gdcm::Global::GetInstance(); // sum of all knowledge !
719 const gdcm::Dicts &dicts = g.GetDicts();
720 const gdcm::Dict &dict = dicts.GetPublicDict(); // Part 6
728 while(std::getline(buffer, line))
731 { //increment levels.
737 // For each level, a name to describe it
747 // split line to find all tags
748 std::vector<std::string> descriptors;
749 std::string separator = " ";
750 std::string::size_type last_pos = line.find_first_not_of(separator);
751 //find first separator
752 std::string::size_type pos = line.find_first_of(separator, last_pos);
753 while(std::string::npos != pos || std::string::npos != last_pos)
755 descriptors.push_back(line.substr(last_pos, pos - last_pos));
756 last_pos = line.find_first_not_of(separator, pos);
757 pos = line.find_first_of(separator, last_pos);
760 // By default, the last tag is at zero and not recorded but if take in count
761 unsigned int flag = 0;
762 if(descriptors.size() == 4)
764 std::stringstream val;
765 val << std::dec << descriptors[3];
769 // if Dicom tag, use "group" and "element" descriptor
770 if(descriptors[0] == "D")
771 { std::stringstream val, val2;
772 unsigned short group;
773 unsigned short element;
774 val << std::dec << descriptors[1] ;
775 val >> std::hex >> group;
776 val2 << std::dec << descriptors[2];
777 val2 >> std::hex >> element;
778 std::string compose = "D";
779 compose += descriptors[1];
781 compose += descriptors[2];
782 #if defined(USE_GDCM)
783 GDCM_NAME_SPACE::DictEntry* entry = GDCM_NAME_SPACE::Global::GetDicts()->GetDefaultPubDict()->GetEntry(group, element);
786 onAddAttribute( entry->GetName(),compose, level);
790 #if defined(USE_GDCM2)
791 gdcm::DictEntry dictentry = dict.GetDictEntry(gdcm::Tag(group, element));
794 onAddAttribute( dictentry.GetName(),compose, level);
800 else if(descriptors[0].find("#") != -1)
802 // commented line continue to next line
804 else // "O" means if user's own tag.
806 boost::algorithm::replace_all(descriptors[2],"_"," ");
807 if(ilevel>0 && descriptors[1] != "NumberOfChildren" )
809 onAddAttribute( descriptors[2].c_str(),descriptors[1].c_str(), level);
816 //======================================================================
818 //======================================================================
820 } // EO namespace creaImageIO