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