1 #include "creaImageIOWxDescriptorPanel.h"
2 #include <creaImageIOSystem.h>
3 #include <gdcmGlobal.h>
4 #include <gdcmDictSet.h>
6 #include <boost/algorithm/string.hpp>
12 WxDescriptorPanel::WxDescriptorPanel(wxWindow *parent, const std::string path)
13 : wxDialog(parent, -1,_T("Descriptor Creation"), wxDefaultPosition, wxSize(550,550)) , m_path(path)
17 GimmickDebugMessage(1,"WxDescriptorPanel::WxDescriptorPanel"
21 ownatt["FullFileName"] = "Full_File_Name";
22 ownatt["FullFileDirectory"] = "Full_File_Directory";
26 wxButton *NewDescriptor = new wxButton(this, -1,_T("Create a new descriptor"), wxPoint(10,7) );
27 Connect( NewDescriptor->GetId(), wxEVT_COMMAND_BUTTON_CLICKED , (wxObjectEventFunction) &WxDescriptorPanel::OnNew );
29 wxButton *LoadDescriptor = new wxButton(this, -1,_T("Load a descriptor"), wxPoint(150,7) );
30 Connect( LoadDescriptor->GetId(), wxEVT_COMMAND_BUTTON_CLICKED , (wxObjectEventFunction) &WxDescriptorPanel::OnLoad );
32 wxStaticLine *line1 = new wxStaticLine(this, -1, wxPoint(5,40), wxSize(540,2));
35 wxStaticText * LevelText=new wxStaticText(this,-1,_T(" Level: "), wxPoint(5,50));
36 LevelCtrl=new wxTextCtrl(this, ID_GR_CTRL,_T("patient"), wxPoint(50,50), wxSize(50,25));
37 wxButton *addLevel = new wxButton(this, ID_LEVEL_ADD,_T("add a level"), wxPoint(150,50) );
38 Connect( addLevel->GetId(), wxEVT_COMMAND_BUTTON_CLICKED , (wxObjectEventFunction) &WxDescriptorPanel::OnAddLevel );
40 wxStaticLine *line2 = new wxStaticLine(this, -1, wxPoint(5,75), wxSize(540,2));
44 wxStaticText * GR=new wxStaticText(this,-1,_T(" DICOM Group: "), wxPoint(5,110));
45 GRCtrl=new wxTextCtrl(this, ID_GR_CTRL,_T("0x0010"), wxPoint(82,110), wxSize(50,25));
46 Connect( GRCtrl->GetId(), wxEVT_COMMAND_TEXT_UPDATED , (wxObjectEventFunction) &WxDescriptorPanel::OnDicomAttribute );
48 wxStaticText * EL=new wxStaticText(this,-1,_T(" DICOM Element: "), wxPoint(140,110));
49 ELCtrl=new wxTextCtrl(this, ID_EL_CTRL,_T("0x0010"), wxPoint(230,110), wxSize(50,25));
50 Connect( ELCtrl->GetId(), wxEVT_COMMAND_TEXT_UPDATED , (wxObjectEventFunction) &WxDescriptorPanel::OnDicomAttribute );
54 choices[0] = _T("Unknow Attribute");
55 std::map<std::string, std::string>::iterator it_att =ownatt.begin();
56 for(int i = 1; it_att != ownatt.end(); it_att++, i++)
58 choices[i] = crea::std2wx(it_att->second);
62 AttributeCombo = new wxComboBox(this, ID_ATTRIBUTE_CTRL,_T(""),wxPoint(300,110), wxSize(120,25),3,choices, wxCB_READONLY);
63 AttributeCombo->SetSelection(0);
66 wxButton *addAttribute = new wxButton(this, ID_ATTRIBUTE_ADD,_T("add an attribute"), wxPoint(440,110) );
67 Connect( addAttribute->GetId(), wxEVT_COMMAND_BUTTON_CLICKED , (wxObjectEventFunction) &WxDescriptorPanel::OnAddAttribute );
69 wxStaticLine *line3 = new wxStaticLine(this, -1, wxPoint(5,140), wxSize(540,2));
73 ResultCtrl=new wxTextCtrl(this, ID_EL_CTRL,_T(""), wxPoint(5,150), wxSize(250,310), wxTE_READONLY| wxMac | wxTE_MULTILINE | wxTE_RICH );
74 wxButton *RemoveCtrl = new wxButton(this, ID_REMOVE_ADD,_T("Remove an entry"), wxPoint(280,200) );
75 Connect( RemoveCtrl->GetId(), wxEVT_COMMAND_BUTTON_CLICKED , (wxObjectEventFunction) &WxDescriptorPanel::OnRemove );
77 wxStaticLine *line4 = new wxStaticLine(this, -1, wxPoint(5,470), wxSize(540,2));
79 wxButton *Ok = new wxButton(this, -1,_T("OK"), wxPoint(10,480) );
80 Connect( Ok->GetId(), wxEVT_COMMAND_BUTTON_CLICKED , (wxObjectEventFunction) &WxDescriptorPanel::OnOK );
82 wxButton *Apply = new wxButton(this, -1,_T("APPLY"), wxPoint(150,480) );
83 Connect( Apply->GetId(), wxEVT_COMMAND_BUTTON_CLICKED , (wxObjectEventFunction) &WxDescriptorPanel::OnApply );
85 wxButton *Cancel = new wxButton(this, wxID_CANCEL,_T("CANCEL"), wxPoint(250,480) );
86 // Connect( Cancel->GetId(), wxEVT_COMMAND_BUTTON_CLICKED , (wxCloseEvent) &wxWindow::Close );
93 WxDescriptorPanel::~WxDescriptorPanel()
95 GimmickDebugMessage(1,"WxCustomizeConfigPanel::~WxCustomizeConfigPanel"
99 //////////////////////////////////////////////////////////
100 // Add an attribute //
101 // @param event : Wxevent //
103 //////////////////////////////////////////////////
104 void WxDescriptorPanel::OnAddAttribute(wxCommandEvent& event)
107 std::string name_att;
108 if (AttributeCombo->GetSelection() == 0)
110 name_att = "D" + crea::wx2std(GRCtrl->GetValue()) + "_" + crea::wx2std(ELCtrl->GetValue());
114 wxString wd = AttributeCombo->GetValue();
115 std::string st = crea::wx2std(wd);
116 name_att = OwnAttribute(st);
118 onAddAttribute(crea::wx2std(AttributeCombo->GetValue()), name_att);
120 //////////////////////////////////////////////////////////
121 // add an attribute //
122 // @param att : attribute //
123 // @param name_att : 's name //
124 // @param level : level to add the attribute //
126 //////////////////////////////////////////////////
127 void WxDescriptorPanel::onAddAttribute( const std::string &att, const std::string &name_att,std::string level )
131 wxMessageBox(_T("Need a level first!"),crea::std2wx("WARNING"),wxOK,this);
137 // Find Name of level
143 if (!addAtribute(level, name_att))
145 wxMessageBox(_T("Attribute already used in this level"),crea::std2wx("WARNING"),wxOK,this);
149 ResultCtrl->SetInsertionPoint(InsertPt);
150 for (int i = 1; i<=lv;i++)
152 ResultCtrl->WriteText(_T(" "));
154 ResultCtrl->WriteText(_T("| - "));
155 ResultCtrl->WriteText(crea::std2wx(att));
156 wxTextAttr ResultAttr(ResultCtrl->GetDefaultStyle());
157 ResultAttr.SetTextColour(*wxWHITE);
158 ResultCtrl->SetDefaultStyle(ResultAttr);
159 std::string text = " ";
160 ResultCtrl->WriteText(crea::std2wx(" " + name_att));
161 ResultAttr.SetTextColour(*wxBLACK);
162 ResultCtrl->SetDefaultStyle(ResultAttr);
163 ResultCtrl->WriteText(_T("\n"));
165 InsertPt = ResultCtrl->GetInsertionPoint();
170 //////////////////////////////////////////////////////////
172 // @param event : Wxevent //
174 //////////////////////////////////////////////////
175 void WxDescriptorPanel::OnAddLevel(wxCommandEvent& event)
177 if( !LevelCtrl->GetValue().IsEmpty() )
179 onAddLevel(crea::wx2std(LevelCtrl->GetValue()));
183 //////////////////////////////////////////////////////////
185 // @param level : level's name //
187 //////////////////////////////////////////////////
188 void WxDescriptorPanel::onAddLevel(const std::string &level)
192 wxMessageBox(_T("Level already used"),crea::std2wx(("WARNING")),wxOK,this);
197 ResultCtrl->SetInsertionPoint(InsertPt);
198 for (int i = 1; i<lv;i++)
200 ResultCtrl->WriteText(_T(" "));
203 { ResultCtrl->WriteText(_T("| \n"));
204 for (int i = 1; i<lv;i++)
206 ResultCtrl->WriteText(_T(" "));
208 ResultCtrl->WriteText(_T("|_"));
211 wxTextAttr ResultAttr(ResultCtrl->GetDefaultStyle());
212 ResultAttr.SetTextColour(*wxRED);
213 ResultCtrl->SetDefaultStyle(ResultAttr);
214 ResultCtrl->WriteText(crea::std2wx(level));
215 ResultAttr.SetTextColour(*wxBLACK);
216 ResultCtrl->SetDefaultStyle(ResultAttr);
217 ResultCtrl->WriteText(_T("\n"));
218 InsertPt = ResultCtrl->GetInsertionPoint();
222 //////////////////////////////////////////////////////////
223 // Find a DICOM attribute from group and element values //
224 // @param event : Wxevent //
226 //////////////////////////////////////////////////
227 void WxDescriptorPanel::OnDicomAttribute(wxCommandEvent& event)
230 if(!GRCtrl->GetValue().IsEmpty() && !ELCtrl->GetValue().IsEmpty()
231 && GRCtrl->GetValue().Len() == 6 && ELCtrl->GetValue().Len() == 6 && AttributeCombo->GetSelection() == 0)
234 std::string gr = crea::wx2std(GRCtrl->GetValue());
235 std::string el = crea::wx2std(ELCtrl->GetValue());
236 std::stringstream val;
238 unsigned short group;
239 unsigned short element;
240 val << std::dec << gr ;
241 val >> std::hex >> group;
243 val << std::dec << el ;
244 val >> std::hex >> element;
246 // Retrieve the name from gdcm dict
247 GDCM_NAME_SPACE::DictEntry* entry = GDCM_NAME_SPACE::Global::GetDicts()->GetDefaultPubDict()->GetEntry(group, element);
248 // AttributeCombo->Clear();
251 AttributeCombo->Delete(0);
252 AttributeCombo->Insert(crea::std2wx(entry->GetName()), 0);
256 AttributeCombo->Delete(0);
257 AttributeCombo->Insert(_T("Unknown Attribute"),0);
259 AttributeCombo->SetSelection(0);
266 //////////////////////////////////////////////////////////
267 // determine values for own attributes //
268 // @param name : attribute's name //
269 // @param key : indicates key map or not //
271 //////////////////////////////////////////////////
272 std::string WxDescriptorPanel::OwnAttribute(const std::string name)
276 std::map<std::string, std::string>::iterator it_att = ownatt.begin();
277 for(; it_att != ownatt.end(); it_att++)
279 if(it_att->second == name)
281 result = it_att->first.c_str();
288 //////////////////////////////////////////////////////////
289 // Find a level in function of position in Return Ctrl //
292 //////////////////////////////////////////////////
293 std::string WxDescriptorPanel::findLevel()
298 ResultCtrl->PositionToXY( ResultCtrl->GetInsertionPoint(),&column, &line);
299 std::string tx(crea::wx2std(ResultCtrl->GetRange(0, ResultCtrl->XYToPosition(0,line+1))).c_str());
300 std::string::size_type level_pos_start = tx.rfind("|_");
301 if(level_pos_start == -1)
307 level_pos_start += 2;
310 std::string::size_type level_pos_end = tx.find_first_of("\n",level_pos_start);
311 return tx.substr(level_pos_start,level_pos_end - level_pos_start);
314 //////////////////////////////////////////////////////
316 // @param event : Wxevent //
318 //////////////////////////////////////////////////
319 void WxDescriptorPanel::OnRemove(wxCommandEvent& event)
326 pos_start = ResultCtrl->GetInsertionPoint();
327 ResultCtrl->PositionToXY( pos_start,&column, &line);
330 std::string name("root");
337 wxString text = ResultCtrl->GetLineText(line);
338 if ( text.Find(_T("|_")) == -1)
340 std::string level = findLevel();
341 // find GR and EL values to remove
342 std::string tx = crea::wx2std(text);
343 std::string::size_type EL_start_pos = tx.find_last_of(" ");
344 RemoveAttribute(level, tx.substr(EL_start_pos+1,tx.size() - EL_start_pos));
345 ResultCtrl->Remove( ResultCtrl->XYToPosition(0,line), ResultCtrl->XYToPosition(0,line+1));
349 RemoveLevel(crea::wx2std(text.AfterFirst('_')));
350 lv = text.Find(_T("|"))/3;
351 pos_start= ResultCtrl->XYToPosition(0,line-1);
352 ResultCtrl->SetInsertionPointEnd();
353 pos_end = ResultCtrl->GetInsertionPoint();
354 ResultCtrl->Remove(pos_start, pos_end);
359 //////////////////////////////////////////////
360 // create a descriptor structure //
361 // @param name : level's name to add //
362 // @return : boolean result //
363 //////////////////////////////////////////////////
364 void WxDescriptorPanel::CreateDescriptor(int type)
366 if(type == 0) // First initialization
369 outDscp += "<level>";
373 outDscp += "O Name Name 4";
380 outDscp += "O NumberOfChildren ";
381 outDscp += crea::wx2std(LevelCtrl->GetValue());
385 outDscp += "<level>";
387 outDscp += crea::wx2std(LevelCtrl->GetValue());
395 outDscp += crea::wx2std(GRCtrl->GetValue());
397 outDscp += crea::wx2std(ELCtrl->GetValue());
407 //////////////////////////////////////////////////////
409 // @param name : level's name to add //
410 // @return : boolean result //
411 //////////////////////////////////////////////////
412 bool WxDescriptorPanel::addLevel(const std::string &name)
415 std::map<std::string, std::vector <std::string> >::iterator it_tree = DscpTree.begin();
416 for (;it_tree != DscpTree.end(); it_tree++)
418 if(it_tree->first == name)
427 std::vector <std::string> branch;
428 DscpTree[name] = branch;
433 //////////////////////////////////////////////////////
435 // @param name : level's name to remove //
436 // @return : boolean result //
437 //////////////////////////////////////////////////
438 bool WxDescriptorPanel::RemoveLevel(const std::string &name)
440 bool bresult = false;
441 std::map<int, std::string>::iterator it_list= lvlist.begin();
442 for(; it_list != lvlist.end(); it_list++)
444 if(it_list->second == name)
449 std::map<int, std::string>::iterator it_list2 = it_list;
450 for(;it_list != lvlist.end(); it_list++)
452 std::map<std::string, std::vector <std::string> >::iterator it_tree = DscpTree.begin();
453 for (;it_tree != DscpTree.end(); it_tree++)
455 if(it_tree->first == name)
457 DscpTree.erase(it_tree);
462 lvlist.erase(it_list2, lvlist.end());
467 //////////////////////////////////////////////////////
468 // add an attribute in a level //
469 // @param level : level's name to add attribute //
470 // @param name : attribute's name //
471 // @return : boolean result //
472 //////////////////////////////////////////////////
473 bool WxDescriptorPanel::addAtribute(const std::string &level, const std::string &name)
476 std::map<std::string, std::vector <std::string> >::iterator it_tree = DscpTree.begin();
477 for (;it_tree != DscpTree.end(); it_tree++)
479 if (it_tree->first.c_str() == level)
481 std::vector<std::string>::iterator it_branch = it_tree->second.begin();
482 for(;it_branch != it_tree->second.end(); it_branch++)
484 if(it_branch->c_str() == name)
491 it_tree->second.push_back(name);
499 //////////////////////////////////////////////////////
500 // remove an attribute from a level //
501 // @param level : level's name to remove attribute //
502 // @param name : attribute's name //
503 // @return : boolean result //
504 //////////////////////////////////////////////////
505 bool WxDescriptorPanel::RemoveAttribute(const std::string &level, const std::string &name)
507 bool bresult = false;
508 std::map<std::string, std::vector <std::string> >::iterator it_tree = DscpTree.begin();
509 for (;it_tree != DscpTree.end(); it_tree++)
511 if(it_tree->first == level)
513 std::vector<std::string>::iterator it_branch = it_tree->second.begin();
514 cout << it_tree->second.size();
515 for(;it_branch != it_tree->second.end(); it_branch++)
517 if(it_branch->c_str() == name)
520 it_tree->second.erase(it_branch);
529 //////////////////////////////////////////////////
530 // create a new descriptor //
531 // @param event : WxEvent //
533 //////////////////////////////////////////////////
534 void WxDescriptorPanel::OnNew(wxCommandEvent &Event)
536 LevelCtrl->SetValue(_T("patient"));
542 //////////////////////////////////////////////////
543 // Load a descriptor file //
544 // @param event : WxEvent //
546 //////////////////////////////////////////////////
547 void WxDescriptorPanel::OnLoad(wxCommandEvent &Event)
549 long style = wxOPEN | wxFILE_MUST_EXIST;
550 LevelCtrl->SetValue(_T("patient"));
555 std::string wc("*.dscp");
556 wxFileDialog* FD = new wxFileDialog( 0,
558 crea::std2wx(m_path),
563 if (FD->ShowModal()==wxID_OK)
565 loadDescriptor(crea::wx2std(FD->GetPath()).c_str());
570 //////////////////////////////////////////////////
571 // Save a descriptor //
572 // @param event : WxEvent //
574 //////////////////////////////////////////////////
575 void WxDescriptorPanel::OnOK(wxCommandEvent &Event)
581 /////////////////////////////////////////////////////
582 // Save a descriptor and apply it (create a new DB//
583 // @param event : WxEvent //
585 /////////////////////////////////////////////////////
586 void WxDescriptorPanel::OnApply(wxCommandEvent &Event)
588 m_DscpFile = saveDescriptor();
590 SetReturnCode(ID_DSCP_APPLY);
593 const std::string WxDescriptorPanel::saveDescriptor()
595 std::string file = "";
597 std::string wc("*.dscp");
598 wxFileDialog* FD = new wxFileDialog( 0,
607 if (FD->ShowModal()==wxID_OK)
609 createDescriptorFile();
610 file = crea::wx2std(FD->GetPath()).c_str();
611 std::ofstream ofs(file.c_str());
619 ///////////////////////////////////////////////////////
621 // @param event : WxEvent //
623 ///////////////////////////////////////////////////////
625 void WxDescriptorPanel::OnCancel(wxCommandEvent& event)
629 ///////////////////////////////////////////////////////
630 // create a descriptor file //
633 ///////////////////////////////////////////////////////
634 void WxDescriptorPanel::createDescriptorFile()
638 outDscp += "<level>";
642 outDscp += "O Name Name 4";
644 std::map<std::string, std::vector <std::string> >::iterator it_tree = DscpTree.begin();
645 std::map<int, std::string >::iterator it_lv_nb = lvlist.begin();
646 std::map<int, std::string >::iterator it_lv = lvlist.begin();
648 for (;it_lv != lvlist.end(); it_lv++, it_lv_nb++)
652 outDscp += it_lv->second.c_str();
654 if(it_lv_nb != lvlist.end())
656 outDscp += "O NumberOfChildren ";
657 outDscp += it_lv_nb->second.c_str();
661 std::vector<std::string>::iterator it_branch = DscpTree[it_lv->second.c_str()].begin();
662 for(;it_branch != DscpTree[it_lv->second.c_str()].end(); it_branch++)
664 std::string att = it_branch->c_str();
665 if(att[0] == 'D' && att[7] == '_' && att.size() == 14)
668 outDscp += att.substr(1,6) + " "; // GR
669 outDscp += att.substr(8,6) + " ";// EL
676 outDscp += it_branch->c_str();
678 outDscp += ownatt[att];
689 ///////////////////////////////////////////////////////
690 // load a descriptor //
691 // @param i_name : file name to load //
693 /////////////////////////////////////////////////////
694 void WxDescriptorPanel::loadDescriptor(const std::string i_name)
696 std::ifstream i_file(i_name.c_str());
697 std::stringstream buffer;
698 buffer << i_file.rdbuf();
706 while(std::getline(buffer, line))
709 { //increment levels.
715 // For each level, a name to describe it
725 // split line to find all tags
726 std::vector<std::string> descriptors;
727 std::string separator = " ";
728 std::string::size_type last_pos = line.find_first_not_of(separator);
729 //find first separator
730 std::string::size_type pos = line.find_first_of(separator, last_pos);
731 while(std::string::npos != pos || std::string::npos != last_pos)
733 descriptors.push_back(line.substr(last_pos, pos - last_pos));
734 last_pos = line.find_first_not_of(separator, pos);
735 pos = line.find_first_of(separator, last_pos);
738 // By default, the last tag is at zero and not recorded but if take in count
739 unsigned int flag = 0;
740 if(descriptors.size() == 4)
742 std::stringstream val;
743 val << std::dec << descriptors[3];
747 // if Dicom tag, use "group" and "element" descriptor
748 if(descriptors[0] == "D")
749 { std::stringstream val, val2;
750 unsigned short group;
751 unsigned short element;
752 val << std::dec << descriptors[1] ;
753 val >> std::hex >> group;
754 val2 << std::dec << descriptors[2];
755 val2 >> std::hex >> element;
756 std::string compose = "D";
757 compose += descriptors[1];
759 compose += descriptors[2];
760 GDCM_NAME_SPACE::DictEntry* entry = GDCM_NAME_SPACE::Global::GetDicts()->GetDefaultPubDict()->GetEntry(group, element);
763 onAddAttribute( entry->GetName(),compose, level);
766 else // "O" means if user's own tag.
768 boost::algorithm::replace_all(descriptors[2],"_"," ");
769 if(ilevel>0 && descriptors[1] != "NumberOfChildren" )
771 onAddAttribute( descriptors[2].c_str(),descriptors[1].c_str(), level);
778 //======================================================================
780 //======================================================================
782 } // EO namespace creaImageIO