]> Creatis software - creaImageIO.git/blob - src2/creaImageIOWxGimmickView.cpp
Allow reading image files without name extention
[creaImageIO.git] / src2 / creaImageIOWxGimmickView.cpp
1 #include <creaImageIOWxGimmickView.h>
2 #include <creaImageIOWxTreeView.h>
3 #include <creaImageIOSystem.h>
4 #include <creaImageIOWxCustomizeConfigPanel.h>
5 #include <creaImageIOWxListenerPanel.h>
6 #include <creaImageIOWxEditFieldsPanel.h>
7 #include <creaImageIOWxAttributeSelectionPanel.h>
8 #include <creaImageIOWxPACSConnectionPanel.h>
9
10 using namespace crea;
11 // Icons
12 #include "icons/accept.xpm"
13 #include "icons/add.xpm"
14 #include "icons/folder-down.xpm"
15 #include "icons/page-down.xpm"
16 #include "icons/remove.xpm"
17 #include "icons/database-add.xpm"
18 #include "icons/create-database.xpm"
19 #include "icons/help.xpm"
20 #include "icons/synchronize.xpm"
21 #include "icons/settings.xpm"
22 #include "icons/tools.xpm"
23 //#include "icons/import.xpm"
24
25 #include <wx/imaglist.h>
26 #include <wx/popupwin.h>
27 #include<boost/filesystem/operations.hpp>
28 #if defined(BUILD_BRUKER)
29         #include "bruker2dicom.h"
30 #endif
31
32 namespace creaImageIO
33 {
34    
35   //======================================================================
36   // The ids of the different tools
37   enum
38     {
39           TOOL_CREATEDB_ID = 1,
40       TOOL_ADDFILES_ID = 2,
41       TOOL_ADDDIR_ID = 3,
42           TOOL_ADDDATABASE_ID = 4,
43       TOOL_REMOVE_ID = 5,
44           TOOL_SYNCHRONIZE_ID = 6,
45       TOOL_HELP_ID = 7,
46           TOOL_SETTINGS_ID = 8,
47           TOOL_TOOLS_ID = 9
48     };
49   //======================================================================
50
51   //================================================================
52   // 
53   const int icon_number = 11;
54   // Icon ids
55   typedef enum
56     {
57           Icon_create_database,
58       Icon_accept,
59       Icon_add,
60       Icon_folder_down,
61       Icon_page_down,
62           Icon_database_add,
63       Icon_remove,
64           Icon_synchronize,
65       Icon_help,
66           Icon_settings,
67       Icon_tools
68     }
69     icon_id;
70   //================================================================
71
72   //================================================================
73   /*
74   const icon_id Icon[5] = { Icon_Database,  
75                             Icon_Patient,
76                             Icon_Study,
77                             Icon_Series,
78                             Icon_Image };
79   */
80   //================================================================
81
82
83   //======================================================================
84   // CTor
85   WxGimmickView::WxGimmickView(Gimmick* gimmick,
86                                wxWindow *parent, 
87                                const wxWindowID id,
88                                const wxPoint& pos, const wxSize& size,
89                                int min_dim,
90                                    int max_dim,
91                                int number_of_threads)
92     : wxPanel(parent,id,pos,size),
93       GimmickView(gimmick, number_of_threads),
94       mProgressDialog(0),
95       mConstructed(false)
96   {
97     GimmickDebugMessage(1,"WxGimmickView::WxGimmickView"
98                         <<std::endl);
99     // Sets the current directory to the home dir
100     mCurrentDirectory =  std2wx(gimmick->GetHomeDirectory());
101
102      // Connect the AddProgress callback
103     gimmick->ConnectAddProgressObserver
104       ( boost::bind( &WxGimmickView::OnAddProgress , this, _1 ) );
105
106     // Create the list of icons (mIcon)
107     CreateIconList();
108
109     // Global sizer
110     wxBoxSizer  *sizer = new wxBoxSizer(wxVERTICAL);
111
112     // Create the tool bar
113     CreateToolBar(); 
114     sizer->Add( mToolBar ,0, wxGROW  ,0);
115
116     // Split part below toolbar into notebook for views and panel
117     // for preview, messages...
118     mSplitter = new wxSplitterWindow( this , -1);
119  
120    
121     // Notebook
122     mNotebook = new wxNotebook(mSplitter,
123                                -1,wxDefaultPosition, wxDefaultSize, 0);
124
125     //Gimmick
126     mGimmick=gimmick;
127
128       
129     mSelectionMaxDimension= max_dim;
130     mSelectionMinDimension= min_dim;
131     
132     // Create the views
133     CreateTreeViews();
134
135     // Bottom panel 
136     mBottomPanel = new wxPanel(mSplitter,-1);
137     
138           wxBoxSizer    *bottom_sizer = new wxBoxSizer(wxVERTICAL); //HORIZONTAL);
139     
140     
141     // Previewer
142     mViewer = new WxViewer(mBottomPanel, wxID_ANY, wxT("Gimmick! Viewer"),wxDefaultPosition, wxDefaultSize );
143         pointers.push_back(new ImagePointerHolder(GetDefaultImage()));
144         mViewer->SetImageVector(pointers);
145         mViewer->StartPlayer();
146
147
148     bottom_sizer->Add(mViewer,1,wxGROW,1);
149     //    mViewer->Show();
150
151           mText = new wxStaticText(mBottomPanel, wxID_ANY, wxT("Welcome to Gimmick!"));
152           bottom_sizer->Add(mText,0,wxGROW,0);
153
154           
155           
156     mBottomPanel->SetSizer(bottom_sizer);
157
158     // Splitting
159     int hsize = size.GetHeight();
160
161     int top_minsize = 450;
162     int bottom_minsize = 50;
163
164     mSplitter->SetMinimumPaneSize( bottom_minsize );
165     mSplitter->SplitHorizontally( mNotebook, mBottomPanel, 
166                                   top_minsize);
167
168     sizer->Add( mSplitter,1,wxGROW  ,0);
169
170         mProgressDialog=0;
171     SetSizer( sizer );     
172     SetAutoLayout(true);
173     Layout();
174         mListener=new Listener();
175         mListener->ConnectObserver(boost::bind( &WxGimmickView::OnDriveMount , this, _1 ) );
176         mListener->Create();
177         mListener->Run();
178         mListener->Pause();
179     
180     mConstructed = true;
181   }
182   //======================================================================
183
184   //======================================================================
185   /// Destructor
186   WxGimmickView::~WxGimmickView()
187   {
188         // stop the viewer before application exit.
189         mViewer->StopPlayer();
190     GimmickDebugMessage(1,"WxGimmickView::~WxGimmickView"
191                         <<std::endl);
192         if(mListener->IsAlive())
193         {
194          mListener->Delete();
195         }
196   }
197   //======================================================================
198   
199   //======================================================================
200   /// Creates the tool bar
201   void WxGimmickView::CreateToolBar()
202   {
203     long style = wxTB_HORIZONTAL | wxNO_BORDER | wxTB_TEXT;
204     mToolBar = new wxToolBar(this,-1,wxDefaultPosition,wxDefaultSize,
205                              style);
206
207         mToolAddFile = mToolBar->AddTool( TOOL_CREATEDB_ID, 
208                                       _T("Create database"),
209                                       mIcon->GetBitmap(Icon_create_database),
210                                       _T("Create DB from an Attributes Descriptor file")
211                                       );
212     mToolAddFile = mToolBar->AddTool( TOOL_ADDFILES_ID, 
213                                       _T("Add file(s)"),
214                                       mIcon->GetBitmap(Icon_page_down),
215                                       _T("Add one or more file to database")
216                                       );
217     mToolAddDir = mToolBar->AddTool( TOOL_ADDDIR_ID, 
218                                       _T("Add folder"),
219                                       mIcon->GetBitmap(Icon_folder_down),
220                                       _T("Add the content of a folder to database")
221                                       );
222         mToolAddDatabase = mToolBar->AddTool( TOOL_ADDDATABASE_ID, 
223                                       _T("Open database"),
224                                       mIcon->GetBitmap(Icon_database_add),
225                                       _T("Open a local or distant database")
226                                       );
227     mToolRemove = mToolBar->AddTool( TOOL_REMOVE_ID, 
228                                       _T("Remove"),
229                                       mIcon->GetBitmap(Icon_remove),
230                                       _T("Remove selected items")
231                                       );
232     mToolSynchronize = mToolBar->AddTool( TOOL_SYNCHRONIZE_ID, 
233                                       _T("Synchronize"),
234                                       mIcon->GetBitmap(Icon_synchronize),
235                                       _T("Synchronizes the database with disk")
236                                       );
237         mToolHelp = mToolBar->AddTool( TOOL_HELP_ID, 
238                                       _T("Help"),
239                                       mIcon->GetBitmap(Icon_help),
240                                       _T("Open help window")
241                                       );
242         mToolSettings = mToolBar->AddTool( TOOL_SETTINGS_ID, 
243                                       _T("System settings"),
244                                       mIcon->GetBitmap(Icon_settings),
245                                       _T("Allows the modification of various system settings")
246                                       );
247         mToolTools = mToolBar->AddTool( TOOL_TOOLS_ID, 
248                                       _T("Tools"),
249                                       mIcon->GetBitmap(Icon_tools),
250                                       _T("Applies tools to images")
251                                       );
252     //const wxBitmap& bitmap1, const wxString& shortHelpString = "", wxItemKind kind = wxITEM_NORMAL)
253
254     mToolBar->Realize();
255   }
256   //======================================================================
257
258  
259   //======================================================================
260   /// Create the tree view for TreeHandler provided
261   void WxGimmickView::CreateTreeView( TreeHandler* h)
262   {
263     std::string name(h->GetTree().GetAttribute("Name"));
264     GimmickMessage(2,"Creating the tree view for '"<<
265                    name<<"'"<<std::endl);
266     // Create the WxTreeView
267     WxTreeView* view = new WxTreeView(h,this,mNotebook,-1);
268
269     // TO DO : TEST THAT A VIEW WITH SAME NAME IS NOT
270     // ALREADY IN THE MAP
271     GetTreeViewMap()[name] = view;
272
273     // Add Notebook page
274     mNotebook->AddPage( view, crea::std2wx(name) );
275         
276   }
277
278   //======================================================================
279   void WxGimmickView::GetSelectedImages(std::vector<vtkImageData*>& s, int dim)
280   {
281         std::vector<std::string> files;
282         GetTreeViewMap()[crea::wx2std(mNotebook->GetPageText(mNotebook->GetSelection()))]->GetSelectedAsString(files);
283         ReadImagesNotThreaded(s,files,dim);
284   }
285   //======================================================================
286
287   //======================================================================
288   void WxGimmickView::GetSelectedFiles(std::vector<std::string>& s)
289   {
290         GetTreeViewMap()[crea::wx2std(mNotebook->GetPageText(mNotebook->GetSelection()))]->GetSelectedAsString(s);
291   }
292   //======================================================================
293
294   //======================================================================
295   void WxGimmickView::GetImages(int dim, 
296                                 const std::vector<std::string>& files, 
297                                 std::vector<vtkImageData*>& s)
298   {
299         ReadImagesNotThreaded(s,files,dim);
300   }
301   //======================================================================
302
303
304   //=================================================
305   void WxGimmickView::CreateIconList()
306   {
307     // Size of the icons;
308     int size = 16;
309
310     wxIcon icons[20];
311     // should correspond to Icon_xxx enum
312     icons[Icon_accept] = wxIcon(accept_xpm);
313     icons[Icon_add] = wxIcon(add_xpm);
314     icons[Icon_folder_down] = wxIcon(folder_down_xpm);
315     icons[Icon_page_down] = wxIcon(page_down_xpm);
316     icons[Icon_remove] = wxIcon(remove_xpm);
317     icons[Icon_database_add] = wxIcon(database_add_xpm);
318     icons[Icon_help] = wxIcon(help_xpm);
319         icons[Icon_synchronize] = wxIcon(synchronize_xpm);
320         icons[Icon_create_database] = wxIcon(create_database_xpm);
321         icons[Icon_settings] = wxIcon(settings_xpm);
322         icons[Icon_tools] = wxIcon(tools_xpm);
323
324     //   unsigned int NbIcons = 8;
325     // Make an image list containing small icons
326     mIcon = new wxImageList(size,size,true);
327     
328     // Make all icons the same size = size of the first one
329     int sizeOrig = icons[0].GetWidth();
330     for ( size_t i = 0; i < icon_number; i++ )
331       {
332         if ( size == sizeOrig )
333           {
334             mIcon->Add(icons[i]);
335           }
336         else
337           {
338             mIcon->Add(wxBitmap(wxBitmap(icons[i]).ConvertToImage().Rescale(size, size)));
339           }
340       }
341   }
342   //=================================================
343
344
345   //=================================================
346   void WxGimmickView::OnAddFiles(wxCommandEvent& event)
347   {
348     mViewer->StopPlayer();
349    long style = wxOPEN | wxFILE_MUST_EXIST | wxFD_MULTIPLE;
350     std::string wc("*");
351     wxFileDialog* FD = new wxFileDialog( 0, 
352                                          _T("Select file"),
353                                          _T(""),
354                                          _T(""),
355                                          crea::std2wx(wc),
356                                          style,
357                                          wxDefaultPosition);
358     
359     if (FD->ShowModal()==wxID_OK)
360       {
361         wxBusyCursor busy;
362
363         wxArrayString files;
364         FD->GetPaths(files);
365         unsigned int i;
366         std::vector<std::string> filenames;
367         for (i=0;i<files.GetCount();++i)
368         {
369           filenames.push_back(wx2std(files[i]));
370           GimmickMessage(2,"Adding File "<<files[i]<<"."<<std::endl);
371         }
372
373         mProgressDialog = 
374           new wxProgressDialog(_T("Adding file(s)"),
375                                _T(""),
376                                1000,
377                                this,
378                                wxPD_ELAPSED_TIME |
379                                //                              wxPD_ESTIMATED_TIME | 
380                                //                              wxPD_REMAINING_TIME |
381                                wxPD_CAN_ABORT );
382
383         // TO DO : select the current tree handler
384         mGimmick->AddFiles(crea::wx2std(mNotebook->GetPageText(mNotebook->GetSelection())),filenames);
385
386         mProgressDialog->Pulse(_T("Updating view..."));
387
388         UpdateTreeViewLevel(crea::wx2std(mNotebook->GetPageText(mNotebook->GetSelection())),1);
389         delete mProgressDialog;
390         DisplayAddSummary();    
391
392       }
393         mViewer->StartPlayer(); 
394   }
395   //=================================================
396
397   //=================================================
398   void WxGimmickView::OnAddDir(wxCommandEvent& event)
399   {
400     mViewer->StopPlayer();
401         std::string name = crea::wx2std(mNotebook->GetCurrentPage()->GetName());
402     long style = wxDD_DEFAULT_STYLE | wxDD_DIR_MUST_EXIST;
403     wxDirDialog* FD = 
404       new wxDirDialog( 0, 
405                        _T("Select directory"),
406                        mCurrentDirectory,
407                        style);
408     
409     if (FD->ShowModal()==wxID_OK)
410       {
411
412         
413                   std::string dirname = wx2std (FD->GetPath());
414                   bool recurse =  isNeedRecursive(dirname);
415                   if (recurse)
416                  {
417              recurse = wxMessageBox(_T("Recurse into sub-directories ?"),  _T("Scan directory"),         wxYES_NO,this ) == wxYES ? true : false;
418                  }
419                 
420                 wxBusyCursor busy;
421                 wxString title(_T("Adding directory"));
422                 if (recurse) 
423                 title = _T("Adding directory (recursive)");
424                 mProgressDialog = 
425                 new wxProgressDialog(_T("Adding directory"),
426                                         _T(""),
427                                         NumberFilesToAdd(dirname,recurse),
428                                         this,
429                                         wxPD_ELAPSED_TIME | 
430                                         wxPD_SMOOTH |
431                                         //                             wxPD_ESTIMATED_TIME | 
432                                         //                             wxPD_REMAINING_TIME |
433                                         wxPD_CAN_ABORT );
434                 
435                 mCurrentDirectory = FD->GetPath();  
436                 mGimmick->AddDir(crea::wx2std(mNotebook->GetPageText(mNotebook->GetSelection())),dirname,recurse);
437                 mProgressDialog->Pulse(_T("Updating view..."));
438                 
439                 UpdateTreeViewLevel(crea::wx2std(mNotebook->GetPageText(mNotebook->GetSelection())),1);
440                 delete mProgressDialog;
441                 DisplayAddSummary();
442
443           }
444     mViewer->StartPlayer();
445   }
446
447
448    //=================================================
449   // Determines number of files potentially to add to database
450    int WxGimmickView::NumberFilesToAdd(const std::string &dirpath, bool recursive)
451   {
452            int nb = 0;
453            if ( !boost::filesystem::exists( dirpath ) ) return nb;
454            boost::filesystem::directory_iterator end_itr; // default construction yields past-the-end
455            for ( boost::filesystem::directory_iterator itr( dirpath );  itr != end_itr;  ++itr )
456           {
457                 // If is directory & recurse : do recurse
458                 if ( boost::filesystem::is_directory(itr->status()) )
459                 {
460                         if (recursive) 
461                         {
462                                 nb += NumberFilesToAdd(itr->string(), recursive);
463                         }
464                 }
465                 else
466                 {
467                         nb++;
468                 }
469           }
470         return nb;
471
472   }
473
474     //=================================================
475    // Test a directory to know if contains sub-directory to analyze
476   bool WxGimmickView::isNeedRecursive(std::string i_name)
477   {
478       boost::filesystem::directory_iterator iter(i_name), end_iter;
479           bool bfindir = false;
480                   for(; iter != end_iter; ++iter)
481                   {
482                           if(boost::filesystem::is_directory(*iter))
483                           {
484                                   return true;
485                           }
486                   }
487                   return false;
488   }
489   //=================================================
490
491   //=================================================
492   void WxGimmickView::OnSelectionChange(const std::vector<tree::Node*>& sel, bool isSelection, int selection, bool needProcess)
493   {      
494     GimmickDebugMessage(5,
495                         "WxGimmickView::OnSelectionChange"
496                         <<std::endl);
497     wxBusyCursor busy;
498         bool valid=true;
499         
500         if(sel.size()==0)
501         {
502                 valid= ValidateSelected(NULL,
503                                 mSelectionMinDimension,
504                                 mSelectionMaxDimension );
505         }
506         else if(needProcess)
507         {
508                 ResetExtent();
509                 std::vector<tree::Node*>::const_iterator i;
510                 for(i=sel.begin();i!=sel.end()&&valid;++i)
511                 {
512                         valid= ValidateSelected((*i),
513                                 mSelectionMinDimension,
514                                 mSelectionMaxDimension );
515                 }
516         }
517         else if(isSelection)
518         {
519                 valid= ValidateSelected(sel.front(),
520                                 mSelectionMinDimension,
521                                 mSelectionMaxDimension );
522         }
523         else
524         {
525                 ResetExtent();
526                 std::vector<tree::Node*>::const_iterator i;
527                 for(i=sel.begin();i!=sel.end()&&valid;++i)
528                 {
529                         valid= ValidateSelected((*i),
530                                 mSelectionMinDimension,
531                                 mSelectionMaxDimension );
532                 }
533         }
534         mText->SetLabel(crea::std2wx(GetMessage()));
535     /*if(valid)
536       {
537         ReadImageThreaded(sel);
538       }
539     else
540       {
541                   ClearSelection();
542       }*/
543         ReadImageThreaded(sel);
544
545     
546    }
547
548   //==================================================
549
550   //==================================================
551   ///Reads Images (Threaded)
552   void WxGimmickView::ReadImageThreaded(const std::vector<tree::Node*>& sel)
553   {     
554    GimmickDebugMessage(5,
555                        "ReadImageThreaded"
556                        <<std::endl);
557    int maxprio = GetMaximalPriority();
558    int prio = maxprio + 2000;
559
560    if(sel.size()>0)
561    {
562    //First load the selected images
563    mCurImageItemToShow = sel.front();
564    pointers.clear();
565    int index = 0;
566    std::vector<tree::Node*>::const_iterator selected;
567    for(selected=sel.begin();selected!=sel.end();++selected)
568      {
569        GimmickDebugMessage(5,
570                            "Requesting image from selected "
571                            <<(*selected)->GetAttribute("FullFileName")
572                            <<std::endl);
573            ImagePointerHolder* ph=new ImagePointerHolder(GetDefaultImage());
574            pointers.push_back(ph);
575        RequestReading(*selected,prio,index,ph);
576        //       AddEntryToMap(*selected);
577        prio--;
578        index++;
579      }
580         mViewer->SetImageVector(pointers);
581         //Going up
582         prio = maxprio + 20;
583         std::vector<tree::Node*> up;
584         GetTreeViewMap()[crea::wx2std(mNotebook->GetPageText(mNotebook->GetSelection()))]->GetNodes(up,true);
585         std::vector<tree::Node*>::iterator iterUp;
586         for(iterUp=up.begin();iterUp!=up.end();++iterUp)
587         {
588                 GimmickDebugMessage(5,
589                                 "Requesting image from neighbors up "
590                                 <<(*iterUp)->GetAttribute("FullFileName")
591                                 <<std::endl);
592                 ImagePointerHolder* ph=new ImagePointerHolder(GetDefaultImage());
593                 RequestReading(*iterUp,prio,-1,ph);
594                 //              AddEntryToMap(*iterUp);
595                 prio--;
596                 if (prio == maxprio) break;
597         }
598
599         //Going down
600         prio = maxprio + 19;
601         std::vector<tree::Node*> down;
602         GetTreeViewMap()[crea::wx2std(mNotebook->GetPageText(mNotebook->GetSelection()))]->GetNodes(down,false);
603         std::vector<tree::Node*>::iterator iterDown;
604         for(iterDown=down.begin();iterDown!=down.end();++iterDown)
605         {
606                 GimmickDebugMessage(5,
607                                 "Requesting image from neighbors down "
608                                 <<(*iterDown)->GetAttribute("FullFileName")
609                                 <<std::endl);
610                 ImagePointerHolder* ph=new ImagePointerHolder(GetDefaultImage());
611                 RequestReading(*iterDown,prio,-1,ph);
612                 //              AddEntryToMap(*iterDown);
613                 prio--;
614                 if (prio == maxprio) break;
615         }
616    }
617    else
618    {
619            pointers.clear();
620            ImagePointerHolder* ph=new ImagePointerHolder(GetDefaultImage());
621            pointers.push_back(ph);
622            mViewer->SetImageVector(pointers);
623    }
624   }
625
626   //==================================================
627
628   //==================================================
629
630   //==================================================
631    void  WxGimmickView::OnInternalIdle()
632   {
633    if (!mConstructed) return;
634    static bool first_time = true;
635    if (false)
636    {
637         first_time = false;
638      }
639    //   GimmickMessage(1,"WxGimmickView : Refresh viewer"<<std::endl);
640         //  mViewer->StartPlayer();
641    if(mViewer)
642    {
643            mViewer->RefreshIfNecessary();
644    }
645   }
646
647    //==================================================
648
649   //==================================================
650    void  WxGimmickView::ClearSelection()
651   {
652         pointers.clear();
653         pointers.push_back(new ImagePointerHolder(GetDefaultImage()));
654         mViewer->SetImageVector(pointers);
655         mViewer->RefreshIfNecessary();
656         ResetExtent();
657   }
658   
659   //=================================================
660  
661   //=================================================
662   void WxGimmickView::OnRemove(wxCommandEvent& event)
663   {
664         //TODO Select current tree handler       
665     wxBusyCursor busy;
666     GetTreeViewMap()[crea::wx2std(mNotebook->GetPageText(mNotebook->GetSelection()))]->RemoveSelected();
667         ClearSelection();
668   }
669   //=================================================
670
671   
672   //=================================================
673   void WxGimmickView::AddIgnoreFile(tree::Node* toRemove)
674   {
675           mGimmick->RemoveFile(crea::wx2std(mNotebook->GetPageText(mNotebook->GetSelection())),toRemove);
676           GetTreeViewMap()[crea::wx2std(mNotebook->GetPageText(mNotebook->GetSelection()))]->UpdateLevel(1);
677   }
678
679   //=================================================
680   void WxGimmickView::CopyFiles(const std::vector<std::string>& filenames)
681   {
682           mGimmick->CopyFiles(filenames, crea::wx2std(mNotebook->GetPageText(mNotebook->GetSelection())));
683           wxMessageBox(std2wx("The selected files have been copied"),_T("Copy files"),wxOK,this);
684   }
685
686    //=================================================
687   void WxGimmickView::AddDir(std::string dirName)
688   {
689                 mProgressDialog = new wxProgressDialog(_T("Adding directory"),_T(""),1000,this,wxPD_ELAPSED_TIME |wxPD_CAN_ABORT );
690                 mCurrentDirectory = crea::std2wx(dirName);
691                 mGimmick->AddDir(crea::wx2std(mNotebook->GetPageText(mNotebook->GetSelection())),dirName,true);
692                 mProgressDialog->Pulse(_T("Updating view..."));
693                                                                         
694                 UpdateTreeViewLevel(crea::wx2std(mNotebook->GetPageText(mNotebook->GetSelection())),1);
695                 delete mProgressDialog;
696                 DisplayAddSummary();
697   }
698
699    //=================================================
700   void WxGimmickView::OnSynchronize(wxCommandEvent& event)
701   {       
702     wxBusyCursor busy;
703         const wxString choices[] = { _T("Check database for files deletion and addition and give a report."), 
704                                                                 _T("Check database for files deletion, addition and attributes change. Then give a report."), 
705                                                                 _T("Repair database (remove deleted files and add new files)."), 
706                                                                 _T("Repair database (remove deleted files, add new files and reset changed attributes).") } ;
707
708     wxSingleChoiceDialog dialog(this,
709                                                                 _T("Select one of the following synchronization actions:\n")
710                                 _T("Please note that, due to the heavy amount of operations required, this action might take a while."),
711                                 _T("Synchronization Settings"),
712                                 WXSIZEOF(choices), choices);
713
714     //dialog.SetSelection(0);
715
716     if (dialog.ShowModal() == wxID_OK)
717     {
718         int sel=dialog.GetSelection();
719                 bool repair=false;
720                 bool checkAttributes=false;
721                 if(sel==2 || sel==3){repair=true;}
722                 if(sel==1 || sel==3){checkAttributes=true;}
723                 std::string mess=mGimmick->Synchronize(crea::wx2std(mNotebook->GetPageText(mNotebook->GetSelection())),repair, checkAttributes);
724                 wxMessageBox(std2wx(mess),_T("Synchronization result"),wxOK,this);
725                 if(sel==2 || sel==3){
726                 GetTreeViewMap()[crea::wx2std(mNotebook->GetPageText(mNotebook->GetSelection()))]->UpdateLevel(1);
727                 }
728                 
729     }
730   }
731   //=================================================
732
733   //=================================================
734   void WxGimmickView::OnSettings(wxCommandEvent& event)
735   {
736     wxDialog* dial= new wxDialog (this,-1,_T("System Settings"),wxDefaultPosition, wxSize(450,220));
737     wxBoxSizer  *siz = new wxBoxSizer(wxVERTICAL);
738     // Notebook
739     wxNotebook* nb= new wxNotebook(dial, -1, wxDefaultPosition, wxDefaultSize, 0);
740     
741     siz->Add( nb,1,wxGROW  ,0);  
742     CreateSettingsDialog(nb,dial);
743     dial->SetSizer(siz);
744     dial->ShowModal();
745   }
746   //=================================================
747   void WxGimmickView::OnImportExport(wxCommandEvent &Event)
748   {
749         wxBusyCursor busy;
750         // Test if one image is selected => export
751         // if not =>import
752     if (GetTreeViewMap()[crea::wx2std(mNotebook->GetPageText(mNotebook->GetSelection()))])
753         {
754                 ExportImages();
755         }
756         else
757         {
758                 ImportImages();
759         }
760   }
761
762   void WxGimmickView::ExportImages()
763   {
764                 //Archive selection: name, emplacement
765                 //same process than copy local but to a zip
766                 // if settings are yes "always ask for descriptor addition", ask
767                 // if settings are yes, adding descriptor
768   }
769
770   void WxGimmickView::ImportImages()
771   {
772                 //Find the *.zip
773                 //dezip
774                 // Contain a descriptor.text
775                 // create a new database, and add to database
776                 // if not, add to current database
777                 // 
778   }
779
780   //=================================================
781   //AndresDonadio
782   void WxGimmickView::OnTools(wxCommandEvent& event)
783   {
784                 mViewer->StopPlayer();
785                 
786                 wxDialog* dial = new wxDialog (this,-1,_T("Tools"),wxDefaultPosition, wxSize(300,250));
787
788                 wxSizer* buttonsSizer = dial->CreateSeparatedButtonSizer(wxOK|wxCANCEL);
789                 wxNotebook* nb= new wxNotebook(dial, -1, wxDefaultPosition, wxDefaultSize, 0);
790
791                 wxBoxSizer *dialSizer = new wxBoxSizer(wxVERTICAL);     
792                 dialSizer->Add(nb,1,wxGROW,0);
793                 dialSizer->Add(buttonsSizer,0,wxGROW);
794
795 #if defined(BUILD_BRUKER)
796                         //First page: Bruker Image Reader
797                         WxGimmickTools * gimmickTools = new WxGimmickTools(nb, mCurrentDirectory);
798                         nb->AddPage( gimmickTools, _T("Bruker Image Reader") );
799 #endif
800
801                 dial->SetSizer(dialSizer, true);
802                 dial->Layout();
803                 dial->ShowModal();
804
805                 if (dial->GetReturnCode() == wxID_OK)
806                         {
807 #if defined(BUILD_BRUKER)
808                                         if (nb->GetSelection()==0)//Selection: Bruker Image Reader
809                                         {
810                                                 std::string inputDir = crea::wx2std(gimmickTools->getInputDir());
811                                                 std::string outputDir = crea::wx2std(gimmickTools->getOutputDir());
812                                                 bool addToDB = gimmickTools->getCheckBoxValue();
813
814                                                 if (inputDir.compare("")!=0 && outputDir.compare("")!=0)
815                                                 {
816                                                         if ( wxMessageBox(_T("Depending on the amount of Data the process can take between 1 and 5 minutes. Do you want to continue?"),
817                                                                         _T("Please confirm"), wxICON_QUESTION | wxYES_NO) == wxYES )
818                                                         {
819                                                                 Bruker2Dicom b2d;    
820                                                                 b2d.SetInputDirectory(inputDir);
821                                                                 b2d.SetOutputDirectory(outputDir);
822                                                                 b2d.SetConvertModeToDicom();
823                                                                 b2d.Execute();
824
825                                                                 if (addToDB)
826                                                                 {
827                                                                         mProgressDialog = new wxProgressDialog(_T("Adding directory"),_T(""),1000,this,wxPD_ELAPSED_TIME |wxPD_CAN_ABORT );
828                                                                         mCurrentDirectory = gimmickTools->getOutputDir();
829                                                                         mGimmick->AddDir(crea::wx2std(mNotebook->GetPageText(mNotebook->GetSelection())),outputDir,true);
830                                                                         mProgressDialog->Pulse(_T("Updating view..."));
831                                                                         
832                                                                         UpdateTreeViewLevel(crea::wx2std(mNotebook->GetPageText(mNotebook->GetSelection())),1);
833                                                                         delete mProgressDialog;
834                                                                         DisplayAddSummary();
835                                                                 }       
836                                                         }
837                                                 }
838
839                                                 else
840                                                 {
841                                                         wxMessageBox(_T("One or both of the directory fields are empty"),_T("Empty Fields"),wxOK,this);
842                                                 }
843                                 }
844                                         delete gimmickTools;
845 #endif
846                         }
847
848                 mViewer->StartPlayer();
849   }
850   //=================================================
851
852   void WxGimmickView::CreateSettingsDialog(wxNotebook* nb, wxDialog* dial)
853   {
854           //First page: Customization of configurations
855           //Copy Path string
856           std::string cp;
857           mGimmick->GetSetting(SETTINGS_COPY_PATH,cp);
858           //Database Path String
859           std::string dp;
860           mGimmick->GetSetting(SETTINGS_DBPATH,dp);
861           //Syncronization Event String
862           std::string se;
863           mGimmick->GetSetting(SETTINGS_SYNC_EVENT,se);
864           //Syncronization Frequency String
865           std::string sf;
866           mGimmick->GetSetting(SETTINGS_SYNC_FREQ,sf);
867
868           WxCustomizeConfigPanel * customConfig=new WxCustomizeConfigPanel(nb,dial,this,cp,dp,se,sf);
869
870           nb->AddPage( customConfig, crea::std2wx("Customize Configuration") );
871
872           //Second page: Creation of Databases
873           /*wxPanel* databaseCreation=new wxPanel(nb);
874           nb->AddPage( databaseCreation, crea::std2wx("Create Database") );*/
875
876           //Second page (temporary): Connection to PACS
877           WxPACSConnectionPanel* pacs=new WxPACSConnectionPanel(nb,dial, this);
878           nb->AddPage( pacs, crea::std2wx("Connect to PACS") );
879
880           //Third page: CD/DVD Watch
881           WxListenerPanel* cdWatch=new WxListenerPanel(nb,dial, this, mListener->IsPaused());
882           nb->AddPage( cdWatch, crea::std2wx("CD/DVD") );
883
884           //Fourth page: Selection of attributes to show
885           std::vector<std::string> shown;
886       std::vector<std::string> nShown;
887           GetTreeViewMap()[crea::wx2std(mNotebook->GetPageText(mNotebook->GetSelection()))]->GetAttributes(shown,nShown,1);
888           int nLev=GetTreeViewMap()[crea::wx2std(mNotebook->GetPageText(mNotebook->GetSelection()))]->GetNumberOfLevels();
889           WxAttributeSelectionPanel* attSelection=new WxAttributeSelectionPanel(nb,dial,this,shown,nShown,nLev);
890           nb->AddPage( attSelection, crea::std2wx("Selection of Attributes") );
891   }
892
893   //===================================================================
894   void WxGimmickView::GetVisibleAttributes(std::vector<std::string>& shown, 
895           std::vector<std::string>& nShown, int level)
896   {
897           GetTreeViewMap()[crea::wx2std(mNotebook->GetPageText(mNotebook->GetSelection()))]->GetAttributes(shown,nShown,level);
898   }
899
900   //===================================================================
901   void WxGimmickView::OnAttributesChanged(const std::vector<std::string>& nShown, int level)
902   {
903           GetTreeViewMap()[crea::wx2std(mNotebook->GetPageText(mNotebook->GetSelection()))]->SetNonVisibleAttributes(nShown,level);
904           std::vector<std::string> n=nShown;
905           GetTreeViewMap()[crea::wx2std(mNotebook->GetPageText(mNotebook->GetSelection()))]->CreateCtrl(n,level);
906   }
907   //===================================================================
908   void WxGimmickView::OnSaveSettingsCallback(const std::string& copyPath,
909           const std::string& dbPath,
910           const std::string& syncEvent,
911           const std::string& syncFreq)
912   {
913           mGimmick->UpdateSetting(SETTINGS_COPY_PATH,copyPath);
914           mGimmick->UpdateSetting(SETTINGS_DBPATH,dbPath);
915           mGimmick->UpdateSetting(SETTINGS_SYNC_EVENT,syncEvent);
916           mGimmick->UpdateSetting(SETTINGS_SYNC_FREQ,syncFreq);
917   }
918
919   //===================================================================
920   void WxGimmickView::OnListenerCallback(const std::string& drive, bool addFiles, bool removeFiles)
921   {
922          mListener->SetMonitoredDrive(drive);
923          mListener->SetAddFilesState(addFiles);
924          mListener->SetRemoveFilesState(removeFiles);
925   }
926
927   //========================================================================
928
929   void WxGimmickView::OnDriveMount(bool mount)
930   {
931           GimmickMessage(1, "Gimmick::OnDriveMount"<<std::endl);
932           std::string drive;
933           mListener->GetMonitoredDrive(drive);
934           
935           if(mount)
936           {
937                 mViewer->StopPlayer();
938                 wxBusyCursor busy;
939                 wxString title(_T("Adding drive"));
940                 mProgressDialog = 
941                 new wxProgressDialog(_T("Adding drive"),
942                                         _T(""),
943                                         1000,
944                                         this,
945                                         wxPD_ELAPSED_TIME |
946                                         //                             wxPD_ESTIMATED_TIME | 
947                                         //                             wxPD_REMAINING_TIME |
948                                         wxPD_CAN_ABORT );
949                 mCurrentDirectory = crea::std2wx(drive);
950                 mGimmick->AddDir(crea::wx2std(mNotebook->GetPageText(mNotebook->GetSelection())),drive,true);
951                 mProgressDialog->Pulse(_T("Updating view..."));
952                 
953                 UpdateTreeViewLevel(crea::wx2std(mNotebook->GetPageText(mNotebook->GetSelection())),1);
954                 delete mProgressDialog;
955                 DisplayAddSummary();
956                 mViewer->StartPlayer();
957                   
958           }
959           else
960           {  
961                   mGimmick->DeleteDrive(drive);
962                   UpdateTreeViewLevel(crea::wx2std(mNotebook->GetPageText(mNotebook->GetSelection())),1);
963           }
964          
965   }
966
967    //========================================================================
968
969   void WxGimmickView::StartListeningThread()
970   {
971           mListener->Resume();
972   }
973
974    //========================================================================
975
976   void WxGimmickView::StopListeningThread()
977   {
978           mListener->Pause();
979   }
980
981   //========================================================================
982   void WxGimmickView::CreateEditFieldsDialog(tree::Node* node, std::vector<std::string> names, std::vector<std::string> keys)
983   {
984           wxDialog* dial= new wxDialog (this,-1,crea::std2wx("Edit Fields for node "+node->GetLabel()),wxDefaultPosition, wxSize(350,155));
985     wxBoxSizer  *siz = new wxBoxSizer(wxVERTICAL);
986     WxEditFieldsPanel* ef = new WxEditFieldsPanel(dial, dial, this, node, names, keys);
987
988     siz->Add( ef,1,wxGROW  ,0); 
989     dial->SetSizer(siz);
990     dial->ShowModal();  
991   }
992
993   //========================================================================
994   void WxGimmickView::OnFieldsEdited(tree::Node* node, const std::string& name, const std::string& key, const std::string& val)
995   {
996           mGimmick->EditField(node, crea::wx2std(mNotebook->GetPageText(mNotebook->GetSelection())), name, key, val);
997           UpdateTreeViewLevel(crea::wx2std(mNotebook->GetPageText(mNotebook->GetSelection())),1);
998   }
999
1000   //=================================================
1001   /// AddProgress Gimmick callback
1002   void WxGimmickView::OnAddProgress( Gimmick::AddProgress& p)
1003   {
1004     char mess[200];
1005         sprintf(mess,"%i dirs : %i files :\n            %i handled - %i added",
1006            p.GetNumberScannedDirs(),
1007            p.GetNumberScannedFiles(),
1008            p.GetNumberHandledFiles(),
1009            p.GetNumberAddedFiles());
1010     //    std::cout << "OnAddProgress "<<mess<<std::endl;
1011     wxString s(wxString::From8BitData(mess));
1012     //  std::cout << "Pulse"<<std::endl;
1013     if (!mProgressDialog->Pulse(s)) 
1014       {
1015         p.SetStop();
1016       }
1017     //  std::cout << "OnAddProgress ok"<<std::endl;
1018   }
1019   //=================================================
1020
1021   //=================================================
1022   void WxGimmickView::DisplayAddSummary()
1023   {
1024     const Gimmick::AddProgress& p = mGimmick->GetAddProgress();
1025     std::stringstream mess;
1026     mess << "Dirs \tscanned\t: " << p.GetNumberScannedDirs()  << "\n";
1027     mess << "Files\tscanned\t: " << p.GetNumberScannedFiles() << "\n";
1028     mess << "Files\thandled\t: " << p.GetNumberHandledFiles() << "\n\n";
1029     mess << "Files\tadded  \t: " << p.GetNumberAddedFiles()   << "\n\n";
1030
1031     /*    char times[500];
1032     sprintf(times,"Time to parse dir \t\t: %ld ms \t%d°/o\nTime to read files info \t: %ld ms \t%d°/o\nTime to update structs \t: %ld ms \t%d°/o\nTime to update database \t: %ld ms \t%d°/o\nTotal time \t\t\t: %ld ms",
1033             summary.parse_time,
1034             (int)( summary.parse_time*100./summary.total_time),
1035             summary.file_scan_time,
1036             (int)(summary.file_scan_time*100./summary.total_time),
1037             summary.update_structs_time,
1038             (int)(summary.update_structs_time*100./summary.total_time),
1039             summary.update_database_time,
1040             (int)(summary.update_database_time*100./summary.total_time),
1041             summary.total_time );
1042     
1043     mess << times;
1044     */
1045     wxMessageBox(std2wx(mess.str()),_T("Addition result"),wxOK,this);
1046   }
1047
1048   //////////////////////////////////////////////////
1049   // Add a DB to application                                      //
1050   // @param event : WxEvent                                               //
1051   // @return : -                                                                  //
1052   //////////////////////////////////////////////////
1053   void WxGimmickView::OnAddDB(wxCommandEvent& event)
1054   {
1055     
1056           //Select DB
1057           long style = wxDD_DEFAULT_STYLE | wxDD_DIR_MUST_EXIST;
1058           std::string wc("*.sqlite3*");
1059           wxFileDialog* FD = new wxFileDialog( 0, 
1060                                          _T("Select file"),
1061                                          _T(""),
1062                                          _T(""),
1063                                          crea::std2wx(wc),
1064                                          style,
1065                                          wxDefaultPosition);
1066     
1067     if (FD->ShowModal()==wxID_OK)
1068         {
1069                 wxBusyCursor busy;
1070                 wxArrayString files;
1071                 FD->GetPaths(files);
1072                 std::stringstream st;
1073                 for(int i = 0; i< files.size(); i++)
1074                 {
1075                         //get name of DB (file name)
1076                   size_t pos = files[i].find_last_of(_T("\\"));
1077                   std::string name = crea::wx2std(files[i].substr(pos+1));
1078                   pos = name.find_last_of(".");
1079                   name = name.substr(0,pos);
1080                   //create TreeHandler
1081                   mGimmick->addDB(name, crea::wx2std(files[i]));
1082                   //create TreeView
1083                   CreateSingleTreeView(name);
1084                 }
1085         }
1086   }
1087     ////////////////////////////////////////////////////
1088   // Create a DB from an Attributes Descriptor files  //
1089   // @param event : WxEvent                                               //
1090   // @return : -                                                                  //
1091   //////////////////////////////////////////////////
1092   void WxGimmickView::OnCreateDB(wxCommandEvent& event)
1093   {
1094     
1095           //Select DB
1096           long style = wxDD_DEFAULT_STYLE | wxDD_DIR_MUST_EXIST;
1097           std::string wc("*.txt");
1098           wxFileDialog* FD = new wxFileDialog( 0, 
1099                                          _T("Select file"),
1100                                          _T(""),
1101                                          _T(""),
1102                                          crea::std2wx(wc),
1103                                          style,
1104                                          wxDefaultPosition);
1105     
1106     if (FD->ShowModal()==wxID_OK)
1107         {
1108                 wxBusyCursor busy;
1109                 wxArrayString afile;
1110                 FD->GetPaths(afile);
1111                 //get name of DB (file name)
1112                 std::string file = crea::wx2std(afile[0]);
1113                 size_t pos = file.find_last_of("\\");
1114                 std::string name = file.substr(pos+1);
1115                 std::string directory = file.substr(0,pos);
1116                 pos = name.find_last_of(".");
1117                 name = name.substr(0,pos);
1118                 //get directory to store DB
1119                 directory +=  "\\" + name + ".sqlite3";
1120                 //create createDB
1121                 mGimmick->createDB(name, file,directory);
1122                 //create TreeHandler
1123                 mGimmick->addDB(name, directory);
1124                 //create TreeView
1125                 CreateSingleTreeView(name);
1126         }
1127   }
1128
1129    //=================================================
1130
1131    //=================================================
1132   BEGIN_EVENT_TABLE(WxGimmickView, wxPanel)
1133     EVT_TOOL(TOOL_CREATEDB_ID, WxGimmickView::OnCreateDB)
1134     EVT_TOOL(TOOL_ADDFILES_ID, WxGimmickView::OnAddFiles)
1135     EVT_TOOL(TOOL_ADDDIR_ID, WxGimmickView::OnAddDir)
1136         EVT_TOOL(TOOL_ADDDATABASE_ID, WxGimmickView::OnAddDB)
1137         EVT_TOOL(TOOL_REMOVE_ID, WxGimmickView::OnRemove)
1138         EVT_TOOL(TOOL_SYNCHRONIZE_ID, WxGimmickView::OnSynchronize)
1139         EVT_TOOL(TOOL_SETTINGS_ID, WxGimmickView::OnSettings)
1140         EVT_TOOL(TOOL_TOOLS_ID, WxGimmickView::OnTools)
1141   END_EVENT_TABLE()
1142   //=================================================
1143
1144 } // EO namespace creaImageIO
1145
1146