1 #include "creaImageIOWxDescriptorPanel.h"
2 #include <creaImageIOSystem.h>
3 #include <gdcmGlobal.h>
4 #include <gdcmDictSet.h>
11 WxDescriptorPanel::WxDescriptorPanel(wxWindow *parent, const std::string path)
12 : wxDialog(parent, -1,_T("Descriptor Creation"), wxDefaultPosition, wxSize(550,550)) , m_path(path)
16 GimmickDebugMessage(1,"WxDescriptorPanel::WxDescriptorPanel"
20 ownatt["FullFileName"] = "Full_File_Name";
21 ownatt["FullFileDirectory"] = "Full_File_Directory";
25 wxButton *NewDescriptor = new wxButton(this, -1,_T("Create a new descriptor"), wxPoint(10,7) );
26 Connect( NewDescriptor->GetId(), wxEVT_COMMAND_BUTTON_CLICKED , (wxObjectEventFunction) &WxDescriptorPanel::OnNew );
28 wxButton *LoadDescriptor = new wxButton(this, -1,_T("Load a descriptor"), wxPoint(150,7) );
29 Connect( LoadDescriptor->GetId(), wxEVT_COMMAND_BUTTON_CLICKED , (wxObjectEventFunction) &WxDescriptorPanel::OnLoad );
31 wxStaticLine *line1 = new wxStaticLine(this, -1, wxPoint(5,40), wxSize(540,2));
34 wxStaticText * LevelText=new wxStaticText(this,-1,_T(" Level: "), wxPoint(5,50));
35 LevelCtrl=new wxTextCtrl(this, ID_GR_CTRL,_T("patient"), wxPoint(50,50), wxSize(50,25));
36 wxButton *addLevel = new wxButton(this, ID_LEVEL_ADD,_T("add a level"), wxPoint(150,50) );
37 Connect( addLevel->GetId(), wxEVT_COMMAND_BUTTON_CLICKED , (wxObjectEventFunction) &WxDescriptorPanel::OnAddLevel );
39 wxStaticLine *line2 = new wxStaticLine(this, -1, wxPoint(5,75), wxSize(540,2));
43 wxStaticText * GR=new wxStaticText(this,-1,_T(" DICOM Group: "), wxPoint(5,110));
44 GRCtrl=new wxTextCtrl(this, ID_GR_CTRL,_T("0x0010"), wxPoint(82,110), wxSize(50,25));
45 Connect( GRCtrl->GetId(), wxEVT_COMMAND_TEXT_UPDATED , (wxObjectEventFunction) &WxDescriptorPanel::OnDicomAttribute );
47 wxStaticText * EL=new wxStaticText(this,-1,_T(" DICOM Element: "), wxPoint(140,110));
48 ELCtrl=new wxTextCtrl(this, ID_EL_CTRL,_T("0x0010"), wxPoint(230,110), wxSize(50,25));
49 Connect( ELCtrl->GetId(), wxEVT_COMMAND_TEXT_UPDATED , (wxObjectEventFunction) &WxDescriptorPanel::OnDicomAttribute );
53 choices[0] = _T("Unknow Attribute");
54 std::map<std::string, std::string>::iterator it_att =ownatt.begin();
55 for(int i = 1; it_att != ownatt.end(); it_att++, i++)
57 choices[i] = crea::std2wx(it_att->second);
61 AttributeCombo = new wxComboBox(this, ID_ATTRIBUTE_CTRL,_T(""),wxPoint(300,110), wxSize(120,25),3,choices, wxCB_READONLY);
62 AttributeCombo->SetSelection(0);
65 wxButton *addAttribute = new wxButton(this, ID_ATTRIBUTE_ADD,_T("add an attribute"), wxPoint(440,110) );
66 Connect( addAttribute->GetId(), wxEVT_COMMAND_BUTTON_CLICKED , (wxObjectEventFunction) &WxDescriptorPanel::OnAddAttribute );
68 wxStaticLine *line3 = new wxStaticLine(this, -1, wxPoint(5,140), wxSize(540,2));
72 ResultCtrl=new wxTextCtrl(this, ID_EL_CTRL,_T(""), wxPoint(5,150), wxSize(250,310), wxTE_READONLY| wxMac | wxTE_MULTILINE | wxTE_RICH );
73 wxButton *RemoveCtrl = new wxButton(this, ID_REMOVE_ADD,_T("Remove an entry"), wxPoint(280,200) );
74 Connect( RemoveCtrl->GetId(), wxEVT_COMMAND_BUTTON_CLICKED , (wxObjectEventFunction) &WxDescriptorPanel::OnRemove );
76 wxStaticLine *line4 = new wxStaticLine(this, -1, wxPoint(5,470), wxSize(540,2));
78 wxButton *Ok = new wxButton(this, -1,_T("OK"), wxPoint(10,480) );
79 Connect( Ok->GetId(), wxEVT_COMMAND_BUTTON_CLICKED , (wxObjectEventFunction) &WxDescriptorPanel::OnOK );
81 wxButton *Apply = new wxButton(this, -1,_T("APPLY"), wxPoint(150,480) );
82 Connect( Apply->GetId(), wxEVT_COMMAND_BUTTON_CLICKED , (wxObjectEventFunction) &WxDescriptorPanel::OnApply );
84 wxButton *Cancel = new wxButton(this, wxID_CANCEL,_T("CANCEL"), wxPoint(250,480) );
85 // Connect( Cancel->GetId(), wxEVT_COMMAND_BUTTON_CLICKED , (wxCloseEvent) &wxWindow::Close );
92 WxDescriptorPanel::~WxDescriptorPanel()
94 GimmickDebugMessage(1,"WxCustomizeConfigPanel::~WxCustomizeConfigPanel"
98 //////////////////////////////////////////////////////////
99 // Add an attribute //
100 // @param event : Wxevent //
102 //////////////////////////////////////////////////
103 void WxDescriptorPanel::OnAddAttribute(wxCommandEvent& event)
106 std::string name_att;
107 if (AttributeCombo->GetSelection() == 0)
109 name_att = "D" + GRCtrl->GetValue() + "_" + ELCtrl->GetValue();
112 { wxString wd = AttributeCombo->GetValue();
113 std::string st = crea::wx2std(wd);
114 name_att = OwnAttribute(st);
116 onAddAttribute(crea::wx2std(AttributeCombo->GetValue()), name_att);
118 //////////////////////////////////////////////////////////
119 // add an attribute //
120 // @param att : attribute //
121 // @param name_att : 's name //
122 // @param level : level to add the attribute //
124 //////////////////////////////////////////////////
125 void WxDescriptorPanel::onAddAttribute( const std::string &att, const std::string &name_att,std::string level )
129 wxMessageBox(_T("Need a level first!"),crea::std2wx("WARNING"),wxOK,this);
135 // Find Name of level
141 if (!addAtribute(level, name_att))
143 wxMessageBox(_T("Attribute already used in this level"),crea::std2wx("WARNING"),wxOK,this);
147 ResultCtrl->SetInsertionPoint(InsertPt);
148 for (int i = 1; i<=lv;i++)
150 ResultCtrl->WriteText(" ");
152 ResultCtrl->WriteText("| - ");
153 ResultCtrl->WriteText(att);
154 wxTextAttr ResultAttr(ResultCtrl->GetDefaultStyle());
155 ResultAttr.SetTextColour(*wxWHITE);
156 ResultCtrl->SetDefaultStyle(ResultAttr);
157 std::string text = " ";
158 ResultCtrl->WriteText(" " + name_att);
159 ResultAttr.SetTextColour(*wxBLACK);
160 ResultCtrl->SetDefaultStyle(ResultAttr);
161 ResultCtrl->WriteText("\n");
163 InsertPt = ResultCtrl->GetInsertionPoint();
168 //////////////////////////////////////////////////////////
170 // @param event : Wxevent //
172 //////////////////////////////////////////////////
173 void WxDescriptorPanel::OnAddLevel(wxCommandEvent& event)
175 if( !LevelCtrl->GetValue().IsEmpty() )
177 onAddLevel(crea::wx2std(LevelCtrl->GetValue()));
181 //////////////////////////////////////////////////////////
183 // @param level : level's name //
185 //////////////////////////////////////////////////
186 void WxDescriptorPanel::onAddLevel(const std::string &level)
188 if(addLevel(crea::wx2std(level)))
190 wxMessageBox(_T("Level already used"),crea::std2wx(("WARNING")),wxOK,this);
195 ResultCtrl->SetInsertionPoint(InsertPt);
196 for (int i = 1; i<lv;i++)
198 ResultCtrl->WriteText(" ");
201 { ResultCtrl->WriteText("| \n");
202 for (int i = 1; i<lv;i++)
204 ResultCtrl->WriteText(" ");
206 ResultCtrl->WriteText("|_");
209 wxTextAttr ResultAttr(ResultCtrl->GetDefaultStyle());
210 ResultAttr.SetTextColour(*wxRED);
211 ResultCtrl->SetDefaultStyle(ResultAttr);
212 ResultCtrl->WriteText(level);
213 ResultAttr.SetTextColour(*wxBLACK);
214 ResultCtrl->SetDefaultStyle(ResultAttr);
215 ResultCtrl->WriteText("\n");
216 InsertPt = ResultCtrl->GetInsertionPoint();
220 //////////////////////////////////////////////////////////
221 // Find a DICOM attribute from group and element values //
222 // @param event : Wxevent //
224 //////////////////////////////////////////////////
225 void WxDescriptorPanel::OnDicomAttribute(wxCommandEvent& event)
228 if(!GRCtrl->GetValue().IsEmpty() && !ELCtrl->GetValue().IsEmpty()
229 && GRCtrl->GetValue().Len() == 6 && ELCtrl->GetValue().Len() == 6 && AttributeCombo->GetSelection() == 0)
232 std::string gr = crea::wx2std(GRCtrl->GetValue());
233 std::string el = crea::wx2std(ELCtrl->GetValue());
234 std::stringstream val;
236 unsigned short group;
237 unsigned short element;
238 val << std::dec << gr ;
239 val >> std::hex >> group;
241 val << std::dec << el ;
242 val >> std::hex >> element;
244 // Retrieve the name from gdcm dict
245 GDCM_NAME_SPACE::DictEntry* entry = GDCM_NAME_SPACE::Global::GetDicts()->GetDefaultPubDict()->GetEntry(group, element);
246 // AttributeCombo->Clear();
249 AttributeCombo->Delete(0);
250 AttributeCombo->Insert(crea::std2wx(entry->GetName()), 0);
254 AttributeCombo->Delete(0);
255 AttributeCombo->Insert(_T("Unknown Attribute"),0);
257 AttributeCombo->SetSelection(0);
264 //////////////////////////////////////////////////////////
265 // determine values for own attributes //
266 // @param name : attribute's name //
267 // @param key : indicates key map or not //
269 //////////////////////////////////////////////////
270 std::string WxDescriptorPanel::OwnAttribute(const std::string name)
274 std::map<std::string, std::string>::iterator it_att = ownatt.begin();
275 for(; it_att != ownatt.end(); it_att++)
277 if(it_att->second == name)
279 result = it_att->first.c_str();
286 //////////////////////////////////////////////////////////
287 // Find a level in function of position in Return Ctrl //
290 //////////////////////////////////////////////////
291 std::string WxDescriptorPanel::findLevel()
296 ResultCtrl->PositionToXY( ResultCtrl->GetInsertionPoint(),&column, &line);
297 std::string tx(crea::wx2std(ResultCtrl->GetRange(0, ResultCtrl->XYToPosition(0,line+1))).c_str());
298 std::string::size_type level_pos_start = tx.rfind("|_");
299 if(level_pos_start == -1)
305 level_pos_start += 2;
308 std::string::size_type level_pos_end = tx.find_first_of("\n",level_pos_start);
309 return tx.substr(level_pos_start,level_pos_end - level_pos_start);
312 //////////////////////////////////////////////////////
314 // @param event : Wxevent //
316 //////////////////////////////////////////////////
317 void WxDescriptorPanel::OnRemove(wxCommandEvent& event)
324 pos_start = ResultCtrl->GetInsertionPoint();
325 ResultCtrl->PositionToXY( pos_start,&column, &line);
328 std::string name("root");
335 wxString text = ResultCtrl->GetLineText(line);
336 if ( text.Find("|_") == -1)
338 std::string level = findLevel();
339 // find GR and EL values to remove
340 std::string tx = crea::wx2std(text);
341 std::string::size_type EL_start_pos = tx.find_last_of(" ");
342 RemoveAttribute(level, tx.substr(EL_start_pos+1,tx.size() - EL_start_pos));
343 ResultCtrl->Remove( ResultCtrl->XYToPosition(0,line), ResultCtrl->XYToPosition(0,line+1));
347 RemoveLevel(crea::wx2std(text.AfterFirst('_')));
348 lv = text.Find("|")/3;
349 pos_start= ResultCtrl->XYToPosition(0,line-1);
350 ResultCtrl->SetInsertionPointEnd();
351 pos_end = ResultCtrl->GetInsertionPoint();
352 ResultCtrl->Remove(pos_start, pos_end);
357 //////////////////////////////////////////////////////
358 // create a descriptor structure //
359 // @param name : level's name to add //
360 // @return : boolean result //
361 //////////////////////////////////////////////////
362 void WxDescriptorPanel::CreateDescriptor(int type)
364 if(type == 0) // First initialization
367 outDscp += "<level>";
371 outDscp += "O Name Name 4";
378 outDscp += "O NumberOfChildren ";
379 outDscp += crea::wx2std(LevelCtrl->GetValue());
383 outDscp += "<level>";
385 outDscp += crea::wx2std(LevelCtrl->GetValue());
393 outDscp += crea::wx2std(GRCtrl->GetValue());
395 outDscp += crea::wx2std(ELCtrl->GetValue());
405 //////////////////////////////////////////////////////
407 // @param name : level's name to add //
408 // @return : boolean result //
409 //////////////////////////////////////////////////
410 bool WxDescriptorPanel::addLevel(const std::string &name)
413 std::map<std::string, std::vector <std::string> >::iterator it_tree = DscpTree.begin();
414 for (;it_tree != DscpTree.end(); it_tree++)
416 if(it_tree->first == name)
425 std::vector <std::string> branch;
426 DscpTree[name] = branch;
431 //////////////////////////////////////////////////////
433 // @param name : level's name to remove //
434 // @return : boolean result //
435 //////////////////////////////////////////////////
436 bool WxDescriptorPanel::RemoveLevel(const std::string &name)
438 bool bresult = false;
439 std::map<int, std::string>::iterator it_list= lvlist.begin();
440 for(; it_list != lvlist.end(); it_list++)
442 if(it_list->second == name)
447 std::map<int, std::string>::iterator it_list2 = it_list;
448 for(;it_list != lvlist.end(); it_list++)
450 std::map<std::string, std::vector <std::string> >::iterator it_tree = DscpTree.begin();
451 for (;it_tree != DscpTree.end(); it_tree++)
453 if(it_tree->first == name)
455 DscpTree.erase(it_tree);
460 lvlist.erase(it_list2, lvlist.end());
465 //////////////////////////////////////////////////////
466 // add an attribute in a level //
467 // @param level : level's name to add attribute //
468 // @param name : attribute's name //
469 // @return : boolean result //
470 //////////////////////////////////////////////////
471 bool WxDescriptorPanel::addAtribute(const std::string &level, const std::string &name)
474 std::map<std::string, std::vector <std::string> >::iterator it_tree = DscpTree.begin();
475 for (;it_tree != DscpTree.end(); it_tree++)
477 if (it_tree->first.c_str() == level)
479 std::vector<std::string>::iterator it_branch = it_tree->second.begin();
480 for(;it_branch != it_tree->second.end(); it_branch++)
482 if(it_branch->c_str() == name)
489 it_tree->second.push_back(name);
497 //////////////////////////////////////////////////////
498 // remove an attribute from a level //
499 // @param level : level's name to remove attribute //
500 // @param name : attribute's name //
501 // @return : boolean result //
502 //////////////////////////////////////////////////
503 bool WxDescriptorPanel::RemoveAttribute(const std::string &level, const std::string &name)
505 bool bresult = false;
506 std::map<std::string, std::vector <std::string> >::iterator it_tree = DscpTree.begin();
507 for (;it_tree != DscpTree.end(); it_tree++)
509 if(it_tree->first == level)
511 std::vector<std::string>::iterator it_branch = it_tree->second.begin();
512 cout << it_tree->second.size();
513 for(;it_branch != it_tree->second.end(); it_branch++)
515 if(it_branch->c_str() == name)
518 it_tree->second.erase(it_branch);
527 //////////////////////////////////////////////////
528 // create a new descriptor //
529 // @param event : WxEvent //
531 //////////////////////////////////////////////////
532 void WxDescriptorPanel::OnNew(wxCommandEvent &Event)
534 LevelCtrl->SetValue(_T("patient"));
540 //////////////////////////////////////////////////
541 // Load a descriptor file //
542 // @param event : WxEvent //
544 //////////////////////////////////////////////////
545 void WxDescriptorPanel::OnLoad(wxCommandEvent &Event)
547 long style = wxOPEN | wxFILE_MUST_EXIST;
548 LevelCtrl->SetValue(_T("patient"));
553 std::string wc("*.dscp");
554 wxFileDialog* FD = new wxFileDialog( 0,
556 crea::std2wx(m_path),
561 if (FD->ShowModal()==wxID_OK)
563 loadDescriptor(crea::wx2std(FD->GetPath()).c_str());
568 //////////////////////////////////////////////////
569 // Save a descriptor //
570 // @param event : WxEvent //
572 //////////////////////////////////////////////////
573 void WxDescriptorPanel::OnOK(wxCommandEvent &Event)
579 /////////////////////////////////////////////////////
580 // Save a descriptor and apply it (create a new DB//
581 // @param event : WxEvent //
583 /////////////////////////////////////////////////////
584 void WxDescriptorPanel::OnApply(wxCommandEvent &Event)
586 m_DscpFile = saveDescriptor();
588 SetReturnCode(ID_DSCP_APPLY);
591 const std::string WxDescriptorPanel::saveDescriptor()
593 std::string file = "";
595 std::string wc("*.dscp");
596 wxFileDialog* FD = new wxFileDialog( 0,
605 if (FD->ShowModal()==wxID_OK)
607 createDescriptorFile();
608 file = crea::wx2std(FD->GetPath()).c_str();
609 std::ofstream ofs(file.c_str());
617 ///////////////////////////////////////////////////////
619 // @param event : WxEvent //
621 ///////////////////////////////////////////////////////
623 void WxDescriptorPanel::OnCancel(wxCommandEvent& event)
627 ///////////////////////////////////////////////////////
628 // create a descriptor file //
631 ///////////////////////////////////////////////////////
632 void WxDescriptorPanel::createDescriptorFile()
636 outDscp += "<level>";
640 outDscp += "O Name Name 4";
642 std::map<std::string, std::vector <std::string> >::iterator it_tree = DscpTree.begin();
643 std::map<int, std::string >::iterator it_lv_nb = lvlist.begin();
644 std::map<int, std::string >::iterator it_lv = lvlist.begin();
646 for (;it_lv != lvlist.end(); it_lv++, it_lv_nb++)
650 outDscp += it_lv->second.c_str();
652 if(it_lv_nb != lvlist.end())
654 outDscp += "O NumberOfChildren ";
655 outDscp += it_lv_nb->second.c_str();
659 std::vector<std::string>::iterator it_branch = DscpTree[it_lv->second.c_str()].begin();
660 for(;it_branch != DscpTree[it_lv->second.c_str()].end(); it_branch++)
662 std::string att = it_branch->c_str();
663 if(att[0] == 'D' && att[7] == '_' && att.size() == 14)
666 outDscp += att.substr(1,6) + " "; // GR
667 outDscp += att.substr(8,6) + " ";// EL
674 outDscp += it_branch->c_str();
676 outDscp += ownatt[att];
687 ///////////////////////////////////////////////////////
688 // load a descriptor //
689 // @param i_name : file name to load //
691 /////////////////////////////////////////////////////
692 void WxDescriptorPanel::loadDescriptor(const std::string i_name)
694 std::ifstream i_file(i_name.c_str());
695 std::stringstream buffer;
696 buffer << i_file.rdbuf();
704 while(std::getline(buffer, line))
707 { //increment levels.
713 // For each level, a name to describe it
723 // split line to find all tags
724 std::vector<std::string> descriptors;
725 std::string separator = " ";
726 std::string::size_type last_pos = line.find_first_not_of(separator);
727 //find first separator
728 std::string::size_type pos = line.find_first_of(separator, last_pos);
729 while(std::string::npos != pos || std::string::npos != last_pos)
731 descriptors.push_back(line.substr(last_pos, pos - last_pos));
732 last_pos = line.find_first_not_of(separator, pos);
733 pos = line.find_first_of(separator, last_pos);
736 // By default, the last tag is at zero and not recorded but if take in count
737 unsigned int flag = 0;
738 if(descriptors.size() == 4)
740 std::stringstream val;
741 val << std::dec << descriptors[3];
745 // if Dicom tag, use "group" and "element" descriptor
746 if(descriptors[0] == "D")
747 { std::stringstream val, val2;
748 unsigned short group;
749 unsigned short element;
750 val << std::dec << descriptors[1] ;
751 val >> std::hex >> group;
752 val2 << std::dec << descriptors[2];
753 val2 >> std::hex >> element;
754 std::string compose = "D";
755 compose += descriptors[1];
757 compose += descriptors[2];
758 GDCM_NAME_SPACE::DictEntry* entry = GDCM_NAME_SPACE::Global::GetDicts()->GetDefaultPubDict()->GetEntry(group, element);
761 onAddAttribute( entry->GetName(),compose, level);
764 else // "O" means if user's own tag.
766 boost::algorithm::replace_all(descriptors[2],"_"," ");
767 if(ilevel>0 && descriptors[1] != "NumberOfChildren" )
769 onAddAttribute( descriptors[2].c_str(),descriptors[1].c_str(), level);
776 //======================================================================
778 //======================================================================
780 } // EO namespace creaImageIO