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 wxStaticLine *line1 = new wxStaticLine(this, -1, wxPoint(5,40), wxSize(540,2));
42 wxStaticText * LevelText=new wxStaticText(this,-1,_T(" Level: "), wxPoint(5,50));
43 LevelCtrl=new wxTextCtrl(this, ID_GR_CTRL,_T("patient"), wxPoint(50,50), wxSize(50,25));
44 wxButton *addLevel = new wxButton(this, ID_LEVEL_ADD,_T("add a level"), wxPoint(150,50) );
45 Connect( addLevel->GetId(), wxEVT_COMMAND_BUTTON_CLICKED , (wxObjectEventFunction) &WxDescriptorPanel::OnAddLevel );
47 wxStaticLine *line2 = new wxStaticLine(this, -1, wxPoint(5,75), wxSize(540,2));
51 wxStaticText * GR=new wxStaticText(this,-1,_T(" DICOM Group: "), wxPoint(5,110));
52 GRCtrl=new wxTextCtrl(this, ID_GR_CTRL,_T("0x0010"), wxPoint(82,110), wxSize(50,25));
53 Connect( GRCtrl->GetId(), wxEVT_COMMAND_TEXT_UPDATED , (wxObjectEventFunction) &WxDescriptorPanel::OnDicomAttribute );
55 wxStaticText * EL=new wxStaticText(this,-1,_T(" DICOM Element: "), wxPoint(140,110));
56 ELCtrl=new wxTextCtrl(this, ID_EL_CTRL,_T("0x0010"), wxPoint(230,110), wxSize(50,25));
57 Connect( ELCtrl->GetId(), wxEVT_COMMAND_TEXT_UPDATED , (wxObjectEventFunction) &WxDescriptorPanel::OnDicomAttribute );
61 choices[0] = _T("Unknow Attribute");
62 std::map<std::string, std::string>::iterator it_att =ownatt.begin();
63 for(int i = 1; it_att != ownatt.end(); it_att++, i++)
65 choices[i] = crea::std2wx(it_att->second);
69 AttributeCombo = new wxComboBox(this, ID_ATTRIBUTE_CTRL,_T(""),wxPoint(300,110), wxSize(120,25),3,choices, wxCB_READONLY);
70 AttributeCombo->SetSelection(0);
73 wxButton *addAttribute = new wxButton(this, ID_ATTRIBUTE_ADD,_T("add an attribute"), wxPoint(440,110) );
74 Connect( addAttribute->GetId(), wxEVT_COMMAND_BUTTON_CLICKED , (wxObjectEventFunction) &WxDescriptorPanel::OnAddAttribute );
76 wxStaticLine *line3 = new wxStaticLine(this, -1, wxPoint(5,140), wxSize(540,2));
80 ResultCtrl=new wxTextCtrl(this, ID_EL_CTRL,_T(""), wxPoint(5,150), wxSize(250,310), wxTE_READONLY| wxMac | wxTE_MULTILINE | wxTE_RICH );
81 wxButton *RemoveCtrl = new wxButton(this, ID_REMOVE_ADD,_T("Remove an entry"), wxPoint(280,200) );
82 Connect( RemoveCtrl->GetId(), wxEVT_COMMAND_BUTTON_CLICKED , (wxObjectEventFunction) &WxDescriptorPanel::OnRemove );
84 wxStaticLine *line4 = new wxStaticLine(this, -1, wxPoint(5,470), wxSize(540,2));
86 wxButton *Ok = new wxButton(this, -1,_T("OK"), wxPoint(10,480) );
87 Connect( Ok->GetId(), wxEVT_COMMAND_BUTTON_CLICKED , (wxObjectEventFunction) &WxDescriptorPanel::OnOK );
89 wxButton *Apply = new wxButton(this, -1,_T("APPLY"), wxPoint(150,480) );
90 Connect( Apply->GetId(), wxEVT_COMMAND_BUTTON_CLICKED , (wxObjectEventFunction) &WxDescriptorPanel::OnApply );
92 wxButton *Cancel = new wxButton(this, wxID_CANCEL,_T("CANCEL"), wxPoint(250,480) );
93 // Connect( Cancel->GetId(), wxEVT_COMMAND_BUTTON_CLICKED , (wxCloseEvent) &wxWindow::Close );
100 WxDescriptorPanel::~WxDescriptorPanel()
102 GimmickDebugMessage(1,"WxCustomizeConfigPanel::~WxCustomizeConfigPanel"
106 //////////////////////////////////////////////////////////
107 // Add an attribute //
108 // @param event : Wxevent //
110 //////////////////////////////////////////////////
111 void WxDescriptorPanel::OnAddAttribute(wxCommandEvent& event)
114 std::string name_att;
115 if (AttributeCombo->GetSelection() == 0)
117 name_att = "D" + crea::wx2std(GRCtrl->GetValue()) + "_" + crea::wx2std(ELCtrl->GetValue());
121 wxString wd = AttributeCombo->GetValue();
122 std::string st = crea::wx2std(wd);
123 name_att = OwnAttribute(st);
125 onAddAttribute(crea::wx2std(AttributeCombo->GetValue()), name_att);
127 //////////////////////////////////////////////////////////
128 // add an attribute //
129 // @param att : attribute //
130 // @param name_att : 's name //
131 // @param level : level to add the attribute //
133 //////////////////////////////////////////////////
134 void WxDescriptorPanel::onAddAttribute( const std::string &att, const std::string &name_att,std::string level )
138 wxMessageBox(_T("Need a level first!"),crea::std2wx("WARNING"),wxOK,this);
144 // Find Name of level
150 if (!addAtribute(level, name_att))
152 wxMessageBox(_T("Attribute already used in this level"),crea::std2wx("WARNING"),wxOK,this);
156 ResultCtrl->SetInsertionPoint(InsertPt);
157 for (int i = 1; i<=lv;i++)
159 ResultCtrl->WriteText(_T(" "));
161 ResultCtrl->WriteText(_T("| - "));
162 ResultCtrl->WriteText(crea::std2wx(att));
163 wxTextAttr ResultAttr(ResultCtrl->GetDefaultStyle());
164 ResultAttr.SetTextColour(*wxWHITE);
165 ResultCtrl->SetDefaultStyle(ResultAttr);
166 std::string text = " ";
167 ResultCtrl->WriteText(crea::std2wx(" " + name_att));
168 ResultAttr.SetTextColour(*wxBLACK);
169 ResultCtrl->SetDefaultStyle(ResultAttr);
170 ResultCtrl->WriteText(_T("\n"));
172 InsertPt = ResultCtrl->GetInsertionPoint();
177 //////////////////////////////////////////////////////////
179 // @param event : Wxevent //
181 //////////////////////////////////////////////////
182 void WxDescriptorPanel::OnAddLevel(wxCommandEvent& event)
184 if( !LevelCtrl->GetValue().IsEmpty() )
186 onAddLevel(crea::wx2std(LevelCtrl->GetValue()));
190 //////////////////////////////////////////////////////////
192 // @param level : level's name //
194 //////////////////////////////////////////////////
195 void WxDescriptorPanel::onAddLevel(const std::string &level)
199 wxMessageBox(_T("Level already used"),crea::std2wx(("WARNING")),wxOK,this);
204 ResultCtrl->SetInsertionPoint(InsertPt);
205 for (int i = 1; i<lv;i++)
207 ResultCtrl->WriteText(_T(" "));
210 { ResultCtrl->WriteText(_T("| \n"));
211 for (int i = 1; i<lv;i++)
213 ResultCtrl->WriteText(_T(" "));
215 ResultCtrl->WriteText(_T("|_"));
218 wxTextAttr ResultAttr(ResultCtrl->GetDefaultStyle());
219 ResultAttr.SetTextColour(*wxRED);
220 ResultCtrl->SetDefaultStyle(ResultAttr);
221 ResultCtrl->WriteText(crea::std2wx(level));
222 ResultAttr.SetTextColour(*wxBLACK);
223 ResultCtrl->SetDefaultStyle(ResultAttr);
224 ResultCtrl->WriteText(_T("\n"));
225 InsertPt = ResultCtrl->GetInsertionPoint();
229 //////////////////////////////////////////////////////////
230 // Find a DICOM attribute from group and element values //
231 // @param event : Wxevent //
233 //////////////////////////////////////////////////
234 void WxDescriptorPanel::OnDicomAttribute(wxCommandEvent& event)
237 if(!GRCtrl->GetValue().IsEmpty() && !ELCtrl->GetValue().IsEmpty()
238 && GRCtrl->GetValue().Len() == 6 && ELCtrl->GetValue().Len() == 6 && AttributeCombo->GetSelection() == 0)
241 std::string gr = crea::wx2std(GRCtrl->GetValue());
242 std::string el = crea::wx2std(ELCtrl->GetValue());
243 std::stringstream val;
245 unsigned short group;
246 unsigned short element;
247 val << std::dec << gr ;
248 val >> std::hex >> group;
250 val << std::dec << el ;
251 val >> std::hex >> element;
252 #if defined(USE_GDCM)
253 // Retrieve the name from gdcm dict
254 GDCM_NAME_SPACE::DictEntry* entry = GDCM_NAME_SPACE::Global::GetDicts()->GetDefaultPubDict()->GetEntry(group, element);
255 // AttributeCombo->Clear();
258 AttributeCombo->Delete(0);
259 AttributeCombo->Insert(crea::std2wx(entry->GetName()), 0);
263 AttributeCombo->Delete(0);
264 AttributeCombo->Insert(_T("Unknown Attribute"),0);
267 AttributeCombo->SetSelection(0);
274 //////////////////////////////////////////////////////////
275 // determine values for own attributes //
276 // @param name : attribute's name //
277 // @param key : indicates key map or not //
279 //////////////////////////////////////////////////
280 std::string WxDescriptorPanel::OwnAttribute(const std::string name)
284 std::map<std::string, std::string>::iterator it_att = ownatt.begin();
285 for(; it_att != ownatt.end(); it_att++)
287 if(it_att->second == name)
289 result = it_att->first.c_str();
296 //////////////////////////////////////////////////////////
297 // Find a level in function of position in Return Ctrl //
300 //////////////////////////////////////////////////
301 std::string WxDescriptorPanel::findLevel()
306 ResultCtrl->PositionToXY( ResultCtrl->GetInsertionPoint(),&column, &line);
307 std::string tx(crea::wx2std(ResultCtrl->GetRange(0, ResultCtrl->XYToPosition(0,line+1))).c_str());
308 std::string::size_type level_pos_start = tx.rfind("|_");
309 if(level_pos_start == -1)
315 level_pos_start += 2;
318 std::string::size_type level_pos_end = tx.find_first_of("\n",level_pos_start);
319 return tx.substr(level_pos_start,level_pos_end - level_pos_start);
322 //////////////////////////////////////////////////////
324 // @param event : Wxevent //
326 //////////////////////////////////////////////////
327 void WxDescriptorPanel::OnRemove(wxCommandEvent& event)
334 pos_start = ResultCtrl->GetInsertionPoint();
335 ResultCtrl->PositionToXY( pos_start,&column, &line);
338 std::string name("root");
345 wxString text = ResultCtrl->GetLineText(line);
346 if ( text.Find(_T("|_")) == -1)
348 std::string level = findLevel();
349 // find GR and EL values to remove
350 std::string tx = crea::wx2std(text);
351 std::string::size_type EL_start_pos = tx.find_last_of(" ");
352 RemoveAttribute(level, tx.substr(EL_start_pos+1,tx.size() - EL_start_pos));
353 ResultCtrl->Remove( ResultCtrl->XYToPosition(0,line), ResultCtrl->XYToPosition(0,line+1));
357 RemoveLevel(crea::wx2std(text.AfterFirst('_')));
358 lv = text.Find(_T("|"))/3;
359 pos_start= ResultCtrl->XYToPosition(0,line-1);
360 ResultCtrl->SetInsertionPointEnd();
361 pos_end = ResultCtrl->GetInsertionPoint();
362 ResultCtrl->Remove(pos_start, pos_end);
367 //////////////////////////////////////////////
368 // create a descriptor structure //
369 // @param name : level's name to add //
370 // @return : boolean result //
371 //////////////////////////////////////////////////
372 void WxDescriptorPanel::CreateDescriptor(int type)
374 if(type == 0) // First initialization
377 outDscp += "<level>";
381 outDscp += "O Name Name 4";
388 outDscp += "O NumberOfChildren ";
389 outDscp += crea::wx2std(LevelCtrl->GetValue());
393 outDscp += "<level>";
395 outDscp += crea::wx2std(LevelCtrl->GetValue());
403 outDscp += crea::wx2std(GRCtrl->GetValue());
405 outDscp += crea::wx2std(ELCtrl->GetValue());
415 //////////////////////////////////////////////////////
417 // @param name : level's name to add //
418 // @return : boolean result //
419 //////////////////////////////////////////////////
420 bool WxDescriptorPanel::addLevel(const std::string &name)
423 std::map<std::string, std::vector <std::string> >::iterator it_tree = DscpTree.begin();
424 for (;it_tree != DscpTree.end(); it_tree++)
426 if(it_tree->first == name)
435 std::vector <std::string> branch;
436 DscpTree[name] = branch;
441 //////////////////////////////////////////////////////
443 // @param name : level's name to remove //
444 // @return : boolean result //
445 //////////////////////////////////////////////////
446 bool WxDescriptorPanel::RemoveLevel(const std::string &name)
448 bool bresult = false;
449 std::map<int, std::string>::iterator it_list= lvlist.begin();
450 for(; it_list != lvlist.end(); it_list++)
452 if(it_list->second == name)
457 std::map<int, std::string>::iterator it_list2 = it_list;
458 for(;it_list != lvlist.end(); it_list++)
460 std::map<std::string, std::vector <std::string> >::iterator it_tree = DscpTree.begin();
461 for (;it_tree != DscpTree.end(); it_tree++)
463 if(it_tree->first == name)
465 DscpTree.erase(it_tree);
470 lvlist.erase(it_list2, lvlist.end());
475 //////////////////////////////////////////////////////
476 // add an attribute in a level //
477 // @param level : level's name to add attribute //
478 // @param name : attribute's name //
479 // @return : boolean result //
480 //////////////////////////////////////////////////
481 bool WxDescriptorPanel::addAtribute(const std::string &level, const std::string &name)
484 std::map<std::string, std::vector <std::string> >::iterator it_tree = DscpTree.begin();
485 for (;it_tree != DscpTree.end(); it_tree++)
487 if (it_tree->first.c_str() == level)
489 std::vector<std::string>::iterator it_branch = it_tree->second.begin();
490 for(;it_branch != it_tree->second.end(); it_branch++)
492 if(it_branch->c_str() == name)
499 it_tree->second.push_back(name);
507 //////////////////////////////////////////////////////
508 // remove an attribute from a level //
509 // @param level : level's name to remove attribute //
510 // @param name : attribute's name //
511 // @return : boolean result //
512 //////////////////////////////////////////////////
513 bool WxDescriptorPanel::RemoveAttribute(const std::string &level, const std::string &name)
515 bool bresult = false;
516 std::map<std::string, std::vector <std::string> >::iterator it_tree = DscpTree.begin();
517 for (;it_tree != DscpTree.end(); it_tree++)
519 if(it_tree->first == level)
521 std::vector<std::string>::iterator it_branch = it_tree->second.begin();
522 cout << it_tree->second.size();
523 for(;it_branch != it_tree->second.end(); it_branch++)
525 if(it_branch->c_str() == name)
528 it_tree->second.erase(it_branch);
537 //////////////////////////////////////////////////
538 // create a new descriptor //
539 // @param event : WxEvent //
541 //////////////////////////////////////////////////
542 void WxDescriptorPanel::OnNew(wxCommandEvent &Event)
544 LevelCtrl->SetValue(_T("patient"));
550 //////////////////////////////////////////////////
551 // Load a descriptor file //
552 // @param event : WxEvent //
554 //////////////////////////////////////////////////
555 void WxDescriptorPanel::OnLoad(wxCommandEvent &Event)
557 long style = wxOPEN | wxFILE_MUST_EXIST;
558 LevelCtrl->SetValue(_T("patient"));
563 std::string wc("*.dscp");
564 wxFileDialog* FD = new wxFileDialog( 0,
566 crea::std2wx(m_path),
571 if (FD->ShowModal()==wxID_OK)
573 loadDescriptor(crea::wx2std(FD->GetPath()).c_str());
578 //////////////////////////////////////////////////
579 // Save a descriptor //
580 // @param event : WxEvent //
582 //////////////////////////////////////////////////
583 void WxDescriptorPanel::OnOK(wxCommandEvent &Event)
589 /////////////////////////////////////////////////////
590 // Save a descriptor and apply it (create a new DB//
591 // @param event : WxEvent //
593 /////////////////////////////////////////////////////
594 void WxDescriptorPanel::OnApply(wxCommandEvent &Event)
596 m_DscpFile = saveDescriptor();
598 SetReturnCode(ID_DSCP_APPLY);
601 const std::string WxDescriptorPanel::saveDescriptor()
603 std::string file = "";
605 std::string wc("*.dscp");
606 wxFileDialog* FD = new wxFileDialog( 0,
615 if (FD->ShowModal()==wxID_OK)
617 createDescriptorFile();
618 file = crea::wx2std(FD->GetPath()).c_str();
619 std::ofstream ofs(file.c_str());
627 ///////////////////////////////////////////////////////
629 // @param event : WxEvent //
631 ///////////////////////////////////////////////////////
633 void WxDescriptorPanel::OnCancel(wxCommandEvent& event)
637 ///////////////////////////////////////////////////////
638 // create a descriptor file //
641 ///////////////////////////////////////////////////////
642 void WxDescriptorPanel::createDescriptorFile()
646 outDscp += "<level>";
650 outDscp += "O Name Name 4";
652 std::map<std::string, std::vector <std::string> >::iterator it_tree = DscpTree.begin();
653 std::map<int, std::string >::iterator it_lv_nb = lvlist.begin();
654 std::map<int, std::string >::iterator it_lv = lvlist.begin();
656 for (;it_lv != lvlist.end(); it_lv++)
660 outDscp += it_lv->second.c_str();
662 if(it_lv_nb != lvlist.end())
664 outDscp += "O NumberOfChildren ";
665 outDscp += it_lv_nb->second.c_str();
670 std::vector<std::string>::iterator it_branch = DscpTree[it_lv->second.c_str()].begin();
671 for(;it_branch != DscpTree[it_lv->second.c_str()].end(); it_branch++)
673 std::string att = it_branch->c_str();
674 if(att[0] == 'D' && att[7] == '_' && att.size() == 14)
677 outDscp += att.substr(1,6) + " "; // GR
678 outDscp += att.substr(8,6) + " ";// EL
685 outDscp += it_branch->c_str();
687 outDscp += ownatt[att];
698 ///////////////////////////////////////////////////////
699 // load a descriptor //
700 // @param i_name : file name to load //
702 /////////////////////////////////////////////////////
703 void WxDescriptorPanel::loadDescriptor(const std::string i_name)
705 std::ifstream i_file(i_name.c_str());
706 std::stringstream buffer;
707 buffer << i_file.rdbuf();
711 #if defined(USE_GDCM2)
712 const gdcm::Global& g = gdcm::Global::GetInstance(); // sum of all knowledge !
713 const gdcm::Dicts &dicts = g.GetDicts();
714 const gdcm::Dict &dict = dicts.GetPublicDict(); // Part 6
722 while(std::getline(buffer, line))
725 { //increment levels.
731 // For each level, a name to describe it
741 // split line to find all tags
742 std::vector<std::string> descriptors;
743 std::string separator = " ";
744 std::string::size_type last_pos = line.find_first_not_of(separator);
745 //find first separator
746 std::string::size_type pos = line.find_first_of(separator, last_pos);
747 while(std::string::npos != pos || std::string::npos != last_pos)
749 descriptors.push_back(line.substr(last_pos, pos - last_pos));
750 last_pos = line.find_first_not_of(separator, pos);
751 pos = line.find_first_of(separator, last_pos);
754 // By default, the last tag is at zero and not recorded but if take in count
755 unsigned int flag = 0;
756 if(descriptors.size() == 4)
758 std::stringstream val;
759 val << std::dec << descriptors[3];
763 // if Dicom tag, use "group" and "element" descriptor
764 if(descriptors[0] == "D")
765 { std::stringstream val, val2;
766 unsigned short group;
767 unsigned short element;
768 val << std::dec << descriptors[1] ;
769 val >> std::hex >> group;
770 val2 << std::dec << descriptors[2];
771 val2 >> std::hex >> element;
772 std::string compose = "D";
773 compose += descriptors[1];
775 compose += descriptors[2];
776 #if defined(USE_GDCM)
777 GDCM_NAME_SPACE::DictEntry* entry = GDCM_NAME_SPACE::Global::GetDicts()->GetDefaultPubDict()->GetEntry(group, element);
780 onAddAttribute( entry->GetName(),compose, level);
784 #if defined(USE_GDCM2)
785 gdcm::DictEntry dictentry = dict.GetDictEntry(gdcm::Tag(group, element));
788 onAddAttribute( dictentry.GetName(),compose, level);
794 else if(descriptors[0].find("#") != -1)
796 // commented line continue to next line
798 else // "O" means if user's own tag.
800 boost::algorithm::replace_all(descriptors[2],"_"," ");
801 if(ilevel>0 && descriptors[1] != "NumberOfChildren" )
803 onAddAttribute( descriptors[2].c_str(),descriptors[1].c_str(), level);
810 //======================================================================
812 //======================================================================
814 } // EO namespace creaImageIO