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