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