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