]> Creatis software - creaImageIO.git/blob - src/creaImageIOWxDescriptorPanel.cpp
#3185 creaImageIO Feature New Normal - 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         ResultCtrl=new wxTextCtrl(this, ID_EL_CTRL,_T(""), wxPoint(5,150), wxSize(250,310), wxTE_READONLY| wxMac | wxTE_MULTILINE | wxTE_RICH );
113         wxButton *RemoveCtrl = new wxButton(this, ID_REMOVE_ADD,_T("Remove an entry"), wxPoint(280,200) );
114         Connect( RemoveCtrl->GetId(), wxEVT_COMMAND_BUTTON_CLICKED , (wxObjectEventFunction) &WxDescriptorPanel::OnRemove ); 
115
116         /// \TODO fix warning: unused variable line4
117         wxStaticLine *line4 = new wxStaticLine(this, -1, wxPoint(5,470), wxSize(540,2));
118         // VALIDATION BUTTON
119         wxButton *Ok = new wxButton(this, -1,_T("OK"), wxPoint(10,480) );
120         Connect( Ok->GetId(), wxEVT_COMMAND_BUTTON_CLICKED , (wxObjectEventFunction) &WxDescriptorPanel::OnOK ); 
121
122         wxButton *Apply = new wxButton(this, -1,_T("APPLY"), wxPoint(150,480) );
123         Connect( Apply->GetId(), wxEVT_COMMAND_BUTTON_CLICKED , (wxObjectEventFunction) &WxDescriptorPanel::OnApply ); 
124         
125         /// \TODO fix warning: unused variable Cancel
126         wxButton *Cancel = new wxButton(this, wxID_CANCEL,_T("CANCEL"), wxPoint(250,480) );
127 //      Connect( Cancel->GetId(), wxEVT_COMMAND_BUTTON_CLICKED , (wxCloseEvent) &wxWindow::Close ); 
128
129         Layout(); 
130         CreateDescriptor(0);
131   }
132
133   /// Destructor
134   WxDescriptorPanel::~WxDescriptorPanel()
135   {
136     GimmickDebugMessage(1,"WxCustomizeConfigPanel::~WxCustomizeConfigPanel"
137                         <<std::endl);
138   }
139
140     //////////////////////////////////////////////////////////
141   // Add an attribute  //
142   // @param event : Wxevent  //
143   // @return : -                                                  //
144   //////////////////////////////////////////////////
145   void WxDescriptorPanel::OnAddAttribute(wxCommandEvent& event)
146   {
147           std::string name_lv;
148           std::string name_att;
149           if (AttributeCombo->GetSelection() == 0)
150           {
151              name_att = "D" + crea::wx2std(GRCtrl->GetValue()) + "_" + crea::wx2std(ELCtrl->GetValue());
152           }
153           else
154           {     
155              wxString wd = AttributeCombo->GetValue();
156              std::string st = crea::wx2std(wd);
157              name_att = OwnAttribute(st);
158           }
159           onAddAttribute(crea::wx2std(AttributeCombo->GetValue()), name_att);
160   }
161   //////////////////////////////////////////////////////////
162   // add an attribute  //
163   // @param att :  attribute //
164   // @param name_att :  's name //
165   // @param level : level to add the attribute  //
166   // @return : -                                                  //
167   //////////////////////////////////////////////////
168   void WxDescriptorPanel::onAddAttribute( const std::string &att, const std::string &name_att,std::string level )
169   {
170           if(lv == 0)
171           {
172                   wxMessageBox(_T("Need a level first!"),crea::std2wx("WARNING"),wxOK,this);
173           }
174           else
175           {
176                 if( !att.empty() )
177                 {
178                 // Find Name of level
179                         if(level.empty())
180                         {
181                                 level = findLevel();
182                         }
183
184                         if (!addAtribute(level, name_att))
185                         {
186                                 wxMessageBox(_T("Attribute already used in this level"),crea::std2wx("WARNING"),wxOK,this);
187                         }
188                         else
189                         {
190                                 ResultCtrl->SetInsertionPoint(InsertPt);
191                 for (int i = 1; i<=lv;i++)
192                                 { 
193                                    ResultCtrl->WriteText(_T("   "));
194                                 }
195                                 ResultCtrl->WriteText(_T("| - "));
196                                 ResultCtrl->WriteText(crea::std2wx(att));
197                                 wxTextAttr ResultAttr(ResultCtrl->GetDefaultStyle());
198                                 ResultAttr.SetTextColour(*wxWHITE);
199                                 ResultCtrl->SetDefaultStyle(ResultAttr);
200                                 std::string text = " ";
201                                 ResultCtrl->WriteText(crea::std2wx(" " + name_att));
202                                 ResultAttr.SetTextColour(*wxBLACK);
203                                 ResultCtrl->SetDefaultStyle(ResultAttr);
204                                 ResultCtrl->WriteText(_T("\n"));
205                         }
206                         InsertPt = ResultCtrl->GetInsertionPoint();
207                 }
208           }
209   }
210   
211     //////////////////////////////////////////////////////////
212   // add a level //
213   // @param event : Wxevent  //
214   // @return : -                                                  //
215   //////////////////////////////////////////////////
216   void WxDescriptorPanel::OnAddLevel(wxCommandEvent& event)
217   {
218           if( !LevelCtrl->GetValue().IsEmpty() )
219           {
220                   onAddLevel(crea::wx2std(LevelCtrl->GetValue()));
221           }
222   }
223
224     //////////////////////////////////////////////////////////
225   // add a level  //
226   // @param level : level's name   //
227   // @return : -                                                  //
228   //////////////////////////////////////////////////
229   void WxDescriptorPanel::onAddLevel(const std::string &level)
230   {
231                   if(addLevel(level))
232                   {
233                           wxMessageBox(_T("Level already used"),crea::std2wx(("WARNING")),wxOK,this);
234                           return;
235                   }
236                   
237                    lv++;
238                    ResultCtrl->SetInsertionPoint(InsertPt);
239                    for (int i = 1; i<lv;i++)
240                    { 
241                            ResultCtrl->WriteText(_T("   "));
242                    }
243                    if(lv>1)
244                    {    ResultCtrl->WriteText(_T("| \n"));
245                                 for (int i = 1; i<lv;i++)
246                                 { 
247                                         ResultCtrl->WriteText(_T("   "));
248                                 }
249                                 ResultCtrl->WriteText(_T("|_"));
250                    }
251                    
252                         wxTextAttr ResultAttr(ResultCtrl->GetDefaultStyle());
253                         ResultAttr.SetTextColour(*wxRED);
254                         ResultCtrl->SetDefaultStyle(ResultAttr);
255                         ResultCtrl->WriteText(crea::std2wx(level));
256                         ResultAttr.SetTextColour(*wxBLACK);
257                         ResultCtrl->SetDefaultStyle(ResultAttr);
258                         ResultCtrl->WriteText(_T("\n"));
259                         InsertPt = ResultCtrl->GetInsertionPoint();
260           
261   }
262
263     //////////////////////////////////////////////////////////
264   // Find a DICOM attribute from group and element values //
265   // @param event : Wxevent  //
266   // @return : -                                                  //
267   //////////////////////////////////////////////////
268   void WxDescriptorPanel::OnDicomAttribute(wxCommandEvent& event)
269   {
270           //int i = 0;
271           if(!GRCtrl->GetValue().IsEmpty() && !ELCtrl->GetValue().IsEmpty() 
272                   && GRCtrl->GetValue().Len() == 6 && ELCtrl->GetValue().Len() == 6 && AttributeCombo->GetSelection() == 0)
273           {
274
275                   std::string gr = crea::wx2std(GRCtrl->GetValue());
276                   std::string el = crea::wx2std(ELCtrl->GetValue());
277                   std::stringstream val;
278         
279                   unsigned short group;
280                   unsigned short element;
281                   val <<   std::dec << gr ;
282                   val >> std::hex >> group;
283                   val.clear();
284                   val <<   std::dec << el ;
285                   val >> std::hex >> element;
286 #if defined(USE_GDCM)   
287                  // Retrieve the name from gdcm dict
288                   GDCM_NAME_SPACE::DictEntry* entry = GDCM_NAME_SPACE::Global::GetDicts()->GetDefaultPubDict()->GetEntry(group, element);
289                  // AttributeCombo->Clear();
290                   if(entry)
291                   {
292                           AttributeCombo->Delete(0);
293                           AttributeCombo->Insert(crea::std2wx(entry->GetName()), 0);
294                   }
295                   else
296                   {
297                           AttributeCombo->Delete(0);
298                           AttributeCombo->Insert(_T("Unknown Attribute"),0);
299                   }
300 #endif
301                           AttributeCombo->SetSelection(0);
302                 
303           }
304     
305   }
306
307
308    //////////////////////////////////////////////////////////
309   // determine values for own attributes //
310   // @param name : attribute's name  //
311   // @param key : indicates key map or not  //
312   // @return : -                                                  //
313   //////////////////////////////////////////////////
314   std::string WxDescriptorPanel::OwnAttribute(const std::string name)
315   {
316           std::string result;
317
318           std::map<std::string, std::string>::iterator it_att = ownatt.begin();
319           for(; it_att != ownatt.end(); it_att++)
320           {
321                   if(it_att->second == name)
322                   {
323                           result = it_att->first.c_str();
324                           break;
325                   }
326           }
327           return result;
328   }
329         
330   //////////////////////////////////////////////////////////
331   // Find a level in function of position in Return Ctrl  //
332   // @param - :   //
333   // @return : -                                                  //
334   //////////////////////////////////////////////////
335   std::string WxDescriptorPanel::findLevel()
336   {
337           long column;
338           long line;
339           
340           ResultCtrl->PositionToXY( ResultCtrl->GetInsertionPoint(),&column, &line);
341           std::string tx(crea::wx2std(ResultCtrl->GetRange(0, ResultCtrl->XYToPosition(0,line+1))).c_str());
342           std::string::size_type level_pos_start = tx.rfind("|_");
343           if(level_pos_start == -1)
344           {
345                   level_pos_start = 0;
346           }
347           else
348           {
349                   level_pos_start += 2;
350           }
351
352           std::string::size_type level_pos_end = tx.find_first_of("\n",level_pos_start);
353           return  tx.substr(level_pos_start,level_pos_end - level_pos_start);
354   }
355
356   //////////////////////////////////////////////////////
357   // Remove an item                               //
358   // @param event : Wxevent  //
359   // @return : -                                                  //
360   //////////////////////////////////////////////////
361   void WxDescriptorPanel::OnRemove(wxCommandEvent& event)
362   {
363           long line;
364           long column;
365           long pos_start;
366           long pos_end;
367
368           pos_start = ResultCtrl->GetInsertionPoint();
369           ResultCtrl->PositionToXY( pos_start,&column, &line);
370           if (line == 0) 
371           {
372                   std::string name("root");
373                   RemoveLevel(name);
374                   ResultCtrl->Clear();
375                   lv = 0;
376           }
377           else
378           {
379                 wxString text = ResultCtrl->GetLineText(line);
380                 if ( text.Find(_T("|_")) == -1)
381                 {
382                   std::string level = findLevel();
383                   // find GR and EL values to remove
384                   std::string tx = crea::wx2std(text);
385                   std::string::size_type  EL_start_pos = tx.find_last_of(" ");
386                   RemoveAttribute(level, tx.substr(EL_start_pos+1,tx.size() - EL_start_pos));
387                   ResultCtrl->Remove( ResultCtrl->XYToPosition(0,line), ResultCtrl->XYToPosition(0,line+1));
388                 }
389                 else
390                 {       
391                          RemoveLevel(crea::wx2std(text.AfterFirst('_')));
392                          lv = text.Find(_T("|"))/3;
393                          pos_start= ResultCtrl->XYToPosition(0,line-1);
394                          ResultCtrl->SetInsertionPointEnd();
395                          pos_end = ResultCtrl->GetInsertionPoint();
396                          ResultCtrl->Remove(pos_start, pos_end);
397                 }
398           }
399
400   }
401    //////////////////////////////////////////////
402   // create a descriptor structure               //
403   // @param name : level's name to add           //
404   // @return : boolean result                    //
405   //////////////////////////////////////////////////
406    void WxDescriptorPanel::CreateDescriptor(int type)
407    {
408            if(type == 0) // First initialization
409            {
410                    outDscp.clear();
411                    outDscp += "<level>";
412                    outDscp += "\n";
413                    outDscp += "root";
414                    outDscp += "\n";
415                    outDscp += "O Name Name 4";
416                    outDscp += "\n";
417            }
418            if(type == 1)
419            {
420                    if(lv > 1)
421                    {
422                         outDscp += "O NumberOfChildren ";
423                         outDscp += crea::wx2std(LevelCtrl->GetValue());
424                         outDscp += "s";
425                         outDscp += "\n";
426                    }
427                    outDscp += "<level>";
428                    outDscp += "\n";
429                    outDscp += crea::wx2std(LevelCtrl->GetValue());
430                    outDscp += "\n";
431                    
432            }
433            if(type == 2)
434            {
435                    outDscp += "D";
436                    outDscp += " ";
437                    outDscp += crea::wx2std(GRCtrl->GetValue());
438                    outDscp += " ";
439                    outDscp += crea::wx2std(ELCtrl->GetValue());
440                    outDscp += " ";
441                    outDscp += "3";
442                    outDscp += "\n";
443            }
444            
445
446    }
447
448
449   //////////////////////////////////////////////////////
450   // add a level                                  //
451   // @param name : level's name to add  //
452   // @return : boolean result                                             //
453   //////////////////////////////////////////////////
454    bool WxDescriptorPanel::addLevel(const std::string &name)
455    {
456            bool bfound = false;
457            std::map<std::string, std::vector <std::string> >::iterator it_tree = DscpTree.begin();
458            for (;it_tree != DscpTree.end(); it_tree++)
459            {
460                    if(it_tree->first == name)
461                    {
462                            bfound = true;
463                            break;
464                    }
465            }
466            if(!bfound)
467            {
468                     lvlist[lv] = name;
469                         std::vector <std::string> branch;
470                         DscpTree[name] = branch;
471            }
472                 return bfound;
473    }
474
475   //////////////////////////////////////////////////////
476   // remove a level                               //
477   // @param name : level's name to remove  //
478   // @return : boolean result                                             //
479   //////////////////////////////////////////////////
480    bool WxDescriptorPanel::RemoveLevel(const std::string &name)
481    {
482            bool bresult = false;
483            std::map<int, std::string>::iterator it_list= lvlist.begin();
484            for(; it_list != lvlist.end(); it_list++)
485            {
486                    if(it_list->second == name)
487                    {
488                            break;
489                    }
490            }
491            std::map<int, std::string>::iterator it_list2 = it_list;
492            for(;it_list != lvlist.end(); it_list++)
493            {
494                         std::map<std::string, std::vector <std::string> >::iterator it_tree = DscpTree.begin();
495                         for (;it_tree != DscpTree.end(); it_tree++)
496                         {       
497                                 if(it_tree->first == name)
498                                 {
499                                         DscpTree.erase(it_tree);
500                                         break;
501                                 }
502                         }
503            }
504            lvlist.erase(it_list2, lvlist.end());
505            return bresult;
506    }
507
508
509   //////////////////////////////////////////////////////
510   // add an attribute in a level                                  //
511   // @param level : level's name to add attribute  //
512   // @param name : attribute's name                                       //
513   // @return : boolean result                                             //
514   //////////////////////////////////////////////////
515    bool WxDescriptorPanel::addAtribute(const std::string &level, const std::string &name)
516    {
517            bool bresult = true;
518            std::map<std::string, std::vector <std::string> >::iterator it_tree = DscpTree.begin();
519            for (;it_tree != DscpTree.end(); it_tree++)
520            {
521                    if (it_tree->first.c_str() == level)
522                    {
523                            std::vector<std::string>::iterator it_branch = it_tree->second.begin();
524                            for(;it_branch != it_tree->second.end(); it_branch++)
525                            { 
526                                    if(it_branch->c_str() == name)
527                                    {
528                                            bresult = false;
529                                    }
530                            }
531                            if(bresult)
532                            {
533                                         it_tree->second.push_back(name);
534                                         break;
535                            }
536                    }
537            }
538            return bresult;
539    }
540
541   //////////////////////////////////////////////////////
542   // remove an attribute from a level                             //
543   // @param level : level's name to remove attribute  //
544   // @param name : attribute's name                                       //
545   // @return : boolean result                                             //
546   //////////////////////////////////////////////////
547    bool WxDescriptorPanel::RemoveAttribute(const std::string &level, const std::string &name)
548    {
549               bool bresult = false;
550            std::map<std::string, std::vector <std::string> >::iterator it_tree = DscpTree.begin();
551            for (;it_tree != DscpTree.end(); it_tree++)
552            {
553                    if(it_tree->first == level)
554                    {
555                            std::vector<std::string>::iterator it_branch = it_tree->second.begin();
556                            cout << it_tree->second.size();
557                            for(;it_branch != it_tree->second.end(); it_branch++)
558                            {
559                                    if(it_branch->c_str() == name)
560                                    {
561                                            bresult = true;
562                                            it_tree->second.erase(it_branch);
563                                            break;
564                                    }
565                            }
566                    }
567            }
568            return bresult;
569    }
570
571   //////////////////////////////////////////////////
572   // create a new descriptor                                    //
573   // @param event : WxEvent                                     //
574   // @return : -                                                //
575   //////////////////////////////////////////////////
576    void WxDescriptorPanel::OnNew(wxCommandEvent &Event)
577    {
578            LevelCtrl->SetValue(_T("patient"));
579            ResultCtrl->Clear();
580            DscpTree.clear();
581            lv = 0;
582    }
583
584   //////////////////////////////////////////////////
585   // Load a descriptor file                                             //
586   // @param event : WxEvent                                             //
587   // @return : -                                                        //
588   //////////////////////////////////////////////////
589    void WxDescriptorPanel::OnLoad(wxCommandEvent &Event)
590    {
591             long style = wxOPEN | wxFILE_MUST_EXIST;
592            LevelCtrl->SetValue(_T("patient"));
593            ResultCtrl->Clear();
594            DscpTree.clear();
595            lv = 0;
596                 
597            std::string wc("*.dscp");
598            wxFileDialog* FD = new wxFileDialog( 0, 
599                                          _T("Select file"),
600                                          crea::std2wx(m_path),
601                                          _T(""),
602                                          crea::std2wx(wc),
603                                          style,
604                                          wxDefaultPosition);
605         if (FD->ShowModal()==wxID_OK)
606         {
607                 loadDescriptor(crea::wx2std(FD->GetPath()).c_str());
608         }
609         
610    }
611
612   //////////////////////////////////////////////////
613   // Save a descriptor                                                    //
614   // @param event : WxEvent                                               //
615   // @return : -                                                         //
616   //////////////////////////////////////////////////
617    void WxDescriptorPanel::OnOK(wxCommandEvent &Event)
618    {
619           saveDescriptor();
620           wxWindow::Close();
621    }
622    
623   /////////////////////////////////////////////////////
624   // Save a descriptor  and apply it (create a new DB//
625   // @param event : WxEvent                                             //
626   // @return : -                                                        //
627   /////////////////////////////////////////////////////
628    void WxDescriptorPanel::OnApply(wxCommandEvent &Event)
629    {
630                 m_DscpFile = saveDescriptor();
631                 wxWindow::Close();
632                 SetReturnCode(ID_DSCP_APPLY);
633    }
634
635    const std::string WxDescriptorPanel::saveDescriptor()
636    {
637            std::string file = "";
638                 long style = wxSAVE;
639                 std::string wc("*.dscp");
640                 wxFileDialog* FD = new wxFileDialog( 0, 
641                                                 _T("Select file"),
642                                                 _T(""),
643                                                 _T(""),
644                                                 crea::std2wx(wc),
645                                                 style,
646                                                 wxDefaultPosition);
647
648
649                 if (FD->ShowModal()==wxID_OK)
650                 {
651                         createDescriptorFile();
652                         file = crea::wx2std(FD->GetPath()).c_str();
653                         std::ofstream ofs(file.c_str());
654                         ofs.clear();
655                         ofs << outDscp;
656                         ofs.close();
657                 }
658                 return file.c_str();
659    }
660  
661    ///////////////////////////////////////////////////////
662    // Cancel action                                                             //
663    // @param event :    WxEvent                                                 //
664    // @return : -                                                               //
665    ///////////////////////////////////////////////////////
666
667    void WxDescriptorPanel::OnCancel(wxCommandEvent& event)
668    {
669    }
670    
671    ///////////////////////////////////////////////////////
672    // create  a descriptor      file                                            //
673    // @param - :                                                                //
674    // @return : -                                                               //
675    ///////////////////////////////////////////////////////
676    void WxDescriptorPanel::createDescriptorFile()
677    {
678                 
679                    outDscp.clear();
680                    outDscp += "<level>";
681                    outDscp += "\n";
682                    outDscp += "Root";
683                    outDscp += "\n";
684                    outDscp += "O Name Name 4";
685                    outDscp += "\n";
686                    std::map<std::string, std::vector <std::string> >::iterator it_tree = DscpTree.begin();
687                    std::map<int, std::string >::iterator it_lv_nb = lvlist.begin();
688                    std::map<int, std::string >::iterator it_lv = lvlist.begin();
689                    it_lv_nb++;
690                    for (;it_lv != lvlist.end(); it_lv++)
691                {
692                            outDscp +="<level>";
693                        outDscp += "\n";
694                            outDscp += it_lv->second.c_str();
695                              outDscp += "\n";
696                             if(it_lv_nb != lvlist.end())
697                            {
698                                    outDscp += "O NumberOfChildren ";
699                                    outDscp += it_lv_nb->second.c_str();
700                                    outDscp += "s";
701                                    outDscp += "\n";
702                                    it_lv_nb++;
703                            }
704                            std::vector<std::string>::iterator it_branch = DscpTree[it_lv->second.c_str()].begin();      
705                       for(;it_branch != DscpTree[it_lv->second.c_str()].end(); it_branch++)
706                           {      
707                                   std::string att = it_branch->c_str();
708                                   if(att[0] == 'D' && att[7] == '_' && att.size() == 14) 
709                                   {
710                                       outDscp += "D ";
711                                           outDscp += att.substr(1,6) + " "; // GR
712                                           outDscp += att.substr(8,6) + " ";// EL
713                                           outDscp += "3";
714                                           outDscp += "\n";
715                                   }
716                                   else
717                                   {
718                                           outDscp += "O ";
719                                           outDscp += it_branch->c_str();
720                                           outDscp += " ";
721                                           outDscp += ownatt[att];
722                                           outDscp += " ";
723                                           outDscp += "2";
724                                           outDscp += "\n";
725                                   }
726                           }
727
728                    }
729    }
730
731    
732    ///////////////////////////////////////////////////////
733    // load a descriptor                                                                 //
734    // @param i_name : file name to load                             //
735    // @return : -                                                                               //
736    /////////////////////////////////////////////////////
737    void WxDescriptorPanel::loadDescriptor(const std::string i_name)
738    {
739            std::ifstream i_file(i_name.c_str());
740            std::stringstream buffer;
741            buffer << i_file.rdbuf();
742            std::string line;
743            std::string level;
744
745 #if defined(USE_GDCM2)
746            const gdcm::Global& g = gdcm::Global::GetInstance(); // sum of all knowledge !
747            const gdcm::Dicts &dicts = g.GetDicts();
748            const gdcm::Dict &dict = dicts.GetPublicDict(); // Part 6
749 #endif
750           
751
752                 bool bname;
753                 int ilevel = -1;
754
755                 
756                 while(std::getline(buffer, line))
757                 {
758                         if(line =="<level>")
759                         {       //increment levels.
760                                 ilevel++;
761                                 bname = true;
762                         }
763                         else if(bname)
764                         {
765                                 // For each level, a name to describe it
766                                 level = line;
767                                 if(ilevel>0)
768                                 {
769                                         onAddLevel(level);
770                                 }
771                                 bname = false;
772                         }
773                         else
774                         { 
775                                 // split line to find all tags
776                                 std::vector<std::string> descriptors;
777                                 std::string separator = " ";
778                                 std::string::size_type last_pos = line.find_first_not_of(separator);
779                                 //find first separator
780                                 std::string::size_type pos = line.find_first_of(separator, last_pos);
781                                 while(std::string::npos != pos || std::string::npos != last_pos)
782                                 {
783                                         descriptors.push_back(line.substr(last_pos, pos - last_pos));
784                                         last_pos = line.find_first_not_of(separator, pos);
785                                         pos = line.find_first_of(separator, last_pos);
786                                 }
787                                 
788                                 // By default, the last tag is at zero and not recorded but if take in count
789                                 unsigned int flag = 0;
790                                 if(descriptors.size() == 4)
791                                 {
792                                         std::stringstream val;
793                                         val << std::dec << descriptors[3];
794                                         val>> flag;
795                                 }
796
797                                 // if Dicom tag, use "group" and "element" descriptor
798                                 if(descriptors[0] == "D")
799                                 {       std::stringstream val, val2;
800                                         unsigned short group;
801                                         unsigned short element;
802                                         val <<   std::dec << descriptors[1] ;
803                                         val >> std::hex >> group;
804                                         val2 << std::dec <<  descriptors[2];
805                                         val2 >> std::hex >> element;
806                                         std::string compose =  "D";
807                                         compose +=  descriptors[1];
808                                         compose += "_";
809                                         compose +=  descriptors[2];
810 #if defined(USE_GDCM)
811                                         GDCM_NAME_SPACE::DictEntry* entry = GDCM_NAME_SPACE::Global::GetDicts()->GetDefaultPubDict()->GetEntry(group, element);
812                                         if(ilevel>0)
813                                         {
814                                                 onAddAttribute( entry->GetName(),compose, level);
815                                         }
816 #endif
817
818 #if defined(USE_GDCM2)
819                                         gdcm::DictEntry dictentry =  dict.GetDictEntry(gdcm::Tag(group, element));
820                                         if(ilevel>0)
821                                         {
822                                                 onAddAttribute( dictentry.GetName(),compose, level);
823                                         }
824         
825
826 #endif
827                                 }
828                                 else if(descriptors[0].find("#") != -1)
829                                 {
830                                         // commented line continue to next line
831                                 }
832                                 else // "O" means if user's own tag.
833                                 {       
834                                         boost::algorithm::replace_all(descriptors[2],"_"," ");
835                                         if(ilevel>0 && descriptors[1] != "NumberOfChildren" )
836                                         {       
837                                                 onAddAttribute( descriptors[2].c_str(),descriptors[1].c_str(), level);
838                                         }
839                                 }
840                         }
841                 }
842    }
843    
844 //======================================================================
845   
846 //====================================================================== 
847
848 } // EO namespace creaImageIO
849
850