]> Creatis software - creaImageIO.git/blob - src/creaImageIOWxDescriptorPanel.cpp
Clean code
[creaImageIO.git] / src / creaImageIOWxDescriptorPanel.cpp
1 /*
2 # ---------------------------------------------------------------------
3 #
4 # Copyright (c) CREATIS (Centre de Recherche en Acquisition et Traitement de l'Image 
5 #                        pour la Santé)
6 # Authors : Eduardo Davila, Frederic Cervenansky, Claire Mouton
7 # Previous Authors : Laurent Guigues, Jean-Pierre Roux
8 # CreaTools website : www.creatis.insa-lyon.fr/site/fr/creatools_accueil
9 #
10 #  This software is governed by the CeCILL-B license under French law and 
11 #  abiding by the rules of distribution of free software. You can  use, 
12 #  modify and/ or redistribute the software under the terms of the CeCILL-B 
13 #  license as circulated by CEA, CNRS and INRIA at the following URL 
14 #  http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html 
15 #  or in the file LICENSE.txt.
16 #
17 #  As a counterpart to the access to the source code and  rights to copy,
18 #  modify and redistribute granted by the license, users are provided only
19 #  with a limited warranty  and the software's author,  the holder of the
20 #  economic rights,  and the successive licensors  have only  limited
21 #  liability. 
22 #
23 #  The fact that you are presently reading this means that you have had
24 #  knowledge of the CeCILL-B license and that you accept its terms.
25 # ------------------------------------------------------------------------
26 */
27
28
29 #include "creaImageIOWxDescriptorPanel.h"
30 #include <creaImageIOSystem.h>
31 #if defined(USE_GDCM)
32 #include <gdcmGlobal.h>
33 #include <gdcmDictSet.h>
34 #endif
35
36 #if defined(USE_GDCM2)
37 #include <gdcmGlobal.h>
38 #include <gdcmDicts.h>
39 #include <gdcmDict.h>
40 #endif
41 #include <boost/algorithm/string.hpp>
42
43 namespace creaImageIO
44 {
45   // CTor
46                    
47         WxDescriptorPanel::WxDescriptorPanel(wxWindow *parent, const std::string path)
48                 : wxDialog(parent, -1,_T("Descriptor Creation"), wxDefaultPosition, wxSize(550,550)) , m_path(path)
49 {
50
51   
52     GimmickDebugMessage(1,"WxDescriptorPanel::WxDescriptorPanel"
53                         <<std::endl);
54
55         lv = 0;
56         ownatt["FullFileName"]      = "Full_File_Name";
57         ownatt["FullFileDirectory"] = "Full_File_Directory";
58         
59
60         // START BUTTONS
61         wxButton *NewDescriptor = new wxButton(this, -1,_T("Create a new descriptor"), wxPoint(10,7) );
62         Connect( NewDescriptor->GetId(), wxEVT_COMMAND_BUTTON_CLICKED , (wxObjectEventFunction) &WxDescriptorPanel::OnNew ); 
63
64         wxButton *LoadDescriptor = new wxButton(this, -1,_T("Load a descriptor"), wxPoint(150,7) );
65         Connect( LoadDescriptor->GetId(), wxEVT_COMMAND_BUTTON_CLICKED , (wxObjectEventFunction) &WxDescriptorPanel::OnLoad ); 
66
67         /// \TODO fix warning: unused variable line1            
68         wxStaticLine *line1 = new wxStaticLine(this, -1, wxPoint(5,40), wxSize(540,2));
69
70         // LEVEL
71         /// \TODO fix warning: unused variable LevelText
72         wxStaticText * LevelText=new wxStaticText(this,-1,_T(" Level: "), wxPoint(5,50));
73         LevelCtrl=new wxTextCtrl(this, ID_GR_CTRL,_T("patient"), wxPoint(50,50), wxSize(50,25));
74         wxButton *addLevel = new wxButton(this, ID_LEVEL_ADD,_T("add a level"), wxPoint(150,50) );
75         Connect( addLevel->GetId(), wxEVT_COMMAND_BUTTON_CLICKED , (wxObjectEventFunction) &WxDescriptorPanel::OnAddLevel ); 
76
77         /// \TODO fix warning: unused variable line2
78         wxStaticLine *line2 = new wxStaticLine(this, -1, wxPoint(5,75), wxSize(540,2));
79
80         // ATTRIBUTES
81
82         /// \TODO fix warning: unused variable GR
83         wxStaticText * GR=new wxStaticText(this,-1,_T(" DICOM Group: "), wxPoint(5,110));
84         GRCtrl=new wxTextCtrl(this, ID_GR_CTRL,_T("0x0010"), wxPoint(82,110), wxSize(50,25));
85         Connect( GRCtrl->GetId(), wxEVT_COMMAND_TEXT_UPDATED , (wxObjectEventFunction) &WxDescriptorPanel::OnDicomAttribute ); 
86         
87         /// \TODO fix warning: unused variable EL
88         wxStaticText * EL=new wxStaticText(this,-1,_T(" DICOM Element: "), wxPoint(140,110));
89         ELCtrl=new wxTextCtrl(this, ID_EL_CTRL,_T("0x0010"), wxPoint(230,110), wxSize(50,25));
90         Connect( ELCtrl->GetId(), wxEVT_COMMAND_TEXT_UPDATED , (wxObjectEventFunction) &WxDescriptorPanel::OnDicomAttribute ); 
91
92         wxString choices[3];
93         choices[0] = _T("Unknow Attribute");
94         std::map<std::string, std::string>::iterator it_att =ownatt.begin();
95         for(int i = 1; it_att != ownatt.end(); it_att++, i++)
96         {
97                 choices[i] = crea::std2wx(it_att->second);
98         }
99         
100
101         AttributeCombo  = new wxComboBox(this, ID_ATTRIBUTE_CTRL,_T(""),wxPoint(300,110), wxSize(120,25),3,choices, wxCB_READONLY);
102         AttributeCombo->SetSelection(0);
103         
104
105         wxButton *addAttribute = new wxButton(this, ID_ATTRIBUTE_ADD,_T("add an attribute"), wxPoint(440,110) );
106         Connect( addAttribute->GetId(), wxEVT_COMMAND_BUTTON_CLICKED , (wxObjectEventFunction) &WxDescriptorPanel::OnAddAttribute ); 
107         /// \TODO fix warning: unused variable line3
108         wxStaticLine *line3 = new wxStaticLine(this, -1, wxPoint(5,140), wxSize(540,2));
109
110         // RESULT
111
112 //EED 2017-09-16 Migration wxWidgets 2.8 to 3.0
113 #if wxMAJOR_VERSION <= 2
114         ResultCtrl=new wxTextCtrl(this, ID_EL_CTRL,_T(""), wxPoint(5,150), wxSize(250,310), wxTE_READONLY| wxMac | wxTE_MULTILINE | wxTE_RICH );
115 #else
116         ResultCtrl=new wxTextCtrl(this, ID_EL_CTRL,_T(""), wxPoint(5,150), wxSize(250,310), wxTE_READONLY| wxTE_MULTILINE | wxTE_RICH );
117 #endif
118
119
120         wxButton *RemoveCtrl = new wxButton(this, ID_REMOVE_ADD,_T("Remove an entry"), wxPoint(280,200) );
121         Connect( RemoveCtrl->GetId(), wxEVT_COMMAND_BUTTON_CLICKED , (wxObjectEventFunction) &WxDescriptorPanel::OnRemove ); 
122
123         /// \TODO fix warning: unused variable line4
124         wxStaticLine *line4 = new wxStaticLine(this, -1, wxPoint(5,470), wxSize(540,2));
125         // VALIDATION BUTTON
126         wxButton *Ok = new wxButton(this, -1,_T("OK"), wxPoint(10,480) );
127         Connect( Ok->GetId(), wxEVT_COMMAND_BUTTON_CLICKED , (wxObjectEventFunction) &WxDescriptorPanel::OnOK ); 
128
129         wxButton *Apply = new wxButton(this, -1,_T("APPLY"), wxPoint(150,480) );
130         Connect( Apply->GetId(), wxEVT_COMMAND_BUTTON_CLICKED , (wxObjectEventFunction) &WxDescriptorPanel::OnApply ); 
131         
132         /// \TODO fix warning: unused variable Cancel
133         wxButton *Cancel = new wxButton(this, wxID_CANCEL,_T("CANCEL"), wxPoint(250,480) );
134 //      Connect( Cancel->GetId(), wxEVT_COMMAND_BUTTON_CLICKED , (wxCloseEvent) &wxWindow::Close ); 
135
136         Layout(); 
137         CreateDescriptor(0);
138   }
139
140   /// Destructor
141   WxDescriptorPanel::~WxDescriptorPanel()
142   {
143     GimmickDebugMessage(1,"WxCustomizeConfigPanel::~WxCustomizeConfigPanel"
144                         <<std::endl);
145   }
146
147     //////////////////////////////////////////////////////////
148   // Add an attribute  //
149   // @param event : Wxevent  //
150   // @return : -                                                  //
151   //////////////////////////////////////////////////
152   void WxDescriptorPanel::OnAddAttribute(wxCommandEvent& event)
153   {
154           std::string name_lv;
155           std::string name_att;
156           if (AttributeCombo->GetSelection() == 0)
157           {
158              name_att = "D" + crea::wx2std(GRCtrl->GetValue()) + "_" + crea::wx2std(ELCtrl->GetValue());
159           }
160           else
161           {     
162              wxString wd = AttributeCombo->GetValue();
163              std::string st = crea::wx2std(wd);
164              name_att = OwnAttribute(st);
165           }
166           onAddAttribute(crea::wx2std(AttributeCombo->GetValue()), name_att);
167   }
168   //////////////////////////////////////////////////////////
169   // add an attribute  //
170   // @param att :  attribute //
171   // @param name_att :  's name //
172   // @param level : level to add the attribute  //
173   // @return : -                                                  //
174   //////////////////////////////////////////////////
175   void WxDescriptorPanel::onAddAttribute( const std::string &att, const std::string &name_att,std::string level )
176   {
177           if(lv == 0)
178           {
179                   wxMessageBox(_T("Need a level first!"),crea::std2wx("WARNING"),wxOK,this);
180           }
181           else
182           {
183                 if( !att.empty() )
184                 {
185                 // Find Name of level
186                         if(level.empty())
187                         {
188                                 level = findLevel();
189                         }
190
191                         if (!addAtribute(level, name_att))
192                         {
193                                 wxMessageBox(_T("Attribute already used in this level"),crea::std2wx("WARNING"),wxOK,this);
194                         }
195                         else
196                         {
197                                 ResultCtrl->SetInsertionPoint(InsertPt);
198                 for (int i = 1; i<=lv;i++)
199                                 { 
200                                    ResultCtrl->WriteText(_T("   "));
201                                 }
202                                 ResultCtrl->WriteText(_T("| - "));
203                                 ResultCtrl->WriteText(crea::std2wx(att));
204                                 wxTextAttr ResultAttr(ResultCtrl->GetDefaultStyle());
205                                 ResultAttr.SetTextColour(*wxWHITE);
206                                 ResultCtrl->SetDefaultStyle(ResultAttr);
207                                 std::string text = " ";
208                                 ResultCtrl->WriteText(crea::std2wx(" " + name_att));
209                                 ResultAttr.SetTextColour(*wxBLACK);
210                                 ResultCtrl->SetDefaultStyle(ResultAttr);
211                                 ResultCtrl->WriteText(_T("\n"));
212                         }
213                         InsertPt = ResultCtrl->GetInsertionPoint();
214                 }
215           }
216   }
217   
218     //////////////////////////////////////////////////////////
219   // add a level //
220   // @param event : Wxevent  //
221   // @return : -                                                  //
222   //////////////////////////////////////////////////
223   void WxDescriptorPanel::OnAddLevel(wxCommandEvent& event)
224   {
225           if( !LevelCtrl->GetValue().IsEmpty() )
226           {
227                   onAddLevel(crea::wx2std(LevelCtrl->GetValue()));
228           }
229   }
230
231     //////////////////////////////////////////////////////////
232   // add a level  //
233   // @param level : level's name   //
234   // @return : -                                                  //
235   //////////////////////////////////////////////////
236   void WxDescriptorPanel::onAddLevel(const std::string &level)
237   {
238                   if(addLevel(level))
239                   {
240                           wxMessageBox(_T("Level already used"),crea::std2wx(("WARNING")),wxOK,this);
241                           return;
242                   }
243                   
244                    lv++;
245                    ResultCtrl->SetInsertionPoint(InsertPt);
246                    for (int i = 1; i<lv;i++)
247                    { 
248                            ResultCtrl->WriteText(_T("   "));
249                    }
250                    if(lv>1)
251                    {    ResultCtrl->WriteText(_T("| \n"));
252                                 for (int i = 1; i<lv;i++)
253                                 { 
254                                         ResultCtrl->WriteText(_T("   "));
255                                 }
256                                 ResultCtrl->WriteText(_T("|_"));
257                    }
258                    
259                         wxTextAttr ResultAttr(ResultCtrl->GetDefaultStyle());
260                         ResultAttr.SetTextColour(*wxRED);
261                         ResultCtrl->SetDefaultStyle(ResultAttr);
262                         ResultCtrl->WriteText(crea::std2wx(level));
263                         ResultAttr.SetTextColour(*wxBLACK);
264                         ResultCtrl->SetDefaultStyle(ResultAttr);
265                         ResultCtrl->WriteText(_T("\n"));
266                         InsertPt = ResultCtrl->GetInsertionPoint();
267           
268   }
269
270     //////////////////////////////////////////////////////////
271   // Find a DICOM attribute from group and element values //
272   // @param event : Wxevent  //
273   // @return : -                                                  //
274   //////////////////////////////////////////////////
275   void WxDescriptorPanel::OnDicomAttribute(wxCommandEvent& event)
276   {
277           //int i = 0;
278           if(!GRCtrl->GetValue().IsEmpty() && !ELCtrl->GetValue().IsEmpty() 
279                   && GRCtrl->GetValue().Len() == 6 && ELCtrl->GetValue().Len() == 6 && AttributeCombo->GetSelection() == 0)
280           {
281
282                   std::string gr = crea::wx2std(GRCtrl->GetValue());
283                   std::string el = crea::wx2std(ELCtrl->GetValue());
284                   std::stringstream val;
285         
286                   unsigned short group;
287                   unsigned short element;
288                   val <<   std::dec << gr ;
289                   val >> std::hex >> group;
290                   val.clear();
291                   val <<   std::dec << el ;
292                   val >> std::hex >> element;
293 #if defined(USE_GDCM)   
294                  // Retrieve the name from gdcm dict
295                   GDCM_NAME_SPACE::DictEntry* entry = GDCM_NAME_SPACE::Global::GetDicts()->GetDefaultPubDict()->GetEntry(group, element);
296                  // AttributeCombo->Clear();
297                   if(entry)
298                   {
299                           AttributeCombo->Delete(0);
300                           AttributeCombo->Insert(crea::std2wx(entry->GetName()), 0);
301                   }
302                   else
303                   {
304                           AttributeCombo->Delete(0);
305                           AttributeCombo->Insert(_T("Unknown Attribute"),0);
306                   }
307 #endif
308                           AttributeCombo->SetSelection(0);
309                 
310           }
311     
312   }
313
314
315    //////////////////////////////////////////////////////////
316   // determine values for own attributes //
317   // @param name : attribute's name  //
318   // @param key : indicates key map or not  //
319   // @return : -                                                  //
320   //////////////////////////////////////////////////
321   std::string WxDescriptorPanel::OwnAttribute(const std::string name)
322   {
323           std::string result;
324
325           std::map<std::string, std::string>::iterator it_att = ownatt.begin();
326           for(; it_att != ownatt.end(); it_att++)
327           {
328                   if(it_att->second == name)
329                   {
330                           result = it_att->first.c_str();
331                           break;
332                   }
333           }
334           return result;
335   }
336         
337   //////////////////////////////////////////////////////////
338   // Find a level in function of position in Return Ctrl  //
339   // @param - :   //
340   // @return : -                                                  //
341   //////////////////////////////////////////////////
342   std::string WxDescriptorPanel::findLevel()
343   {
344           long column;
345           long line;
346           
347           ResultCtrl->PositionToXY( ResultCtrl->GetInsertionPoint(),&column, &line);
348           std::string tx(crea::wx2std(ResultCtrl->GetRange(0, ResultCtrl->XYToPosition(0,line+1))).c_str());
349           std::string::size_type level_pos_start = tx.rfind("|_");
350           if(level_pos_start == -1)
351           {
352                   level_pos_start = 0;
353           }
354           else
355           {
356                   level_pos_start += 2;
357           }
358
359           std::string::size_type level_pos_end = tx.find_first_of("\n",level_pos_start);
360           return  tx.substr(level_pos_start,level_pos_end - level_pos_start);
361   }
362
363   //////////////////////////////////////////////////////
364   // Remove an item                               //
365   // @param event : Wxevent  //
366   // @return : -                                                  //
367   //////////////////////////////////////////////////
368   void WxDescriptorPanel::OnRemove(wxCommandEvent& event)
369   {
370           long line;
371           long column;
372           long pos_start;
373           long pos_end;
374
375           pos_start = ResultCtrl->GetInsertionPoint();
376           ResultCtrl->PositionToXY( pos_start,&column, &line);
377           if (line == 0) 
378           {
379                   std::string name("root");
380                   RemoveLevel(name);
381                   ResultCtrl->Clear();
382                   lv = 0;
383           }
384           else
385           {
386                 wxString text = ResultCtrl->GetLineText(line);
387                 if ( text.Find(_T("|_")) == -1)
388                 {
389                   std::string level = findLevel();
390                   // find GR and EL values to remove
391                   std::string tx = crea::wx2std(text);
392                   std::string::size_type  EL_start_pos = tx.find_last_of(" ");
393                   RemoveAttribute(level, tx.substr(EL_start_pos+1,tx.size() - EL_start_pos));
394                   ResultCtrl->Remove( ResultCtrl->XYToPosition(0,line), ResultCtrl->XYToPosition(0,line+1));
395                 }
396                 else
397                 {       
398                          RemoveLevel(crea::wx2std(text.AfterFirst('_')));
399                          lv = text.Find(_T("|"))/3;
400                          pos_start= ResultCtrl->XYToPosition(0,line-1);
401                          ResultCtrl->SetInsertionPointEnd();
402                          pos_end = ResultCtrl->GetInsertionPoint();
403                          ResultCtrl->Remove(pos_start, pos_end);
404                 }
405           }
406
407   }
408    //////////////////////////////////////////////
409   // create a descriptor structure               //
410   // @param name : level's name to add           //
411   // @return : boolean result                    //
412   //////////////////////////////////////////////////
413    void WxDescriptorPanel::CreateDescriptor(int type)
414    {
415            if(type == 0) // First initialization
416            {
417                    outDscp.clear();
418                    outDscp += "<level>";
419                    outDscp += "\n";
420                    outDscp += "root";
421                    outDscp += "\n";
422                    outDscp += "O Name Name 4";
423                    outDscp += "\n";
424            }
425            if(type == 1)
426            {
427                    if(lv > 1)
428                    {
429                         outDscp += "O NumberOfChildren ";
430                         outDscp += crea::wx2std(LevelCtrl->GetValue());
431                         outDscp += "s";
432                         outDscp += "\n";
433                    }
434                    outDscp += "<level>";
435                    outDscp += "\n";
436                    outDscp += crea::wx2std(LevelCtrl->GetValue());
437                    outDscp += "\n";
438                    
439            }
440            if(type == 2)
441            {
442                    outDscp += "D";
443                    outDscp += " ";
444                    outDscp += crea::wx2std(GRCtrl->GetValue());
445                    outDscp += " ";
446                    outDscp += crea::wx2std(ELCtrl->GetValue());
447                    outDscp += " ";
448                    outDscp += "3";
449                    outDscp += "\n";
450            }
451            
452
453    }
454
455
456   //////////////////////////////////////////////////////
457   // add a level                                  //
458   // @param name : level's name to add  //
459   // @return : boolean result                                             //
460   //////////////////////////////////////////////////
461    bool WxDescriptorPanel::addLevel(const std::string &name)
462    {
463            bool bfound = false;
464            std::map<std::string, std::vector <std::string> >::iterator it_tree = DscpTree.begin();
465            for (;it_tree != DscpTree.end(); it_tree++)
466            {
467                    if(it_tree->first == name)
468                    {
469                            bfound = true;
470                            break;
471                    }
472            }
473            if(!bfound)
474            {
475                     lvlist[lv] = name;
476                         std::vector <std::string> branch;
477                         DscpTree[name] = branch;
478            }
479                 return bfound;
480    }
481
482   //////////////////////////////////////////////////////
483   // remove a level                               //
484   // @param name : level's name to remove  //
485   // @return : boolean result                                             //
486   //////////////////////////////////////////////////
487    bool WxDescriptorPanel::RemoveLevel(const std::string &name)
488    {
489            bool bresult = false;
490            std::map<int, std::string>::iterator it_list= lvlist.begin();
491            for(; it_list != lvlist.end(); it_list++)
492            {
493                    if(it_list->second == name)
494                    {
495                            break;
496                    }
497            }
498            std::map<int, std::string>::iterator it_list2 = it_list;
499            for(;it_list != lvlist.end(); it_list++)
500            {
501                         std::map<std::string, std::vector <std::string> >::iterator it_tree = DscpTree.begin();
502                         for (;it_tree != DscpTree.end(); it_tree++)
503                         {       
504                                 if(it_tree->first == name)
505                                 {
506                                         DscpTree.erase(it_tree);
507                                         break;
508                                 }
509                         }
510            }
511            lvlist.erase(it_list2, lvlist.end());
512            return bresult;
513    }
514
515
516   //////////////////////////////////////////////////////
517   // add an attribute in a level                                  //
518   // @param level : level's name to add attribute  //
519   // @param name : attribute's name                                       //
520   // @return : boolean result                                             //
521   //////////////////////////////////////////////////
522    bool WxDescriptorPanel::addAtribute(const std::string &level, const std::string &name)
523    {
524            bool bresult = true;
525            std::map<std::string, std::vector <std::string> >::iterator it_tree = DscpTree.begin();
526            for (;it_tree != DscpTree.end(); it_tree++)
527            {
528                    if (it_tree->first.c_str() == level)
529                    {
530                            std::vector<std::string>::iterator it_branch = it_tree->second.begin();
531                            for(;it_branch != it_tree->second.end(); it_branch++)
532                            { 
533                                    if(it_branch->c_str() == name)
534                                    {
535                                            bresult = false;
536                                    }
537                            }
538                            if(bresult)
539                            {
540                                         it_tree->second.push_back(name);
541                                         break;
542                            }
543                    }
544            }
545            return bresult;
546    }
547
548   //////////////////////////////////////////////////////
549   // remove an attribute from a level                             //
550   // @param level : level's name to remove attribute  //
551   // @param name : attribute's name                                       //
552   // @return : boolean result                                             //
553   //////////////////////////////////////////////////
554    bool WxDescriptorPanel::RemoveAttribute(const std::string &level, const std::string &name)
555    {
556               bool bresult = false;
557            std::map<std::string, std::vector <std::string> >::iterator it_tree = DscpTree.begin();
558            for (;it_tree != DscpTree.end(); it_tree++)
559            {
560                    if(it_tree->first == level)
561                    {
562                            std::vector<std::string>::iterator it_branch = it_tree->second.begin();
563                            cout << it_tree->second.size();
564                            for(;it_branch != it_tree->second.end(); it_branch++)
565                            {
566                                    if(it_branch->c_str() == name)
567                                    {
568                                            bresult = true;
569                                            it_tree->second.erase(it_branch);
570                                            break;
571                                    }
572                            }
573                    }
574            }
575            return bresult;
576    }
577
578   //////////////////////////////////////////////////
579   // create a new descriptor                                    //
580   // @param event : WxEvent                                     //
581   // @return : -                                                //
582   //////////////////////////////////////////////////
583    void WxDescriptorPanel::OnNew(wxCommandEvent &Event)
584    {
585            LevelCtrl->SetValue(_T("patient"));
586            ResultCtrl->Clear();
587            DscpTree.clear();
588            lv = 0;
589    }
590
591   //////////////////////////////////////////////////
592   // Load a descriptor file                                             //
593   // @param event : WxEvent                                             //
594   // @return : -                                                        //
595   //////////////////////////////////////////////////
596    void WxDescriptorPanel::OnLoad(wxCommandEvent &Event)
597    {
598 //EED 2017-09-16 Migration wxWidgets 2.8 to 3.0
599 #if wxMAJOR_VERSION <= 2
600             long style = wxOPEN | wxFILE_MUST_EXIST;
601 #else
602             long style = wxFD_OPEN | wxFD_FILE_MUST_EXIST;
603 #endif
604            LevelCtrl->SetValue(_T("patient"));
605            ResultCtrl->Clear();
606            DscpTree.clear();
607            lv = 0;
608                 
609            std::string wc("*.dscp");
610            wxFileDialog* FD = new wxFileDialog( 0, 
611                                          _T("Select file"),
612                                          crea::std2wx(m_path),
613                                          _T(""),
614                                          crea::std2wx(wc),
615                                          style,
616                                          wxDefaultPosition);
617         if (FD->ShowModal()==wxID_OK)
618         {
619                 loadDescriptor(crea::wx2std(FD->GetPath()).c_str());
620         }
621         
622    }
623
624   //////////////////////////////////////////////////
625   // Save a descriptor                                                    //
626   // @param event : WxEvent                                               //
627   // @return : -                                                         //
628   //////////////////////////////////////////////////
629    void WxDescriptorPanel::OnOK(wxCommandEvent &Event)
630    {
631           saveDescriptor();
632           wxWindow::Close();
633    }
634    
635   /////////////////////////////////////////////////////
636   // Save a descriptor  and apply it (create a new DB//
637   // @param event : WxEvent                                             //
638   // @return : -                                                        //
639   /////////////////////////////////////////////////////
640    void WxDescriptorPanel::OnApply(wxCommandEvent &Event)
641    {
642                 m_DscpFile = saveDescriptor();
643                 wxWindow::Close();
644                 SetReturnCode(ID_DSCP_APPLY);
645    }
646
647    const std::string WxDescriptorPanel::saveDescriptor()
648    {
649            std::string file = "";
650 //EED 2017-09-16 Migration wxWidgets 2.8 to 3.0
651 #if wxMAJOR_VERSION <= 2
652                 long style = wxSAVE;
653 #else
654                 long style = wxFD_SAVE;
655 #endif
656                 std::string wc("*.dscp");
657                 wxFileDialog* FD = new wxFileDialog( 0, 
658                                                 _T("Select file"),
659                                                 _T(""),
660                                                 _T(""),
661                                                 crea::std2wx(wc),
662                                                 style,
663                                                 wxDefaultPosition);
664
665
666                 if (FD->ShowModal()==wxID_OK)
667                 {
668                         createDescriptorFile();
669                         file = crea::wx2std(FD->GetPath()).c_str();
670                         std::ofstream ofs(file.c_str());
671                         ofs.clear();
672                         ofs << outDscp;
673                         ofs.close();
674                 }
675                 return file.c_str();
676    }
677  
678    ///////////////////////////////////////////////////////
679    // Cancel action                                                             //
680    // @param event :    WxEvent                                                 //
681    // @return : -                                                               //
682    ///////////////////////////////////////////////////////
683
684    void WxDescriptorPanel::OnCancel(wxCommandEvent& event)
685    {
686    }
687    
688    ///////////////////////////////////////////////////////
689    // create  a descriptor      file                                            //
690    // @param - :                                                                //
691    // @return : -                                                               //
692    ///////////////////////////////////////////////////////
693    void WxDescriptorPanel::createDescriptorFile()
694    {
695                 
696                    outDscp.clear();
697                    outDscp += "<level>";
698                    outDscp += "\n";
699                    outDscp += "Root";
700                    outDscp += "\n";
701                    outDscp += "O Name Name 4";
702                    outDscp += "\n";
703                    std::map<std::string, std::vector <std::string> >::iterator it_tree = DscpTree.begin();
704                    std::map<int, std::string >::iterator it_lv_nb = lvlist.begin();
705                    std::map<int, std::string >::iterator it_lv = lvlist.begin();
706                    it_lv_nb++;
707                    for (;it_lv != lvlist.end(); it_lv++)
708                {
709                            outDscp +="<level>";
710                        outDscp += "\n";
711                            outDscp += it_lv->second.c_str();
712                              outDscp += "\n";
713                             if(it_lv_nb != lvlist.end())
714                            {
715                                    outDscp += "O NumberOfChildren ";
716                                    outDscp += it_lv_nb->second.c_str();
717                                    outDscp += "s";
718                                    outDscp += "\n";
719                                    it_lv_nb++;
720                            }
721                            std::vector<std::string>::iterator it_branch = DscpTree[it_lv->second.c_str()].begin();      
722                       for(;it_branch != DscpTree[it_lv->second.c_str()].end(); it_branch++)
723                           {      
724                                   std::string att = it_branch->c_str();
725                                   if(att[0] == 'D' && att[7] == '_' && att.size() == 14) 
726                                   {
727                                       outDscp += "D ";
728                                           outDscp += att.substr(1,6) + " "; // GR
729                                           outDscp += att.substr(8,6) + " ";// EL
730                                           outDscp += "3";
731                                           outDscp += "\n";
732                                   }
733                                   else
734                                   {
735                                           outDscp += "O ";
736                                           outDscp += it_branch->c_str();
737                                           outDscp += " ";
738                                           outDscp += ownatt[att];
739                                           outDscp += " ";
740                                           outDscp += "2";
741                                           outDscp += "\n";
742                                   }
743                           }
744
745                    }
746    }
747
748    
749    ///////////////////////////////////////////////////////
750    // load a descriptor                                                                 //
751    // @param i_name : file name to load                             //
752    // @return : -                                                                               //
753    /////////////////////////////////////////////////////
754    void WxDescriptorPanel::loadDescriptor(const std::string i_name)
755    {
756            std::ifstream i_file(i_name.c_str());
757            std::stringstream buffer;
758            buffer << i_file.rdbuf();
759            std::string line;
760            std::string level;
761
762 #if defined(USE_GDCM2)
763            const gdcm::Global& g = gdcm::Global::GetInstance(); // sum of all knowledge !
764            const gdcm::Dicts &dicts = g.GetDicts();
765            const gdcm::Dict &dict = dicts.GetPublicDict(); // Part 6
766 #endif
767           
768
769                 bool bname;
770                 int ilevel = -1;
771
772                 
773                 while(std::getline(buffer, line))
774                 {
775                         if(line =="<level>")
776                         {       //increment levels.
777                                 ilevel++;
778                                 bname = true;
779                         }
780                         else if(bname)
781                         {
782                                 // For each level, a name to describe it
783                                 level = line;
784                                 if(ilevel>0)
785                                 {
786                                         onAddLevel(level);
787                                 }
788                                 bname = false;
789                         }
790                         else
791                         { 
792                                 // split line to find all tags
793                                 std::vector<std::string> descriptors;
794                                 std::string separator = " ";
795                                 std::string::size_type last_pos = line.find_first_not_of(separator);
796                                 //find first separator
797                                 std::string::size_type pos = line.find_first_of(separator, last_pos);
798                                 while(std::string::npos != pos || std::string::npos != last_pos)
799                                 {
800                                         descriptors.push_back(line.substr(last_pos, pos - last_pos));
801                                         last_pos = line.find_first_not_of(separator, pos);
802                                         pos = line.find_first_of(separator, last_pos);
803                                 }
804                                 
805                                 // By default, the last tag is at zero and not recorded but if take in count
806                                 unsigned int flag = 0;
807                                 if(descriptors.size() == 4)
808                                 {
809                                         std::stringstream val;
810                                         val << std::dec << descriptors[3];
811                                         val>> flag;
812                                 }
813
814                                 // if Dicom tag, use "group" and "element" descriptor
815                                 if(descriptors[0] == "D")
816                                 {       std::stringstream val, val2;
817                                         unsigned short group;
818                                         unsigned short element;
819                                         val <<   std::dec << descriptors[1] ;
820                                         val >> std::hex >> group;
821                                         val2 << std::dec <<  descriptors[2];
822                                         val2 >> std::hex >> element;
823                                         std::string compose =  "D";
824                                         compose +=  descriptors[1];
825                                         compose += "_";
826                                         compose +=  descriptors[2];
827 #if defined(USE_GDCM)
828                                         GDCM_NAME_SPACE::DictEntry* entry = GDCM_NAME_SPACE::Global::GetDicts()->GetDefaultPubDict()->GetEntry(group, element);
829                                         if(ilevel>0)
830                                         {
831                                                 onAddAttribute( entry->GetName(),compose, level);
832                                         }
833 #endif
834
835 #if defined(USE_GDCM2)
836                                         gdcm::DictEntry dictentry =  dict.GetDictEntry(gdcm::Tag(group, element));
837                                         if(ilevel>0)
838                                         {
839                                                 onAddAttribute( dictentry.GetName(),compose, level);
840                                         }
841         
842
843 #endif
844                                 }
845                                 else if(descriptors[0].find("#") != -1)
846                                 {
847                                         // commented line continue to next line
848                                 }
849                                 else // "O" means if user's own tag.
850                                 {       
851                                         boost::algorithm::replace_all(descriptors[2],"_"," ");
852                                         if(ilevel>0 && descriptors[1] != "NumberOfChildren" )
853                                         {       
854                                                 onAddAttribute( descriptors[2].c_str(),descriptors[1].c_str(), level);
855                                         }
856                                 }
857                         }
858                 }
859    }
860    
861 //======================================================================
862   
863 //====================================================================== 
864
865 } // EO namespace creaImageIO
866
867