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