]> Creatis software - creaImageIO.git/blob - src2/creaImageIOWxTreeView.cpp
Message for remove patients action
[creaImageIO.git] / src2 / creaImageIOWxTreeView.cpp
1 #include <creaImageIOWxTreeView.h>
2 #include <creaImageIOGimmickView.h>
3 #include <creaImageIOSystem.h>
4 #include <wx/splitter.h>
5 #include <wx/gdicmn.h>
6 #include <boost/date_time/gregorian/gregorian.hpp>
7
8
9 //=====================================================================
10 namespace creaImageIO
11 {
12
13   //=====================================================================
14 }
15 //=====================================================================
16
17 //=====================================================================
18 ///Comparing function for ordering algorithm. Takes parameters as strings.
19 int wxCALLBACK CompareFunctionStrings(long item1, long item2, long sortData)
20 {       
21   creaImageIO::ItemData* data1 = (creaImageIO::ItemData*)item1;
22   creaImageIO::ItemData* data2 = (creaImageIO::ItemData*)item2;
23
24   const std::string& s1(*(data1->attr));
25   const std::string& s2(*(data2->attr));
26   if(sortData==1)
27     {
28       // inverse the order
29       if (s1 < s2)
30         return 1;
31       if (s1 > s2)
32         return -1;
33       
34       return 0;
35     }
36   else
37     {
38       if (s1 < s2)
39         return -1;
40       if (s1 > s2)
41         return 1;
42       
43       return 0;
44       
45     }
46 }
47 //=====================================================================
48
49 //=====================================================================
50 ///Comparing function for ordering algorithm. Takes parameters as ints.
51 int wxCALLBACK CompareFunctionInts(long item1, long item2, long sortData)
52 {       
53   creaImageIO::ItemData* data1 = (creaImageIO::ItemData*)item1;
54   creaImageIO::ItemData* data2 = (creaImageIO::ItemData*)item2;
55
56   const std::string& s1(*(data1->attr));
57   const std::string& s2(*(data2->attr));
58
59   int val1=atoi(s1.c_str());
60   int val2=atoi(s2.c_str());
61
62   if(sortData==1)
63     {
64       // inverse the order
65       if (val1 < val2)
66         return 1;
67       if (val1 > val2)
68         return -1;
69       
70       return 0;
71     }
72   else
73     {
74       if (val1 < val2)
75         return -1;
76       if (val1 > val2)
77         return 1;
78
79       return 0;
80       
81     }
82   
83 }
84
85 //=====================================================================
86
87
88 //=====================================================================
89 namespace creaImageIO
90 {
91   //=====================================================================
92   // CTor
93   WxTreeView::WxTreeView(TreeHandler* handler,
94                          GimmickView* gimmick,
95                          wxWindow* parent,
96                          const wxWindowID id)
97     : wxPanel(parent,id),
98       TreeView(handler, gimmick)
99   {
100     GimmickDebugMessage(1,"WxTreeView::WxTreeView"
101                         <<std::endl);
102
103     
104     // Split part below toolbar into notebook for views and panel
105     // for preview, messages...
106     // TO DO : Splitter
107     //    mSplitter = new wxSplitterWindow( this , -1);
108
109     // Global sizer
110     wxBoxSizer  *sizer = new wxBoxSizer(wxHORIZONTAL);
111     
112     int ctrl_style = wxLC_REPORT | wxLC_VRULES;
113     int col_style = wxLIST_FORMAT_LEFT;
114
115     // Creating the ListCtrl for the levels > 0 (not for Root level)
116     for (int i = 0;
117          i < handler->GetTree().GetNumberOfLevels() -1;
118          ++i)
119       {
120         GimmickDebugMessage(5,"Creating view for level "<<i
121                             <<std::endl);
122         LevelType level;
123         level.SelectedUpToDate = true;
124         level.SortColumn = 0;
125
126         // If the first level : parent = this
127         wxWindow* sparent = this;
128         // else parent = last splitter
129         if (i>0) 
130                 sparent = mLevelList[i-1].wxSplitter;
131
132         level.wxSplitter = new wxSplitterWindow( sparent , -1);
133         if(i!=0)
134         {
135         level.wxSplitter->Show(false);
136         }
137         //          level.wxSplitter->SetMinimumPaneSize(100);
138         
139         wxListCtrl* ctrl = new wxListCtrl(level.wxSplitter,
140                                           i,
141                                           wxDefaultPosition, 
142                                           wxDefaultSize,
143                                           ctrl_style);
144         level.wxCtrl = ctrl;
145         level.wxSplitter->Initialize(ctrl);
146    
147         // Create the columns : one for each attribute of the level
148         int col = 0;
149         std::string title;
150
151         tree::LevelDescriptor::AttributeDescriptorListType::const_iterator a;
152         for (a  = handler->GetTree().GetAttributeDescriptorList(i+1).begin();
153              a != handler->GetTree().GetAttributeDescriptorList(i+1).end();
154              ++a)
155
156 {
157         
158             GimmickDebugMessage(5,"Creating column "<<col<<" : "
159                                 <<a->GetName()
160                                 <<std::endl);
161             
162             if(a->GetFlags()!=creaImageIO::tree::AttributeDescriptor::PRIVATE)
163               {
164                 
165                 if(a->GetName()=="UNKNOWN")
166                   {
167                     title = "#";
168                     title += handler->GetTree().GetLevelDescriptor(i+1).GetName();
169                     if (title[title.size()-1]!='s')
170                       title += "s";
171                     
172                   }
173                 else
174                   {
175                     title=a->GetName();
176                   }
177                   std::string temp = a->GetKey();
178                   if (temp.compare("ID") != 0)
179                   {
180                 
181                 ctrl->InsertColumn(col, 
182                                    crea::std2wx(title),
183                                    col_style);
184                 col++;
185                   }
186                 level.key.push_back(a->GetKey());
187               }
188                 
189           }
190           
191         mLevelList.push_back(level);
192       }
193     
194 #if wxUSE_MENUS
195
196          // Column Menu
197     menu =new wxMenu;
198         wxMenuItem* m1=menu->Append(wxID_ANY, _T("&Sort ascending"));
199         wxMenuItem* m2=menu->Append(wxID_ANY, _T("&Sort descending"));
200         wxMenuItem* m3=menu->Append(wxID_ANY, _T("&Filter"));
201         mAscendingID=m1->GetId();
202         mDescendingID=m2->GetId();
203         mFilterID=m3->GetId();
204         Connect( mAscendingID, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(WxTreeView::OnPopupSort) );
205         Connect( mDescendingID, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(WxTreeView::OnPopupSort) );
206         Connect( mFilterID, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(WxTreeView::OnPopupFilter) );
207
208
209
210         //ItemMenu
211         menuItem =new wxMenu;
212         wxMenuItem* m1Item=menuItem->Append(wxID_ANY, _T("&Anonymize"));
213         wxMenuItem* m2Item=menuItem->Append(wxID_ANY, _T("&Local Copy"));
214         wxMenuItem* m3Item=menuItem->Append(wxID_ANY, _T("&Edit Fields"));
215         
216         mAnonymizingID=m1Item->GetId();
217         mLocalCopyID=m2Item->GetId();
218         mEditFieldID=m3Item->GetId();
219         //Connect( mAnonymizingID, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(WxTreeView::OnAnonymize) );
220         Connect( mLocalCopyID, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(WxTreeView::OnLocalCopy) );
221         Connect( mEditFieldID, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(WxTreeView::OnEditField) );
222         
223         
224 #endif // wxUSE_MENUS
225         /// Initialize the first level splitter
226           
227         sizer->Add( mLevelList[0].wxSplitter ,1, wxGROW  ,0);
228         //      mColumnSelected=1;
229         mLastSelected=0;
230         mLastLevel=0;
231         //      mDirection=true;
232
233         mIgnoreSelectedChanged = false;
234
235         //CreateColorPalette();
236     UpdateLevel(1);
237
238     SetSizer( sizer );     
239     SetAutoLayout(true);
240     Layout();
241
242   }
243   //=====================================================================
244
245   //=====================================================================
246   /// Destructor
247   WxTreeView::~WxTreeView()
248   {
249     GimmickDebugMessage(1,"WxTreeView::~WxTreeView"
250                         <<std::endl);
251         delete menu;
252         delete menuItem;
253
254   }
255   //=====================================================================
256   
257   
258   
259   //=====================================================================
260   const std::vector<tree::Node*>& WxTreeView::GetSelected(int level)
261   {
262           std::vector<tree::Node*>& sel = mLevelList[0].Selected;
263     //  if (GetSelectedUpToDate(level)) 
264     int l = level - 1;
265     // the selection of upper level
266         if(mLevelList.size() == level -1)
267                  sel = mLevelList.back().Selected;
268         else
269                   sel=  mLevelList[l].Selected;
270         if (sel.size() > 0)
271         {
272                 sel.clear();
273         }
274           if (level == 1) 
275       {
276         sel.push_back(GetTreeHandler()->GetTree().GetTree());
277       }
278           else if (level < mLevelList.size()+2 ) 
279     {
280                 long item = -1;
281                 for ( ;; )
282                 {
283                         item = GetCtrl(l-1)->GetNextItem(item,
284                                                                                  wxLIST_NEXT_ALL,
285                                                                                  wxLIST_STATE_SELECTED);
286                         if ( item == -1 )
287                                 break;
288                         long adr = GetCtrl(l-1)->GetItemData(item);
289                         tree::Node* n = ((ItemData*)adr)->node;
290                         if(mLastSelected==item)
291                         {
292                                 std::vector<tree::Node*>::iterator it;
293                                 it = sel.begin();
294                                 it = sel.insert ( it , n );
295                         }
296                         else
297                         {
298                                 
299                                 sel.push_back(n);
300                         }                       
301                         
302                 }
303                 /*int n = GetCtrl(l-1)->GetItemCount();
304                 for (int i = 0; i<n; i++)
305                 {
306                         std::cout<<GetCtrl(l-1)->GetItemState(i,wxLIST_STATE_SELECTED)<<std::endl;
307                         if ( GetCtrl(l-1)->GetItemState(i,wxLIST_STATE_SELECTED))
308                         {
309                                 long adr = GetCtrl(l-1)->GetItemData(i);
310                                 tree::Node* n = ((ItemData*)adr)->node;
311                                 if(mLastSelected==i)
312                                 {
313                                         std::vector<tree::Node*>::iterator it;
314                                         it = sel.begin();
315                                         it = sel.insert ( it , n );
316                                 }
317                                 else
318                                 {
319                                         
320                                         sel.push_back(n);
321                                 }
322                         }
323               }*/
324           }
325         else
326         {
327                 // NOTHING
328         }   
329          
330     //    return mLevelList[level-1].Selected;
331     return sel;
332   }
333
334   //=====================================================================
335   
336   //=====================================================================
337   ///Removes selected nodes on last selected level
338    // NOT SPECIFIC 
339   void WxTreeView::RemoveSelected(std::string &i_save)
340   {
341          bool erase=false;
342          
343          unsigned int tempLevel = mLastLevel;
344     mLastLevel+=1;
345     const std::vector<tree::Node*>& sel=GetSelected(mLastLevel+1);
346         // if no selection, no remove action.
347     if(sel.size() != 0)
348         {
349         
350             std::stringstream out;
351             std::string levelName=GetTreeHandler()->GetTree().GetLevelDescriptor(mLastLevel).GetName();
352             out<<"Delete ";
353             out<<sel.size();
354             if(sel.size()>1&&levelName.at(levelName.size()-1)!='s')
355               {
356                 out<<" "<<levelName;
357                 out<<"s?";
358               }
359             else
360               {
361                 out<<" "<<GetTreeHandler()->GetTree().GetLevelDescriptor(mLastLevel).GetName()<<"?";
362               }
363             if (wxMessageBox(crea::std2wx(out.str()),
364                              _T("Remove Files"),
365                              wxYES_NO,this ) == wxYES)
366               {
367                 erase = true;
368               }
369             if(erase)
370                   {
371             GetGimmickView()->modifyValidationSignal(false);
372                     bool needRefresh=false;
373                     std::vector<tree::Node*>::const_iterator i;
374                     for (i=sel.begin(); i!=sel.end(); ++i)
375                       {
376                         GimmickMessage(1,
377                                        "deleting '"
378                                        <<(*i)->GetLabel()
379                                        <<"'"<<mLastLevel
380                                        <<std::endl);
381                         if((*i)->GetParent()->GetNumberOfChildren()<2)
382                           {
383                             needRefresh=true;
384                           }
385                           //tree::Node* n = new (tree::Node*)(*i);
386                           GetTreeHandler()->LoadChildren((*i),4);
387                           GetGimmickView()->AddIgnoreFile(*i);
388                           GetTreeHandler()->Remove(*i);
389                       }
390                     
391                     if(needRefresh && mLastLevel>1)
392                       {
393                         UpdateLevel(mLastLevel-2);
394                       }
395                     else if(mLastLevel>1)
396                       {
397                         UpdateLevel(mLastLevel-1);
398                       }
399                     else
400                       {
401                         UpdateLevel(mLastLevel);
402                       }
403                   }
404         }
405         else
406         {
407                 // no need to incremente level
408                 mLastLevel = tempLevel;
409         }
410     
411         if (erase && mLastLevel == 1 && i_save == "0")
412         {
413         
414                 RemoveAlertDlg *dial = new RemoveAlertDlg(this,  crea::std2wx("Remove files"), wxSize(370,100));
415                 //dial->ShowModal();
416                 if (dial->ShowModal() == wxID_OK)
417                 {
418                         i_save = dial->isChecked() == false? "0" : "1";
419                 }
420                 
421         }
422   }
423   
424   
425   //=====================================================================
426   /// Updates a level of the view (adds or removes children, etc.)
427   void WxTreeView::UpdateLevel( int level )
428   {
429     GimmickDebugMessage(1,
430                         GetTreeHandler()->GetTree().GetLabel()
431                         <<"WxTreeView::UpdateLevel(level "
432                         <<level
433                         <<")"
434                         <<std::endl);
435     
436     wxBusyCursor busy;
437     RecursiveUpdateLevel(level);
438     int i;
439     for (i=0; i<level-1; i++)
440       {
441         if (!GetSplitter(i)->IsSplit()) 
442           GetSplitter(i)->SplitVertically(  GetCtrl(i), GetSplitter(i+1),
443                                             100 );
444       }
445     if (GetSplitter(i)->IsSplit()) GetSplitter(i)->Unsplit();    
446     
447   }
448   //=====================================================================
449   
450   //=====================================================================
451   /// Recursive method called upon by UpdateLevel to refresh all windows
452   void WxTreeView::RecursiveUpdateLevel( int level )
453   {
454     GimmickDebugMessage(1,
455                         GetTreeHandler()->GetTree().GetLabel()
456                         <<"WxTreeView::RecursiveUpdateLevel(level "
457                         <<level
458                         <<")"<<std::endl);
459     
460     
461     const std::vector<tree::Node*>& sel(GetSelected(level));
462     
463     int l = level - 1;
464     
465     // to speed up inserting we hide the control temporarily
466     GetCtrl(l)->Hide();
467     GetCtrl(l)->DeleteAllItems();
468     
469     std::vector<tree::Node*>::const_iterator i;
470     
471     for (i=sel.begin(); i!=sel.end(); ++i)
472       {
473         GimmickDebugMessage(1,
474                             "adding children of '"
475                             <<(*i)->GetLabel()
476                             <<"'"
477                             <<std::endl);
478         int _id=0;
479         
480         //Adds items and sets their attributes 
481         
482         GetTreeHandler()->LoadChildren(*i,1);
483         tree::Node::ChildrenListType::reverse_iterator j;
484         for (j = (*i)->GetChildrenList().rbegin(); 
485              j!= (*i)->GetChildrenList().rend(); 
486              ++j)
487           {
488             GimmickDebugMessage(1,
489                                 "adding children "
490                                 <<(*j)->GetLabel()
491                                 <<"'"
492                                 <<std::endl);
493             
494             wxListItem item;
495             item.SetMask(wxLIST_MASK_STATE | 
496                          wxLIST_MASK_TEXT |
497                          //                      wxLIST_MASK_IMAGE |
498                          wxLIST_MASK_DATA |
499                          //                      wxLIST_MASK_WIDTH |
500                          wxLIST_MASK_FORMAT
501                          );
502             
503                 ItemData* data = new ItemData();
504             data->node = *j;
505             data->id = _id;
506                 
507             item.SetId(_id);
508             item.SetData(data);
509
510             _id++;
511             GetCtrl(l)->InsertItem(item);
512             
513             //Setting attributes
514             for (int k=0; k<GetCtrl(l)->GetColumnCount(); ++k)                          
515               {
516                 std::string val;
517                 //  Temporary correction : it works but no explanation about the problem FCY
518                 
519                 if(k==0 && level <3)
520                 {
521                   val = (*j)->GetAttribute("NumberOfChildren");
522                 }
523                 else
524                   val = (*j)->GetAttribute(mLevelList[l].key[k]);
525                 if(((*j)->GetAttributeDescriptor(mLevelList[l].key[k])).isDateEntry()) // Date
526                   {
527                     //                                    std::cout << "["<<val<< "]" << std::endl;
528                     std::string valtmp(val);
529                     try
530                       {
531                         boost::gregorian::date d1(boost::gregorian::from_undelimited_string(val));                                 
532                         val = to_iso_extended_string(d1);
533                       }
534                     catch (...)
535                       {
536                         val =  valtmp;
537                       }
538                     //                                    std::cout << "["<<val<< "]" << std::endl;     
539                   }
540                 else if(((*j)->GetAttributeDescriptor(mLevelList[l].key[k])).isTimeEntry()) // Time
541                   {
542                     if ((val.size()>6) && 
543                         (val != "" || val != " "))
544                       val = val.substr(0,2) + " : " 
545                         + val.substr(2,2) + " : " 
546                         + val.substr(4,2);
547                   }
548                 else
549                   {
550                     if (val.size()==0) val = "?";
551                   }
552                 if (val.size()==0) val = "X";
553                 item.SetText( crea::std2wx(val));
554                 item.SetColumn(k);
555                   
556                   GetCtrl(l)->SetItem(item);
557                   }
558                 item.Clear();
559             
560           }
561       }
562     
563     SortLevel(l);
564     GetCtrl(l)->Show();
565   }
566   //=====================================================================
567   
568   
569   //================================================================
570   void WxTreeView::OnItemDeSelected(wxListEvent& event)
571   { 
572     GimmickDebugMessage(1,
573                         GetTreeHandler()->GetTree().GetLabel()
574                         <<" WxTreeView::OnItemDeselected"<<std::endl);
575     // retrieve the level
576     wxObject* obj = event.GetEventObject();   
577     unsigned int level = 0;
578     for (level = 0; level<mLevelList.size(); ++level)
579       {
580         if ( GetCtrl(level) == obj ) break;
581       } 
582     SetSelectedUpToDate(level,false);
583     // to allow a first selection in images TreeView
584     if (level==mLevelList.size()-1) 
585       OnItemSelected(event);
586   }
587   //================================================================
588   
589   //================================================================
590   void WxTreeView::OnItemSelected(wxListEvent& event)
591   { 
592           
593     GimmickDebugMessage(1,
594                         GetTreeHandler()->GetTree().GetLabel()
595                         <<" WxTreeView::OnItemSelected"<<std::endl);
596
597     if (mIgnoreSelectedChanged) 
598       {
599         GimmickDebugMessage(1,
600                             " mIgnoreSelectedChanged true: returning"
601                             <<std::endl);
602         return;
603       }
604     
605
606     
607     wxListItem info;
608     info.m_itemId = event.m_itemIndex;
609     mLastSelected = event.m_itemIndex;
610     // retrieve the level
611     wxObject* obj = event.GetEventObject();   
612     unsigned int level = 0;
613     for (level = 0; level<mLevelList.size(); ++level)
614       {
615         if ( GetCtrl(level) == obj ) break;
616       }
617         mLastLevel=level;
618     GimmickDebugMessage(1,
619                         " Level "<<level+1
620                         <<std::endl);
621     
622     // Update the children level (if selection not at last level)
623     if (level<mLevelList.size()-1) 
624       {
625                 
626         UpdateLevel( level + 2 ); 
627         // Reset the viewer setting the default image
628         GetGimmickView()->ClearSelection();
629       }
630     // Select all images if the selection is at series level
631     if (level==mLevelList.size()-2) 
632                 SelectAll(level+1);
633     // Validate selected images if the selection is at image level
634     if (level==(mLevelList.size()-1)) //&&mProcess) 
635       {
636         if(event.GetEventType()==wxEVT_COMMAND_LIST_ITEM_SELECTED)
637           {
638                   ValidateSelectedImages (true);
639           }
640         else
641           {
642                   ValidateSelectedImages (false);
643           }
644       }
645     
646   }
647   //================================================================
648
649   //================================================================
650   void WxTreeView::SelectAll(int level)
651   {
652     long item = -1;
653     //    int level=mLevelList.size()-1;
654     for ( ;; )
655       {
656         item = GetCtrl(level)->GetNextItem(item,
657                                            wxLIST_NEXT_ALL);
658         if ( item == -1 )
659           break;
660         
661         if(item==(GetCtrl(level)->GetItemCount()-1))
662           {
663             mIgnoreSelectedChanged = false;//mProcess=true;
664           }
665         else
666           {
667             mIgnoreSelectedChanged = true;//    mProcess=false;
668           }
669         GetCtrl(level)->SetItemState(item,wxLIST_STATE_SELECTED, wxLIST_MASK_STATE 
670                                      | wxLIST_MASK_TEXT |wxLIST_MASK_IMAGE | wxLIST_MASK_DATA | wxLIST_MASK_WIDTH | wxLIST_MASK_FORMAT);
671       }
672   }
673
674   //================================================================
675   //================================================================
676
677   void WxTreeView::OnColClick(wxListEvent& event)
678   { 
679     mColumnSelected = event.m_col;
680     wxPoint clientpt;
681     clientpt.x = wxGetMousePosition().x - this->GetScreenPosition().x;
682     clientpt.y = wxGetMousePosition().y - this->GetScreenPosition().y;
683     senderCtrl = event.GetEventObject(); 
684     unsigned int level = 0;
685     for (level = 0; level<mLevelList.size(); ++level)
686       {
687         if ( GetCtrl(level) == senderCtrl ) break;
688       }
689     PopupMenu(menu, clientpt);
690     
691   }
692
693    //================================================================
694   //================================================================
695
696   void WxTreeView::OnItemMenu(wxListEvent &event)
697   {
698          wxPoint clientpt;
699     clientpt.x = wxGetMousePosition().x - this->GetScreenPosition().x;
700     clientpt.y = wxGetMousePosition().y - this->GetScreenPosition().y;
701     senderCtrl = event.GetEventObject();
702     unsigned int level = 0;
703     for (level = 0; level<mLevelList.size(); ++level)
704       {
705                 if ( GetCtrl(level) == senderCtrl ) break;
706       }
707           long* ptr=0;
708           int flag;
709           mLastRightLevel=level;
710           mLastRightSelected=GetCtrl(level)->HitTest(wxPoint(0,clientpt.y-8),flag,ptr);
711     PopupMenu(menuItem, clientpt);
712     
713   }
714   
715   //================================================================
716   //================================================================
717
718   void WxTreeView::OnPopupFilter(wxCommandEvent& event)
719   {
720     wxBusyCursor busy;
721     GimmickDebugMessage(7,
722                         "WxTreeView::OnEndLabelEdit" 
723                         <<std::endl);
724     unsigned int level = 0;
725     for (level = 0; level<mLevelList.size(); ++level)
726       {
727         if ( GetCtrl(level) == senderCtrl ) break;
728       }
729     std::string filter = crea::wx2std(wxGetTextFromUser(_T("Enter the filter to apply"), _T("Filter On Column")));
730     
731     std::string att;
732     
733     long it = -1;
734     UpdateLevel(level+1);
735     
736     std::vector<long> items;
737     bool in=false;
738     int del=0;
739     for ( ;; )
740       {
741         it = GetCtrl(level)->GetNextItem(it,
742                                          wxLIST_NEXT_ALL);
743         if ( it == -1 )
744           break;
745         
746         long adr = GetCtrl(level)->GetItemData(it);
747         tree::Node* nod = ((ItemData*)adr)->node;
748         att=(*nod).GetAttribute(mLevelList[level].key[mColumnSelected]);
749         
750         
751         if(att.find(filter)>900)
752           {
753             
754             if(!in)
755               {
756                 in=true;
757               }
758             else
759               {
760                 del+=1;
761               }
762             
763             items.push_back(it-del);
764           }
765         
766       }
767     std::vector<long>::iterator iter;
768     for(iter=items.begin();iter!=items.end();++iter)
769       {
770         GetCtrl(level)->DeleteItem(*iter);
771       }
772     GetGimmickView()->ClearSelection();
773   }
774   //================================================================
775   
776   //================================================================
777   void WxTreeView::OnPopupSort(wxCommandEvent& event)
778   {
779     wxBusyCursor busy;
780     unsigned int level = 0;
781     for (level = 0; level<mLevelList.size(); ++level)
782       {
783         if ( GetCtrl(level) == senderCtrl ) break;
784       }
785     mLevelList[level].SortColumn = mColumnSelected;
786
787     if(event.GetId()==mAscendingID)
788       {
789         mLevelList[level].SortAscending = true;
790       }
791     else if(event.GetId()==mDescendingID)
792       {
793         mLevelList[level].SortAscending = false;
794       }
795           
796     SortLevel(level);
797   }
798   //================================================================
799
800   //================================================================
801   void WxTreeView::OnLocalCopy(wxCommandEvent& event)
802   {
803     wxBusyCursor busy;
804     
805         unsigned int tempLevel = mLastLevel;
806     mLastLevel+=1;
807     const std::vector<tree::Node*>& sel=GetSelected(mLastLevel+1);
808         
809     if(sel.size() != 0)
810         {
811             bool copy=false;
812             std::stringstream out;
813             std::string levelName=GetTreeHandler()->GetTree().GetLevelDescriptor(mLastLevel).GetName();
814             out<<"Copy ";
815             out<<sel.size();
816             if(sel.size()>1&&levelName.at(levelName.size()-1)!='s')
817               {
818                 out<<" "<<levelName;
819                 out<<"s to .gimmick?";
820               }
821             else
822               {
823                 out<<" "<<GetTreeHandler()->GetTree().GetLevelDescriptor(mLastLevel).GetName()<<" to .gimmick?";
824               }
825             if (wxMessageBox(crea::std2wx(out.str()),
826                              _T("Remove Files"),
827                              wxYES_NO,this ) == wxYES)
828               {
829                 copy = true;
830               }
831             if(copy)
832                   {
833                         std::vector<std::string> s;
834                         GetFilenamesAsString(sel,s);
835             GetGimmickView()->CopyFiles(s);
836                   }
837         }
838         else
839         {
840                 mLastLevel = tempLevel;
841         }
842     
843     
844   }
845   //================================================================
846
847    //================================================================
848   void WxTreeView::OnEditField(wxCommandEvent& event)
849   {
850         if(mLastRightSelected!=-1)
851         {
852     tree::Node* node=((ItemData*)GetCtrl(mLastRightLevel)->GetItemData(mLastRightSelected))->node;
853         tree::LevelDescriptor::AttributeDescriptorListType::const_iterator a;
854         std::vector<std::string> names;
855         std::vector<std::string> keys;
856         for (a  = GetTreeHandler()->GetTree().GetAttributeDescriptorList(mLastRightLevel+1).begin();
857              a != GetTreeHandler()->GetTree().GetAttributeDescriptorList(mLastRightLevel+1).end();
858              ++a)
859         {
860                 if(a->GetFlags()==creaImageIO::tree::AttributeDescriptor::EDITABLE)
861             {
862                         names.push_back(a->GetName());
863                         keys.push_back(a->GetKey());
864                 }
865         }
866         GetGimmickView()->CreateEditFieldsDialog(node,names,keys);
867         }
868   }
869   //================================================================
870
871   //================================================================
872   void WxTreeView::SortLevel(int level)
873   {       
874     GimmickDebugMessage(1,
875                         "WxTreeView::SortLevel(" 
876                         <<level<<")"
877                         <<std::endl);  
878     //Obtain the column name and the level that needs to be organized
879     
880     //    int l = level - 1;
881     //Sets the data for the items to be sorted
882     //    std::string att;
883     unsigned int ty=0;
884     int nbselected = 0;
885     int n = GetCtrl(level)->GetItemCount();
886     for (int i = 0; i < n; i++)
887       {
888         
889         //Gets current item data
890         ItemData* data = (ItemData*)GetCtrl(level)->GetItemData(i);
891         
892         //Extracts the node and the type of attribute   
893         tree::Node* nod = data->node;
894         if(i==0)
895           {
896             (*nod).GetAttributeDescriptor
897               (mLevelList[level].key[mLevelList[level].SortColumn])
898               .DecodeType( ty );
899           }
900         //Obtains the organizing attribute
901         data->attr = & (*nod).GetAttribute
902           (mLevelList[level].key[mLevelList[level].SortColumn]);
903         //Selected ?
904         data->selected = false;
905         if (GetCtrl(level)->GetItemState(i,wxLIST_STATE_SELECTED)>0)
906           {
907             data->selected = true;
908             nbselected++;
909           }
910
911       } 
912     GimmickDebugMessage(1,
913                         "WxTreeView::OnSort : " 
914                         <<nbselected<<" selected before sorting"
915                         <<std::endl);  
916
917     mIgnoreSelectedChanged = true; 
918     // 
919     if (mLevelList[level].SortAscending)
920       {
921         
922         if(ty==1)
923           {
924             GetCtrl(level)->SortItems(CompareFunctionInts, 0);
925           }
926         else
927           {
928             GetCtrl(level)->SortItems(CompareFunctionStrings, 0);
929           }
930         
931       }
932     else
933       {
934         if(ty==1)
935           {
936             GetCtrl(level)->SortItems(CompareFunctionInts, 1);
937           }
938         else
939           {
940             GetCtrl(level)->SortItems(CompareFunctionStrings, 1);
941           }
942       }
943  
944
945     // Reselects the unselected 
946     n = GetCtrl(level)->GetItemCount();
947     int after = 0;
948     for (int i = 0; i < n; i++)
949       {
950         
951         //Gets current item data
952         ItemData* data = (ItemData*)GetCtrl(level)->GetItemData(i);
953   
954         //  long item = -1;
955         //    for ( ;; )
956         //      {
957         //      item = GetCtrl(level)->GetNextItem(item,wxLIST_NEXT_ALL);
958         //      if ( item == -1 ) break;
959         //Gets current item data
960         //      ItemData* data = (ItemData*)GetCtrl(level)->GetItemData(item);
961         // was selected ?
962         
963         if (data->selected)
964           {
965             nbselected--;
966             if (nbselected==0)
967               {
968                 // if it is the last one we must process the selection
969                 mIgnoreSelectedChanged = false;
970               }
971             GetCtrl(level)->SetItemState(i,
972                                          wxLIST_STATE_SELECTED, 
973                                          wxLIST_MASK_STATE 
974                                          | wxLIST_MASK_TEXT 
975                                          | wxLIST_MASK_IMAGE 
976                                          | wxLIST_MASK_DATA 
977                                          | wxLIST_MASK_WIDTH 
978                                          | wxLIST_MASK_FORMAT);   
979           }
980         if (GetCtrl(level)->GetItemState(i,wxLIST_STATE_SELECTED)>0)
981           {
982             after++;
983           }
984
985         
986       }
987     mIgnoreSelectedChanged = false; 
988      GimmickDebugMessage(1,
989                         "WxTreeView::SortLevel : " 
990                         <<after<<" selected after sorting"
991                         <<std::endl);  
992   
993   }
994   //================================================================
995
996   
997   //================================================================
998   void WxTreeView::ValidateSelectedImages(bool isSelection)
999   {
1000     GimmickDebugMessage(7,
1001                         "WxTreeView::ValidateSelectedImages" 
1002                         <<std::endl);
1003     const std::vector<tree::Node*>& sel(GetSelected(mLevelList.size()+1));
1004     GetGimmickView()->OnSelectionChange(sel,
1005                                         isSelection,(mLastSelected-1),
1006                                         !mIgnoreSelectedChanged);
1007  
1008   }
1009   //================================================================
1010
1011
1012   //================================================================
1013   void WxTreeView::GetNodes(std::vector<tree::Node*>& nodes, bool direction)
1014   {
1015         long item = mLastSelected;
1016         int level=mLevelList.size()-1;
1017         //Gets current item data
1018         long adr = GetCtrl(level)->GetItemData(item);
1019         //Extracts the node
1020         tree::Node* nod = ((ItemData*)adr)->node;
1021     for ( ;; )
1022     {
1023                 if(direction)
1024                 {
1025                         item = GetCtrl(level)->GetNextItem(item,
1026                                      wxLIST_NEXT_ABOVE);
1027                 }
1028                 else
1029                 {
1030                         item = GetCtrl(level)->GetNextItem(item,
1031                                      wxLIST_NEXT_BELOW);
1032                 }
1033         if ( item == -1 || item==0  )
1034                 {
1035             break;
1036                 }
1037                 if(GetCtrl(level)->GetItemState(item, wxLIST_STATE_SELECTED)==0 )
1038                 {
1039
1040                         adr = GetCtrl(level)->GetItemData(item);
1041                         nod = ((ItemData*)adr)->node;
1042                         nodes.push_back(nod);
1043                 }
1044     }
1045
1046   }
1047   //================================================================
1048    //=================================================
1049   void WxTreeView::OnKeyDown(wxListEvent &event)
1050   {
1051           if(event.GetKeyCode() == WXK_DELETE)
1052           {
1053                    wxBusyCursor busy;
1054                    std::string temp = "0";
1055                    RemoveSelected(temp);
1056                    GetGimmickView()->ClearSelection();
1057           }
1058                   
1059   }
1060   //================================================================
1061
1062   //================================================================
1063   // Should be in another place : not specific !
1064   void WxTreeView::GetSelectedAsString(std::vector<std::string>&s)
1065   {
1066     int level=mLevelList.size();
1067     const std::vector<tree::Node*>& sel=GetSelected(level+1);
1068     std::vector<tree::Node*>::const_iterator i;
1069     
1070     for (i=sel.begin(); i!=sel.end(); ++i)
1071       {
1072         std::string filename=(*i)->GetAttribute("FullFileName");
1073         s.push_back(filename);
1074       }
1075   }
1076
1077   //================================================================
1078   void WxTreeView::GetFilenamesAsString(const std::vector<tree::Node*>& nodes, std::vector<std::string>&s)
1079   {
1080     std::vector<tree::Node*>::const_iterator i;
1081     
1082     for (i=nodes.begin(); i!=nodes.end(); ++i)
1083       {
1084                   if((*i)->GetLevel()<mLevelList.size())
1085                   {
1086                          GetTreeHandler()->LoadChildren(*i,0);
1087                          GetFilenamesAsString((*i)->GetChildrenList(),s);
1088                   }
1089                   else
1090                   {
1091                         std::string filename=(*i)->GetAttribute("FullFileName");
1092                         s.push_back(filename);
1093                   }
1094       }
1095   }
1096
1097    //================================================================
1098
1099    //================================================================
1100   void WxTreeView::GetAttributes(std::vector<std::string>& areShown, std::vector<std::string>& notShown, int level)
1101   {
1102           areShown.clear();
1103           notShown.clear();
1104         tree::LevelDescriptor::AttributeDescriptorListType::const_iterator a;
1105         for (a  = GetTreeHandler()->GetTree().GetAttributeDescriptorList(level).begin();
1106              a != GetTreeHandler()->GetTree().GetAttributeDescriptorList(level).end();
1107              ++a)
1108         {
1109                 if(a->GetFlags()==creaImageIO::tree::AttributeDescriptor::EDITABLE && IsAttributeVisible(a->GetName(),level))
1110             {
1111                         areShown.push_back(a->GetName());
1112                 }
1113         }
1114         notShown=mLevelList[level-1].notShownAtts;
1115   }
1116
1117   //================================================================
1118   void WxTreeView::SetNonVisibleAttributes(const std::vector<std::string>& notShown, int nlevel)
1119   {
1120         mLevelList[nlevel].notShownAtts=notShown;
1121   }
1122
1123   //================================================================
1124    void WxTreeView::CreateCtrl(std::vector<std::string>& notShown, int nlevel)
1125   {
1126         int ctrl_style = wxLC_REPORT | wxLC_VRULES;
1127     int col_style = wxLIST_FORMAT_LEFT;
1128         LevelType level;
1129         mLevelList[nlevel].SelectedUpToDate = true;
1130         mLevelList[nlevel].SortColumn = 0;
1131         mLevelList[nlevel].key.clear();
1132         
1133         mLevelList[nlevel].wxCtrl = new wxListCtrl(mLevelList[nlevel].wxSplitter,
1134                                           nlevel,
1135                                           wxDefaultPosition, 
1136                                           wxDefaultSize,
1137                                           ctrl_style);
1138         wxWindow* oldWin=mLevelList[nlevel].wxSplitter->GetWindow1();
1139         mLevelList[nlevel].wxSplitter->ReplaceWindow(oldWin,mLevelList[nlevel].wxCtrl);
1140         mLevelList[nlevel].wxSplitter->Initialize(mLevelList[nlevel].wxCtrl);
1141    
1142         // Create the columns : one for each attribute of the level
1143         int col = 0;
1144         std::string title;
1145
1146         tree::LevelDescriptor::AttributeDescriptorListType::const_iterator a;
1147         for (a  = GetTreeHandler()->GetTree().GetAttributeDescriptorList(nlevel+1).begin();
1148              a != GetTreeHandler()->GetTree().GetAttributeDescriptorList(nlevel+1).end();
1149              ++a)
1150
1151         {   
1152             if(a->GetFlags()!=creaImageIO::tree::AttributeDescriptor::PRIVATE && IsAttributeVisible(a->GetName(),nlevel+1))
1153               {
1154                   title=a->GetName();
1155                   std::string temp = a->GetKey();
1156                   if (temp.compare("ID") != 0)
1157                   {
1158                         mLevelList[nlevel].wxCtrl->InsertColumn(col, 
1159                                         crea::std2wx(title),
1160                                         col_style);
1161                         col++;
1162                   }
1163                 mLevelList[nlevel].key.push_back(a->GetKey());
1164               }
1165                 
1166           }
1167         oldWin->Destroy();
1168         UpdateLevel(1);
1169         }
1170
1171    //================================================================
1172   bool WxTreeView::IsAttributeVisible(const std::string& val, int level)
1173   {
1174           std::vector<std::string> ns=mLevelList[level-1].notShownAtts;
1175           std::vector<std::string>::iterator it;
1176           bool found=false;
1177           for(it=ns.begin();it!=ns.end()&&!found;++it)
1178           {
1179                   if(val.compare(*it)==0)
1180                   {
1181                           found=true;
1182                   }
1183           }
1184
1185           return !found;
1186   }
1187  //================================================================
1188   //================================================================
1189
1190         RemoveAlertDlg::RemoveAlertDlg(wxWindow *parent, 
1191                                                wxString title,    
1192                                                    const wxSize& size)
1193  :   wxDialog( parent, 
1194                   wxID_ANY, 
1195                   title,
1196                   wxDefaultPosition,
1197                   size,
1198                   wxDEFAULT_DIALOG_STYLE)
1199         {
1200             wxBoxSizer *topsizer = new wxBoxSizer(wxVERTICAL);
1201
1202                 std::string out = "To reload deleted patient, you should synchornize your database before.";
1203                 wxTextCtrl *text = new wxTextCtrl(this, wxID_ANY,crea::std2wx(out),wxDefaultPosition, wxSize(500,20));
1204                 mcheck = new wxCheckBox(this, 5478, "not display this warning again!");
1205                 Connect( mcheck->GetId(), wxEVT_COMMAND_CHECKBOX_CLICKED , (wxObjectEventFunction) &RemoveAlertDlg::onCheck ); 
1206                 wxSizer* buttonsSizer = this->CreateSeparatedButtonSizer(wxOK|wxCANCEL);
1207                 
1208                 topsizer->Add(text);
1209                 topsizer->Add(mcheck,0,wxGROW);
1210                 topsizer->Add(buttonsSizer,0,wxGROW);
1211                 SetSizer(topsizer, true);
1212                 mSave = false;
1213                 Layout();
1214         }
1215         RemoveAlertDlg::~RemoveAlertDlg(){};
1216         bool RemoveAlertDlg::isChecked()
1217         {
1218                 return mSave;
1219         }
1220         void RemoveAlertDlg::onCheck(wxCommandEvent &Event)
1221         {
1222                 mSave = mcheck->IsChecked();
1223         }
1224         
1225
1226   //================================================================
1227   //================================================================
1228   BEGIN_EVENT_TABLE(WxTreeView, wxPanel)   
1229   /*
1230     EVT_SIZE(MyFrame::OnSize)
1231
1232     EVT_MENU(LIST_QUIT, MyFrame::OnQuit)
1233     EVT_MENU(LIST_ABOUT, MyFrame::OnAbout)
1234     EVT_MENU(LIST_LIST_VIEW, MyFrame::OnListView)
1235     EVT_MENU(LIST_REPORT_VIEW, MyFrame::OnReportView)
1236     EVT_MENU(LIST_ICON_VIEW, MyFrame::OnIconView)
1237     EVT_MENU(LIST_ICON_TEXT_VIEW, MyFrame::OnIconTextView)
1238     EVT_MENU(LIST_SMALL_ICON_VIEW, MyFrame::OnSmallIconView)
1239     EVT_MENU(LIST_SMALL_ICON_TEXT_VIEW, MyFrame::OnSmallIconTextView)
1240     EVT_MENU(LIST_VIRTUAL_VIEW, MyFrame::OnVirtualView)
1241     EVT_MENU(LIST_SMALL_VIRTUAL_VIEW, MyFrame::OnSmallVirtualView)
1242
1243     EVT_MENU(LIST_FOCUS_LAST, MyFrame::OnFocusLast)
1244     EVT_MENU(LIST_TOGGLE_FIRST, MyFrame::OnToggleFirstSel)
1245     EVT_MENU(LIST_DESELECT_ALL, MyFrame::OnDeselectAll)
1246     EVT_MENU(LIST_SELECT_ALL, MyFrame::OnSelectAll)
1247     EVT_MENU(LIST_DELETE, MyFrame::OnDelete)
1248     EVT_MENU(LIST_ADD, MyFrame::OnAdd)
1249     EVT_MENU(LIST_EDIT, MyFrame::OnEdit)
1250     EVT_MENU(LIST_DELETE_ALL, MyFrame::OnDeleteAll)
1251     EVT_MENU(LIST_SORT, MyFrame::OnSort)
1252     EVT_MENU(LIST_SET_FG_COL, MyFrame::OnSetFgColour)
1253     EVT_MENU(LIST_SET_BG_COL, MyFrame::OnSetBgColour)
1254     EVT_MENU(LIST_TOGGLE_MULTI_SEL, MyFrame::OnToggleMultiSel)
1255     EVT_MENU(LIST_SHOW_COL_INFO, MyFrame::OnShowColInfo)
1256     EVT_MENU(LIST_SHOW_SEL_INFO, MyFrame::OnShowSelInfo)
1257     EVT_MENU(LIST_FREEZE, MyFrame::OnFreeze)
1258     EVT_MENU(LIST_THAW, MyFrame::OnThaw)
1259     EVT_MENU(LIST_TOGGLE_LINES, MyFrame::OnToggleLines)
1260     EVT_MENU(LIST_MAC_USE_GENERIC, MyFrame::OnToggleMacUseGeneric)
1261
1262     EVT_UPDATE_UI(LIST_SHOW_COL_INFO, MyFrame::OnUpdateShowColInfo)
1263     EVT_UPDATE_UI(LIST_TOGGLE_MULTI_SEL, MyFrame::OnUpdateToggleMultiSel)
1264 END_EVENT_TABLE()
1265
1266 BEGIN_EVENT_TABLE(MyListCtrl, wxListCtrl)
1267     EVT_LIST_BEGIN_DRAG(LIST_CTRL, MyListCtrl::OnBeginDrag)
1268     EVT_LIST_BEGIN_RDRAG(LIST_CTRL, MyListCtrl::OnBeginRDrag)
1269         
1270     EVT_LIST_BEGIN_LABEL_EDIT(-1, WxTreeView::OnBeginLabelEdit)
1271     EVT_LIST_END_LABEL_EDIT(-1, WxTreeView::OnEndLabelEdit)
1272         
1273     EVT_LIST_DELETE_ITEM(LIST_CTRL, MyListCtrl::OnDeleteItem)
1274     EVT_LIST_DELETE_ALL_ITEMS(LIST_CTRL, MyListCtrl::OnDeleteAllItems)
1275 #if WXWIN_COMPATIBILITY_2_4
1276     EVT_LIST_GET_INFO(LIST_CTRL, MyListCtrl::OnGetInfo)
1277     EVT_LIST_SET_INFO(LIST_CTRL, MyListCtrl::OnSetInfo)
1278 #endif
1279   */
1280     EVT_LIST_KEY_DOWN(-1, WxTreeView::OnKeyDown)
1281     EVT_LIST_ITEM_SELECTED(-1, WxTreeView::OnItemSelected)
1282         EVT_LIST_ITEM_RIGHT_CLICK(-1, WxTreeView::OnItemMenu)
1283     EVT_LIST_ITEM_DESELECTED(-1, WxTreeView::OnItemDeSelected)
1284         /*
1285     EVT_LIST_KEY_DOWN(LIST_CTRL, MyListCtrl::OnListKeyDown)
1286     EVT_LIST_ITEM_ACTIVATED(LIST_CTRL, MyListCtrl::OnActivated)
1287     EVT_LIST_ITEM_FOCUSED(LIST_CTRL, MyListCtrl::OnFocused)
1288 */
1289     EVT_LIST_COL_RIGHT_CLICK(-1, WxTreeView::OnColClick)
1290         
1291     EVT_LIST_COL_CLICK(-1, WxTreeView::OnColClick)
1292
1293         //EVT_LEFT_DOWN(WxTreeView::OnMouseClick)
1294         /*
1295     EVT_LIST_COL_BEGIN_DRAG(LIST_CTRL, MyListCtrl::OnColBeginDrag)
1296     EVT_LIST_COL_DRAGGING(LIST_CTRL, MyListCtrl::OnColDragging)
1297     EVT_LIST_COL_END_DRAG(LIST_CTRL, MyListCtrl::OnColEndDrag)
1298
1299     EVT_LIST_CACHE_HINT(LIST_CTRL, MyListCtrl::OnCacheHint)
1300
1301 #if USE_CONTEXT_MENU
1302     EVT_CONTEXT_MENU(MyListCtrl::OnContextMenu)
1303 #endif
1304     EVT_CHAR(MyListCtrl::OnChar)
1305
1306     EVT_RIGHT_DOWN(MyListCtrl::OnRightClick)
1307   */
1308 END_EVENT_TABLE()
1309   
1310 } // EO namespace creaImageIO
1311