]> Creatis software - creaImageIO.git/blob - src2/creaImageIOWxGimmickView.cpp
Added synchronization
[creaImageIO.git] / src2 / creaImageIOWxGimmickView.cpp
1 #include <creaImageIOWxGimmickView.h>
2 #include <creaImageIOWxTreeView.h>
3 #include <creaImageIOSystem.h>
4 using namespace crea;
5 // Icons
6 #include "icons/accept.xpm"
7 #include "icons/add.xpm"
8 #include "icons/folder-down.xpm"
9 #include "icons/page-down.xpm"
10 #include "icons/remove.xpm"
11 #include "icons/database-add.xpm"
12 #include "icons/help.xpm"
13 #include "icons/synchronize.xpm"
14
15 #include <wx/imaglist.h>
16 #include <wx/popupwin.h>
17 #include<boost/filesystem/operations.hpp>
18
19 namespace creaImageIO
20 {
21    
22   //======================================================================
23   // The ids of the different tools
24   enum
25     {
26       TOOL_ADDFILES_ID = 1,
27       TOOL_ADDDIR_ID = 2,
28       TOOL_REMOVE_ID = 3,
29       TOOL_ADDDATABASE_ID = 4,
30       TOOL_HELP_ID = 5,
31           TOOL_SYNCHRONIZE_ID = 6
32     };
33   //======================================================================
34
35   //================================================================
36   // 
37   const int icon_number = 8;
38   // Icon ids
39   typedef enum
40     {
41       Icon_accept,
42       Icon_add,
43       Icon_folder_down,
44       Icon_page_down,
45       Icon_remove,
46       Icon_database_add,
47       Icon_help,
48           Icon_synchronize
49     }
50     icon_id;
51   //================================================================
52
53   //================================================================
54   /*
55   const icon_id Icon[5] = { Icon_Database,  
56                             Icon_Patient,
57                             Icon_Study,
58                             Icon_Series,
59                             Icon_Image };
60   */
61   //================================================================
62
63
64   //======================================================================
65   // CTor
66   WxGimmickView::WxGimmickView(Gimmick* gimmick,
67                                wxWindow *parent, 
68                                const wxWindowID id,
69                                const wxPoint& pos, const wxSize& size,
70                                int min_dim,
71                                    int max_dim,
72                                int number_of_threads)
73     : wxPanel(parent,id,pos,size),
74       GimmickView(gimmick, number_of_threads),
75       mProgressDialog(0),
76       mConstructed(false)
77   {
78     GimmickDebugMessage(1,"WxGimmickView::WxGimmickView"
79                         <<std::endl);
80     // Sets the current directory to the home dir
81     mCurrentDirectory =  std2wx(gimmick->GetHomeDirectory());
82
83      // Connect the AddProgress callback
84     gimmick->ConnectAddProgressObserver
85       ( boost::bind( &WxGimmickView::OnAddProgress , this, _1 ) );
86
87     // Create the list of icons (mIcon)
88     CreateIconList();
89
90     // Global sizer
91     wxBoxSizer  *sizer = new wxBoxSizer(wxVERTICAL);
92
93     // Create the tool bar
94     CreateToolBar(); 
95     sizer->Add( mToolBar ,0, wxGROW  ,0);
96
97     // Split part below toolbar into notebook for views and panel
98     // for preview, messages...
99     mSplitter = new wxSplitterWindow( this , -1);
100  
101    
102     // Notebook
103     mNotebook = new wxNotebook(mSplitter,
104                                -1,wxDefaultPosition, wxDefaultSize, 0);
105
106     //Gimmick
107     mGimmick=gimmick;
108
109       
110     mSelectionMaxDimension= max_dim;
111     mSelectionMinDimension= min_dim;
112     
113     // Create the views
114     CreateTreeViews();
115
116     // Bottom panel 
117     mBottomPanel = new wxPanel(mSplitter,-1);
118     
119           wxBoxSizer    *bottom_sizer = new wxBoxSizer(wxVERTICAL); //HORIZONTAL);
120     
121     
122     // Previewer
123     mViewer = new WxViewer(mBottomPanel, wxID_ANY, wxT("Gimmick! Viewer"),wxDefaultPosition, wxDefaultSize );
124         pointers.push_back(new ImagePointerHolder(GetDefaultImage()));
125         mViewer->SetImageVector(pointers);
126         mViewer->StartPlayer();
127
128
129     bottom_sizer->Add(mViewer,1,wxGROW,1);
130     //    mViewer->Show();
131
132           mText = new wxStaticText(mBottomPanel, wxID_ANY, wxT("Welcome to Gimmick!"));
133           bottom_sizer->Add(mText,0,wxGROW,0);
134
135           
136           
137     mBottomPanel->SetSizer(bottom_sizer);
138
139     // Splitting
140     int hsize = size.GetHeight();
141
142     int top_minsize = 450;
143     int bottom_minsize = 50;
144
145     mSplitter->SetMinimumPaneSize( bottom_minsize );
146     mSplitter->SplitHorizontally( mNotebook, mBottomPanel, 
147                                   top_minsize);
148
149     sizer->Add( mSplitter,1,wxGROW  ,0);
150
151
152     SetSizer( sizer );     
153     SetAutoLayout(true);
154     Layout();
155     
156     mConstructed = true;
157   }
158   //======================================================================
159
160   //======================================================================
161   /// Destructor
162   WxGimmickView::~WxGimmickView()
163   {
164         // stop the viewer before application exit.
165         mViewer->StopPlayer();
166     GimmickDebugMessage(1,"WxGimmickView::~WxGimmickView"
167                         <<std::endl);
168   }
169   //======================================================================
170   
171   //======================================================================
172   /// Creates the tool bar
173   void WxGimmickView::CreateToolBar()
174   {
175     long style = wxTB_HORIZONTAL | wxNO_BORDER | wxTB_TEXT;
176     mToolBar = new wxToolBar(this,-1,wxDefaultPosition,wxDefaultSize,
177                              style);
178
179     mToolAddFile = mToolBar->AddTool( TOOL_ADDFILES_ID, 
180                                       _T("Add file(s)"),
181                                       mIcon->GetBitmap(Icon_page_down),
182                                       _T("Add one or more file to database")
183                                       );
184     mToolAddDir = mToolBar->AddTool( TOOL_ADDDIR_ID, 
185                                       _T("Add folder"),
186                                       mIcon->GetBitmap(Icon_folder_down),
187                                       _T("Add the content of a folder to database")
188                                       );
189     mToolRemove = mToolBar->AddTool( TOOL_REMOVE_ID, 
190                                       _T("Remove"),
191                                       mIcon->GetBitmap(Icon_remove),
192                                       _T("Remove selected items")
193                                       );
194     mToolAddDatabase = mToolBar->AddTool( TOOL_ADDDATABASE_ID, 
195                                       _T("Open database"),
196                                       mIcon->GetBitmap(Icon_database_add),
197                                       _T("Open a local or distant database")
198                                       );
199     mToolHelp = mToolBar->AddTool( TOOL_HELP_ID, 
200                                       _T("Help"),
201                                       mIcon->GetBitmap(Icon_help),
202                                       _T("Open help window")
203                                       );
204         mToolSynchronize = mToolBar->AddTool( TOOL_SYNCHRONIZE_ID, 
205                                       _T("Synchronize"),
206                                       mIcon->GetBitmap(Icon_synchronize),
207                                       _T("Synchronizes the database with disk")
208                                       );
209     //const wxBitmap& bitmap1, const wxString& shortHelpString = "", wxItemKind kind = wxITEM_NORMAL)
210
211     mToolBar->Realize();
212   }
213   //======================================================================
214
215  
216   //======================================================================
217   /// Create the tree view for TreeHandler provided
218   void WxGimmickView::CreateTreeView( TreeHandler* h)
219   {
220     std::string name(h->GetTree().GetAttribute("Name"));
221     GimmickMessage(2,"Creating the tree view for '"<<
222                    name<<"'"<<std::endl);
223     // Create the WxTreeView
224     WxTreeView* view = new WxTreeView(h,this,mNotebook,-1);
225
226     // TO DO : TEST THAT A VIEW WITH SAME NAME IS NOT
227     // ALREADY IN THE MAP
228     GetTreeViewMap()[name] = view;
229
230     // Add Notebook page
231     mNotebook->AddPage( view, crea::std2wx(name) );
232         
233   }
234
235   //======================================================================
236   void WxGimmickView::GetSelectedImages(std::vector<vtkImageData*>& s, int dim)
237   {
238         std::vector<std::string> files;
239         GetTreeViewMap()["Local database"]->GetSelectedAsString(files);
240         ReadImagesNotThreaded(s,files,dim);
241   }
242   //======================================================================
243
244   //======================================================================
245   void WxGimmickView::GetSelectedFiles(std::vector<std::string>& s)
246   {
247         GetTreeViewMap()["Local database"]->GetSelectedAsString(s);
248   }
249   //======================================================================
250
251   //======================================================================
252   void WxGimmickView::GetImages(int dim, 
253                                 const std::vector<std::string>& files, 
254                                 std::vector<vtkImageData*>& s)
255   {
256         ReadImagesNotThreaded(s,files,dim);
257   }
258   //======================================================================
259
260
261   //=================================================
262   void WxGimmickView::CreateIconList()
263   {
264     // Size of the icons;
265     int size = 16;
266
267     wxIcon icons[20];
268     // should correspond to Icon_xxx enum
269     icons[Icon_accept] = wxIcon(accept_xpm);
270     icons[Icon_add] = wxIcon(add_xpm);
271     icons[Icon_folder_down] = wxIcon(folder_down_xpm);
272     icons[Icon_page_down] = wxIcon(page_down_xpm);
273     icons[Icon_remove] = wxIcon(remove_xpm);
274     icons[Icon_database_add] = wxIcon(database_add_xpm);
275     icons[Icon_help] = wxIcon(help_xpm);
276         icons[Icon_synchronize] = wxIcon(synchronize_xpm);
277
278     //   unsigned int NbIcons = 8;
279     // Make an image list containing small icons
280     mIcon = new wxImageList(size,size,true);
281     
282     // Make all icons the same size = size of the first one
283     int sizeOrig = icons[0].GetWidth();
284     for ( size_t i = 0; i < icon_number; i++ )
285       {
286         if ( size == sizeOrig )
287           {
288             mIcon->Add(icons[i]);
289           }
290         else
291           {
292             mIcon->Add(wxBitmap(wxBitmap(icons[i]).ConvertToImage().Rescale(size, size)));
293           }
294       }
295   }
296   //=================================================
297
298
299   //=================================================
300   void WxGimmickView::OnAddFiles(wxCommandEvent& event)
301   {
302     mViewer->StopPlayer();
303    long style = wxOPEN | wxFILE_MUST_EXIST | wxFD_MULTIPLE;
304     std::string wc("*.*");
305     wxFileDialog* FD = new wxFileDialog( 0, 
306                                          _T("Select file"),
307                                          _T(""),
308                                          _T(""),
309                                          crea::std2wx(wc),
310                                          style,
311                                          wxDefaultPosition);
312     
313     if (FD->ShowModal()==wxID_OK)
314       {
315         wxBusyCursor busy;
316
317         wxArrayString files;
318         FD->GetPaths(files);
319         unsigned int i;
320         std::vector<std::string> filenames;
321         for (i=0;i<files.GetCount();++i)
322         {
323           filenames.push_back(wx2std(files[i]));
324           GimmickMessage(2,"Adding File "<<files[i]<<"."<<std::endl);
325         }
326
327         mProgressDialog = 
328           new wxProgressDialog(_T("Adding file(s)"),
329                                _T(""),
330                                1000,
331                                this,
332                                wxPD_ELAPSED_TIME |
333                                //                              wxPD_ESTIMATED_TIME | 
334                                //                              wxPD_REMAINING_TIME |
335                                wxPD_CAN_ABORT );
336
337         // TO DO : select the current tree handler
338         mGimmick->AddFiles(crea::wx2std(mNotebook->GetPageText(mNotebook->GetSelection())),filenames);
339
340         mProgressDialog->Pulse(_T("Updating view..."));
341
342         UpdateTreeViewLevel(crea::wx2std(mNotebook->GetPageText(mNotebook->GetSelection())),1);
343         delete mProgressDialog;
344         DisplayAddSummary();    
345
346       }
347         mViewer->StartPlayer(); 
348   }
349   //=================================================
350
351   //=================================================
352   void WxGimmickView::OnAddDir(wxCommandEvent& event)
353   {
354     mViewer->StopPlayer();
355         std::string name = crea::wx2std(mNotebook->GetCurrentPage()->GetName());
356     long style = wxDD_DEFAULT_STYLE | wxDD_DIR_MUST_EXIST;
357     wxDirDialog* FD = 
358       new wxDirDialog( 0, 
359                        _T("Select directory"),
360                        mCurrentDirectory,
361                        style);
362     
363     if (FD->ShowModal()==wxID_OK)
364       {
365
366         
367                   std::string dirname = wx2std (FD->GetPath());
368                   bool recurse =  isNeedRecursive(dirname);
369                   if (recurse)
370                  {
371              recurse = wxMessageBox(_T("Recurse into sub-directories ?"),  _T("Scan directory"),         wxYES_NO,this ) == wxYES ? true : false;
372                  }
373                 
374                 wxBusyCursor busy;
375                 wxString title(_T("Adding directory"));
376                 if (recurse) 
377                 title = _T("Adding directory (recursive)");
378                 mProgressDialog = 
379                 new wxProgressDialog(_T("Adding directory"),
380                                         _T(""),
381                                         1000,
382                                         this,
383                                         wxPD_ELAPSED_TIME |
384                                         //                             wxPD_ESTIMATED_TIME | 
385                                         //                             wxPD_REMAINING_TIME |
386                                         wxPD_CAN_ABORT );
387                 
388                 mCurrentDirectory = FD->GetPath();  
389                 mGimmick->AddDir(crea::wx2std(mNotebook->GetPageText(mNotebook->GetSelection())),dirname,recurse);
390                 mProgressDialog->Pulse(_T("Updating view..."));
391                 
392                 UpdateTreeViewLevel(crea::wx2std(mNotebook->GetPageText(mNotebook->GetSelection())),1);
393                 delete mProgressDialog;
394                 DisplayAddSummary();
395
396           }
397     mViewer->StartPlayer();
398   }
399
400     //=================================================
401    // Test a directory to know if contains sub-directory to analyze
402   bool WxGimmickView::isNeedRecursive(std::string i_name)
403   {
404       boost::filesystem::directory_iterator iter(i_name), end_iter;
405           bool bfindir = false;
406                   for(; iter != end_iter; ++iter)
407                   {
408                           if(boost::filesystem::is_directory(*iter))
409                           {
410                                   return true;
411                           }
412                   }
413                   return false;
414   }
415   //=================================================
416
417   //=================================================
418   void WxGimmickView::OnSelectionChange(const std::vector<tree::Node*>& sel, bool isSelection, int selection, bool needProcess)
419   {      
420     GimmickDebugMessage(5,
421                         "WxGimmickView::OnSelectionChange"
422                         <<std::endl);
423     wxBusyCursor busy;
424         bool valid=true;
425         
426         if(sel.size()==0)
427         {
428                 valid= ValidateSelected(NULL,
429                                 mSelectionMinDimension,
430                                 mSelectionMaxDimension );
431         }
432         else if(needProcess)
433         {
434                 ResetExtent();
435                 std::vector<tree::Node*>::const_iterator i;
436                 for(i=sel.begin();i!=sel.end()&&valid;++i)
437                 {
438                         valid= ValidateSelected((*i),
439                                 mSelectionMinDimension,
440                                 mSelectionMaxDimension );
441                 }
442         }
443         else if(isSelection)
444         {
445                 valid= ValidateSelected(sel.front(),
446                                 mSelectionMinDimension,
447                                 mSelectionMaxDimension );
448         }
449         else
450         {
451                 ResetExtent();
452                 std::vector<tree::Node*>::const_iterator i;
453                 for(i=sel.begin();i!=sel.end()&&valid;++i)
454                 {
455                         valid= ValidateSelected((*i),
456                                 mSelectionMinDimension,
457                                 mSelectionMaxDimension );
458                 }
459         }
460         
461     mText->SetLabel(crea::std2wx(GetMessage()));
462     /*if(valid)
463       {
464         ReadImageThreaded(sel);
465       }
466     else
467       {
468                   ClearSelection();
469       }*/
470         ReadImageThreaded(sel);
471
472     
473    }
474
475   //==================================================
476
477   //==================================================
478   ///Reads Images (Threaded)
479   void WxGimmickView::ReadImageThreaded(const std::vector<tree::Node*>& sel)
480   {     
481    GimmickDebugMessage(5,
482                        "ReadImageThreaded"
483                        <<std::endl);
484    int maxprio = GetMaximalPriority();
485    int prio = maxprio + 2000;
486
487    if(sel.size()>0)
488    {
489    //First load the selected images
490    mCurImageItemToShow = sel.front();
491    pointers.clear();
492    int index = 0;
493    std::vector<tree::Node*>::const_iterator selected;
494    for(selected=sel.begin();selected!=sel.end();++selected)
495      {
496        GimmickDebugMessage(5,
497                            "Requesting image from selected "
498                            <<(*selected)->GetAttribute("FullFileName")
499                            <<std::endl);
500            ImagePointerHolder* ph=new ImagePointerHolder(GetDefaultImage());
501            pointers.push_back(ph);
502        RequestReading(*selected,prio,index,ph);
503        //       AddEntryToMap(*selected);
504        prio--;
505        index++;
506      }
507         mViewer->SetImageVector(pointers);
508         //Going up
509         prio = maxprio + 20;
510         std::vector<tree::Node*> up;
511         GetTreeViewMap()["Local database"]->GetNodes(up,true);
512         std::vector<tree::Node*>::iterator iterUp;
513         for(iterUp=up.begin();iterUp!=up.end();++iterUp)
514         {
515                 GimmickDebugMessage(5,
516                                 "Requesting image from neighbors up "
517                                 <<(*iterUp)->GetAttribute("FullFileName")
518                                 <<std::endl);
519                 ImagePointerHolder* ph=new ImagePointerHolder(GetDefaultImage());
520                 RequestReading(*iterUp,prio,-1,ph);
521                 //              AddEntryToMap(*iterUp);
522                 prio--;
523                 if (prio == maxprio) break;
524         }
525
526         //Going down
527         prio = maxprio + 19;
528         std::vector<tree::Node*> down;
529         GetTreeViewMap()["Local database"]->GetNodes(down,false);
530         std::vector<tree::Node*>::iterator iterDown;
531         for(iterDown=down.begin();iterDown!=down.end();++iterDown)
532         {
533                 GimmickDebugMessage(5,
534                                 "Requesting image from neighbors down "
535                                 <<(*iterDown)->GetAttribute("FullFileName")
536                                 <<std::endl);
537                 ImagePointerHolder* ph=new ImagePointerHolder(GetDefaultImage());
538                 RequestReading(*iterDown,prio,-1,ph);
539                 //              AddEntryToMap(*iterDown);
540                 prio--;
541                 if (prio == maxprio) break;
542         }
543    }
544    else
545    {
546            pointers.clear();
547            ImagePointerHolder* ph=new ImagePointerHolder(GetDefaultImage());
548            pointers.push_back(ph);
549            mViewer->SetImageVector(pointers);
550    }
551   }
552
553   //==================================================
554
555   //==================================================
556
557   //==================================================
558    void  WxGimmickView::OnInternalIdle()
559   {
560    if (!mConstructed) return;
561    static bool first_time = true;
562    if (false)
563    {
564         first_time = false;
565      }
566    //   GimmickMessage(1,"WxGimmickView : Refresh viewer"<<std::endl);
567         //  mViewer->StartPlayer();
568    if(mViewer)
569    {
570            mViewer->RefreshIfNecessary();
571    }
572   }
573
574    //==================================================
575
576   //==================================================
577    void  WxGimmickView::ClearSelection()
578   {
579         pointers.clear();
580         pointers.push_back(new ImagePointerHolder(GetDefaultImage()));
581         mViewer->SetImageVector(pointers);
582         mViewer->RefreshIfNecessary();
583         ResetExtent();
584   }
585   
586   //=================================================
587  
588   //=================================================
589   void WxGimmickView::OnRemove(wxCommandEvent& event)
590   {
591         //TODO Select current tree handler       
592     wxBusyCursor busy;
593     GetTreeViewMap()["Local database"]->RemoveSelected();
594         ClearSelection();
595   }
596   //=================================================
597
598   
599   //=================================================
600   void WxGimmickView::AddIgnoreFile(const tree::Node* & toRemove)
601   {
602           mGimmick->RemoveFile("Local database",toRemove);
603           GetTreeViewMap()["Local database"]->UpdateLevel(1);
604   }
605
606    //=================================================
607   void WxGimmickView::OnSynchronize(wxCommandEvent& event)
608   {       
609     wxBusyCursor busy;
610         const wxString choices[] = { _T("Check database for file deletion or addition and give a report."), 
611                                                                 _T("Check database for file deletion or addition and attribute change and give a report."), 
612                                                                 _T("Repair database (removes deleted files and adds new files)."), 
613                                                                 _T("Repair database (removes deleted files, adds new files and resets changed attributes).") } ;
614
615     wxSingleChoiceDialog dialog(this,
616                                                                 _T("Select one of the following synchronization actions:\n")
617                                 _T("Plase note that, due to the heavy amount of operations required, this action might take a while."),
618                                 _T("Synchronization Settings"),
619                                 WXSIZEOF(choices), choices);
620
621     //dialog.SetSelection(0);
622
623     if (dialog.ShowModal() == wxID_OK)
624     {
625         int sel=dialog.GetSelection();
626                 bool repair=false;
627                 bool checkAttributes=false;
628                 if(sel==2 || sel==3){repair=true;}
629                 if(sel==1 || sel==3){checkAttributes=true;}
630                 std::string mess=mGimmick->Synchronize(repair, checkAttributes);
631                 wxMessageBox(std2wx(mess),_T("Synchronization result"),wxOK,this);
632                 GetTreeViewMap()["Local database"]->UpdateLevel(1);
633                 
634     }
635   }
636   //=================================================
637
638   //=================================================
639   /// AddProgress Gimmick callback
640   void WxGimmickView::OnAddProgress( Gimmick::AddProgress& p)
641   {
642
643     char mess[200];
644    
645         sprintf(mess,"%i dirs : %i files :\n            %i handled - %i added",
646            p.GetNumberScannedDirs(),
647            p.GetNumberScannedFiles(),
648            p.GetNumberHandledFiles(),
649            p.GetNumberAddedFiles());
650     //    std::cout << "OnAddProgress "<<mess<<std::endl;
651     wxString s(wxString::From8BitData(mess));
652     //  std::cout << "Pulse"<<std::endl;
653     if (!mProgressDialog->Pulse(s)) 
654       {
655         p.SetStop();
656       }
657     //  std::cout << "OnAddProgress ok"<<std::endl;
658   }
659   //=================================================
660
661   //=================================================
662   void WxGimmickView::DisplayAddSummary()
663   {
664     const Gimmick::AddProgress& p = mGimmick->GetAddProgress();
665     std::stringstream mess;
666     mess << "Dirs \tscanned\t: " << p.GetNumberScannedDirs()  << "\n";
667     mess << "Files\tscanned\t: " << p.GetNumberScannedFiles() << "\n";
668     mess << "Files\thandled\t: " << p.GetNumberHandledFiles() << "\n\n";
669     mess << "Files\tadded  \t: " << p.GetNumberAddedFiles()   << "\n\n";
670
671     /*    char times[500];
672     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",
673             summary.parse_time,
674             (int)( summary.parse_time*100./summary.total_time),
675             summary.file_scan_time,
676             (int)(summary.file_scan_time*100./summary.total_time),
677             summary.update_structs_time,
678             (int)(summary.update_structs_time*100./summary.total_time),
679             summary.update_database_time,
680             (int)(summary.update_database_time*100./summary.total_time),
681             summary.total_time );
682     
683     mess << times;
684     */
685     wxMessageBox(std2wx(mess.str()),_T("Addition result"),wxOK,this);
686   }
687
688   //////////////////////////////////////////////////
689   // Add a DB to application                                      //
690   // @param event : WxEvent                                               //
691   // @return : -                                                                  //
692   //////////////////////////////////////////////////
693   void WxGimmickView::OnAddDB(wxCommandEvent& event)
694   {
695     
696           //Select DB
697           long style = wxDD_DEFAULT_STYLE | wxDD_DIR_MUST_EXIST;
698           std::string wc("*.sqlite3*");
699           wxFileDialog* FD = new wxFileDialog( 0, 
700                                          _T("Select file"),
701                                          _T(""),
702                                          _T(""),
703                                          crea::std2wx(wc),
704                                          style,
705                                          wxDefaultPosition);
706     
707     if (FD->ShowModal()==wxID_OK)
708         {
709                 wxBusyCursor busy;
710                 wxArrayString files;
711                 FD->GetPaths(files);
712                 std::stringstream st;
713                 for(int i = 0; i< files.size(); i++)
714                 {
715                         st<< "remote_" << i+1;
716                         //create TreeHandler
717                         mGimmick->addDB(st.str(), crea::wx2std(files[i]));
718                         //create TreeView
719                         CreateSingleTreeView(st.str());
720                 }
721         }
722     
723                 
724   }
725
726    //=================================================
727
728    //=================================================
729   BEGIN_EVENT_TABLE(WxGimmickView, wxPanel)
730     EVT_TOOL(TOOL_ADDFILES_ID, WxGimmickView::OnAddFiles)
731     EVT_TOOL(TOOL_ADDDIR_ID, WxGimmickView::OnAddDir)
732         EVT_TOOL(TOOL_REMOVE_ID, WxGimmickView::OnRemove)
733         EVT_TOOL(TOOL_SYNCHRONIZE_ID, WxGimmickView::OnSynchronize)
734         EVT_TOOL(TOOL_ADDDATABASE_ID, WxGimmickView::OnAddDB)
735   END_EVENT_TABLE()
736   //=================================================
737
738 } // EO namespace creaImageIO
739
740