]> Creatis software - creaImageIO.git/blob - src2/creaImageIOWxTreeView.cpp
49c72ef98bd8d61bcc1c0be867ab7dade7677570
[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 #include <boost/date_time/posix_time/posix_time.hpp>
8 #include <boost/date_time/local_time_adjustor.hpp>
9 #include <boost/date_time/c_local_time_adjustor.hpp>
10
11
12
13
14 const std::string empty_string("");
15
16 //=====================================================================
17 namespace creaImageIO
18 {
19   //=====================================================================
20   /// Data stored by the list items
21   struct ItemData
22   {
23     ItemData() : node(0), id(-1), attr(&empty_string) {}
24     // The corresponding Node
25     tree::Node* node;
26     // The id ?
27     int id;
28     // The pointer on the current attribute string to sort on
29     const std::string* attr;
30     // Was the item previously selected ?
31     // Useful for reselecting the item after sort
32     bool selected;
33   };
34   //=====================================================================
35 }
36 //=====================================================================
37
38 //=====================================================================
39 ///Comparing function for ordering algorithm. Takes parameters as strings.
40 int wxCALLBACK CompareFunctionStrings(long item1, long item2, long sortData)
41 {       
42   creaImageIO::ItemData* data1 = (creaImageIO::ItemData*)item1;
43   creaImageIO::ItemData* data2 = (creaImageIO::ItemData*)item2;
44
45   const std::string& s1(*(data1->attr));
46   const std::string& s2(*(data2->attr));
47   if(sortData==1)
48     {
49       // inverse the order
50       if (s1 < s2)
51         return 1;
52       if (s1 > s2)
53         return -1;
54       
55       return 0;
56     }
57   else
58     {
59       if (s1 < s2)
60         return -1;
61       if (s1 > s2)
62         return 1;
63       
64       return 0;
65       
66     }
67 }
68 //=====================================================================
69
70 //=====================================================================
71 ///Comparing function for ordering algorithm. Takes parameters as ints.
72 int wxCALLBACK CompareFunctionInts(long item1, long item2, long sortData)
73 {       
74   creaImageIO::ItemData* data1 = (creaImageIO::ItemData*)item1;
75   creaImageIO::ItemData* data2 = (creaImageIO::ItemData*)item2;
76
77   const std::string& s1(*(data1->attr));
78   const std::string& s2(*(data2->attr));
79
80   int val1=atoi(s1.c_str());
81   int val2=atoi(s2.c_str());
82
83   if(sortData==1)
84     {
85       // inverse the order
86       if (val1 < val2)
87         return 1;
88       if (val1 > val2)
89         return -1;
90       
91       return 0;
92     }
93   else
94     {
95       if (val1 < val2)
96         return -1;
97       if (val1 > val2)
98         return 1;
99
100       return 0;
101       
102     }
103   
104 }
105
106 //=====================================================================
107
108
109 //=====================================================================
110 namespace creaImageIO
111 {
112   //=====================================================================
113   // CTor
114   WxTreeView::WxTreeView(TreeHandler* handler,
115                          GimmickView* gimmick,
116                          wxWindow* parent,
117                          const wxWindowID id)
118     : wxPanel(parent,id),
119       TreeView(handler,gimmick)
120   {
121     GimmickDebugMessage(1,"WxTreeView::WxTreeView"
122                         <<std::endl);
123
124     
125     // Split part below toolbar into notebook for views and panel
126     // for preview, messages...
127     // TO DO : Splitter
128     //    mSplitter = new wxSplitterWindow( this , -1);
129
130     // Global sizer
131     wxBoxSizer  *sizer = new wxBoxSizer(wxHORIZONTAL);
132     
133     int ctrl_style = wxLC_REPORT | wxLC_VRULES;
134     int col_style = wxLIST_FORMAT_LEFT;
135
136     // Creating the ListCtrl for the levels > 0 (not for Root level)
137     for (int i = 0;
138          i < handler->GetTree().GetNumberOfLevels() -1;
139          ++i)
140       {
141
142         GimmickDebugMessage(5,"Creating view for level "<<i
143                             <<std::endl);
144         LevelType level;
145         level.SelectedUpToDate = true;
146         level.SortColumn = 0;
147
148         // If the first level : parent = this
149         wxWindow* sparent = this;
150         // else parent = last splitter
151         if (i>0) 
152                 sparent = mLevelList[i-1].wxSplitter;
153
154         level.wxSplitter = new wxSplitterWindow( sparent , -1);
155         if(i!=0)
156         {
157         level.wxSplitter->Show(false);
158         }
159         //          level.wxSplitter->SetMinimumPaneSize(100);
160         
161         wxListCtrl* ctrl = new wxListCtrl(level.wxSplitter,
162                                           i,
163                                           wxDefaultPosition, 
164                                           wxDefaultSize,
165                                           ctrl_style);
166         level.wxCtrl = ctrl;
167         level.wxSplitter->Initialize(ctrl);
168
169
170         // Create the columns : one for each attribute of the level
171         int col = 0;
172         std::string title;
173         tree::LevelDescriptor::AttributeDescriptorListType::const_iterator a;
174         for (a  = handler->GetTree().GetAttributeDescriptorList(i+1).begin();
175              a != handler->GetTree().GetAttributeDescriptorList(i+1).end();
176              ++a)
177
178 {
179         
180             GimmickDebugMessage(5,"Creating column "<<col<<" : "
181                                 <<a->GetName()
182                                 <<std::endl);
183             
184             if(a->GetFlags()!=creaImageIO::tree::AttributeDescriptor::PRIVATE)
185               {
186                 
187                 if(a->GetName()=="UNKNOWN")
188                   {
189                     title = "#";
190                     title += handler->GetTree().GetLevelDescriptor(i+1).GetName();
191                     if (title[title.size()-1]!='s')
192                       title += "s";
193                     
194                   }
195                 else
196                   {
197                     title=a->GetName();
198                   }
199                   std::string temp = a->GetKey();
200                   if (temp.compare("ID") != 0)
201                   {
202                 ctrl->InsertColumn(col, 
203                                    crea::std2wx(title),
204                                    col_style);
205                 col++;
206                   }
207                 level.key.push_back(a->GetKey());
208
209                 //          ctrl->SetColumnWidth(col, wxLIST_AUTOSIZE );
210
211                 
212               }
213                 
214           }
215           
216         mLevelList.push_back(level);
217       }
218     
219 #if wxUSE_MENUS
220
221     menu =new wxMenu;
222         wxMenuItem* m1=menu->Append(wxID_ANY, _T("&Sort ascending"));
223         wxMenuItem* m2=menu->Append(wxID_ANY, _T("&Sort descending"));
224         wxMenuItem* m3=menu->Append(wxID_ANY, _T("&Filter"));
225         mAscendingID=m1->GetId();
226         mDescendingID=m2->GetId();
227         mFilterID=m3->GetId();
228         Connect( mAscendingID, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(WxTreeView::OnPopupSort) );
229         Connect( mDescendingID, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(WxTreeView::OnPopupSort) );
230         Connect( mFilterID, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(WxTreeView::OnPopupFilter) );
231         
232 #endif // wxUSE_MENUS
233
234
235         /// Initialize the first level splitter
236           
237         sizer->Add( mLevelList[0].wxSplitter ,1, wxGROW  ,0);
238         //      mColumnSelected=1;
239         mLastSelected=0;
240         mLastLevel=0;
241         //      mDirection=true;
242
243         mIgnoreSelectedChanged = false;
244
245         //CreateColorPalette();
246     UpdateLevel(1);
247
248     SetSizer( sizer );     
249     SetAutoLayout(true);
250     Layout();
251
252   }
253   //=====================================================================
254
255   //=====================================================================
256   /// Destructor
257   WxTreeView::~WxTreeView()
258   {
259     GimmickDebugMessage(1,"WxTreeView::~WxTreeView"
260                         <<std::endl);
261   }
262   //=====================================================================
263   
264   
265   
266   //=====================================================================
267    const std::vector<tree::Node*>& WxTreeView::GetSelected(int level)
268   {
269     //  if (GetSelectedUpToDate(level)) 
270     
271     int l = level - 1;
272     // the selection of upper level
273     std::vector<tree::Node*>& sel(mLevelList[level-1].Selected);
274     sel.clear();
275
276     if (level == 1) 
277       {
278         sel.push_back(GetTreeHandler()->GetTree().GetTree());
279       }
280     else if (level < 5) 
281     {
282                 int n = GetCtrl(l-1)->GetItemCount();
283                 for (int i = 0; i < n; i++)
284                 {
285                         if ( GetCtrl(l-1)->GetItemState(i,wxLIST_STATE_SELECTED))
286                         {
287                                 long adr = GetCtrl(l-1)->GetItemData(i);
288                                 tree::Node* n = ((ItemData*)adr)->node;
289                                 if(mLastSelected==i)
290                                 {
291                                         std::vector<tree::Node*>::iterator it;
292                                         it = sel.begin();
293                                         it = sel.insert ( it , n );
294                                 }
295                                 else
296                                 {
297                                         sel.push_back(n);
298                                 }
299                         }
300               }
301           }
302         else
303         {
304                 // NOTHING
305         }
306
307      
308          
309     //    return mLevelList[level-1].Selected;
310     return sel;
311   }
312
313   //=====================================================================
314   
315   //=====================================================================
316   ///Removes selected nodes on last selected level
317    // NOT SPECIFIC 
318   void WxTreeView::RemoveSelected()
319   {
320           unsigned int tempLevel = mLastLevel;
321     mLastLevel+=1;
322     const std::vector<tree::Node*>& sel=GetSelected(mLastLevel+1);
323         // if no selection, no remove action.
324     if(sel.size() != 0)
325         {
326             bool erase=false;
327             std::stringstream out;
328             std::string levelName=GetTreeHandler()->GetTree().GetLevelDescriptor(mLastLevel).GetName();
329             out<<"Delete ";
330             out<<sel.size();
331             if(sel.size()>1&&levelName.at(levelName.size()-1)!='s')
332               {
333                 out<<" "<<levelName;
334                 out<<"s?";
335               }
336             else
337               {
338                 out<<" "<<GetTreeHandler()->GetTree().GetLevelDescriptor(mLastLevel).GetName()<<"?";
339               }
340             if (wxMessageBox(crea::std2wx(out.str()),
341                              _T("Remove Files"),
342                              wxYES_NO,this ) == wxYES)
343               {
344                 erase = true;
345               }
346             if(erase)
347                   {
348                     bool needRefresh=false;
349                     std::vector<tree::Node*>::const_iterator i;
350                     for (i=sel.begin(); i!=sel.end(); ++i)
351                       {
352                         GimmickMessage(1,
353                                        "deleting '"
354                                        <<(*i)->GetLabel()
355                                        <<"'"<<mLastLevel
356                                        <<std::endl);
357                         if((*i)->GetParent()->GetNumberOfChildren()<2)
358                           {
359                             needRefresh=true;
360                           }
361                         GetTreeHandler()->Remove(*i);
362                       }
363                     
364                     if(needRefresh && mLastLevel>1)
365                       {
366                         UpdateLevel(mLastLevel-2);
367                       }
368                     else if(mLastLevel>1)
369                       {
370                         UpdateLevel(mLastLevel-1);
371                       }
372                     else
373                       {
374                         UpdateLevel(mLastLevel);
375                       }
376                   }
377         }
378         else
379         {
380                 // no need to incremente level
381                 mLastLevel = tempLevel;
382         }
383     
384   }
385   
386   
387   //=====================================================================
388
389  
390   //=====================================================================
391   /// Updates a level of the view (adds or removes children, etc.)
392   void WxTreeView::UpdateLevel( int level )
393   {
394     GimmickDebugMessage(1,
395                         GetTreeHandler()->GetTree().GetLabel()
396                         <<"WxTreeView::UpdateLevel(level "
397                         <<level
398                         <<")"
399                         <<std::endl);
400     
401     wxBusyCursor busy;
402     RecursiveUpdateLevel(level);
403     int i;
404     for (i=0; i<level-1; i++)
405       {
406         if (!GetSplitter(i)->IsSplit()) 
407           GetSplitter(i)->SplitVertically(  GetCtrl(i), GetSplitter(i+1),
408                                             100 );
409       }
410     if (GetSplitter(i)->IsSplit()) GetSplitter(i)->Unsplit();    
411     
412   }
413   //=====================================================================
414   
415  //=====================================================================
416   /// Recursive method called upon by UpdateLevel to refresh all windows
417   void WxTreeView::RecursiveUpdateLevel( int level )
418   {
419     GimmickDebugMessage(1,
420                         GetTreeHandler()->GetTree().GetLabel()
421                         <<"WxTreeView::RecursiveUpdateLevel(level "
422                         <<level
423                         <<")"<<std::endl);
424     
425
426     const std::vector<tree::Node*>& sel(GetSelected(level));
427
428     int l = level - 1;
429  
430     // to speed up inserting we hide the control temporarily
431     GetCtrl(l)->Hide();
432     GetCtrl(l)->DeleteAllItems();
433     
434     std::vector<tree::Node*>::const_iterator i;
435     
436     for (i=sel.begin(); i!=sel.end(); ++i)
437       {
438         GimmickDebugMessage(1,
439                             "adding children of '"
440                             <<(*i)->GetLabel()
441                             <<"'"
442                             <<std::endl);
443         int _id=0;
444         
445         //Adds items and sets their attributes 
446
447         GetTreeHandler()->LoadChildren(*i,1);
448         tree::Node::ChildrenListType::reverse_iterator j;
449         for (j = (*i)->GetChildrenList().rbegin(); 
450              j!= (*i)->GetChildrenList().rend(); 
451              ++j)
452           {
453                         GimmickDebugMessage(1,
454                                                 "adding children "
455                                                 <<(*j)->GetLabel()
456                                                 <<"'"
457                                                 <<std::endl);
458
459                                 wxListItem item;
460                                 item.SetMask(wxLIST_MASK_STATE | 
461                                         wxLIST_MASK_TEXT |
462                                         //                       wxLIST_MASK_IMAGE |
463                                         wxLIST_MASK_DATA |
464                                         //                       wxLIST_MASK_WIDTH |
465                                         wxLIST_MASK_FORMAT
466                                         );
467                             
468                                 ItemData* data = new ItemData;
469                                 data->node = *j;
470                                 data->id = _id;
471
472                                 item.SetId(_id);
473                                 item.SetData(data);
474                             
475                                 _id++;
476                                 GetCtrl(l)->InsertItem(item);
477                             
478                                 //Setting attributes
479                             
480                                 for (int k=0; k<GetCtrl(l)->GetColumnCount(); k++)
481                                 {
482                                         std::string val = (*j)->GetAttribute(mLevelList[l].key[k]);
483                                         if(((*j)->GetAttributeDescriptor(mLevelList[l].key[k])).isDateEntry())
484                                         {
485                                                 boost::gregorian::date d1(boost::gregorian::from_undelimited_string(val));
486                                                 val = to_iso_extended_string(d1);
487                                         }
488                                         else if(((*j)->GetAttributeDescriptor(mLevelList[l].key[k])).isTimeEntry())
489                                         {
490                                                 if (val != "" || val != " ")
491                                                         val = val.substr(0,2) + " : " + val.substr(2,2) + " : " + val.substr(4,2);
492                                         }
493                                         else
494                                         {
495
496                                         }
497                                         if (val.size()==0) val = "?";
498                                         item.SetText( crea::std2wx(val));
499                                         item.SetColumn(k);
500                                         GetCtrl(l)->SetItem(item);
501                                 }       
502                             
503                         }
504       }
505
506     SortLevel(l);
507     GetCtrl(l)->Show();
508  }
509   //=====================================================================
510
511
512   //================================================================
513   void WxTreeView::OnItemDeSelected(wxListEvent& event)
514   { 
515     GimmickDebugMessage(1,
516                         GetTreeHandler()->GetTree().GetLabel()
517                         <<" WxTreeView::OnItemDeselected"<<std::endl);
518     // retrieve the level
519     wxObject* obj = event.GetEventObject();   
520     unsigned int level = 0;
521     for (level = 0; level<mLevelList.size(); ++level)
522       {
523         if ( GetCtrl(level) == obj ) break;
524       } 
525     SetSelectedUpToDate(level,false);
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                     RemoveSelected();
899                 //      ClearSelection();
900           }
901                   
902   }
903   //================================================================
904
905   //================================================================
906   // Should be in another place : not specific !
907   void WxTreeView::GetSelectedAsString(std::vector<std::string>&s)
908   {
909     int level=mLevelList.size();
910     const std::vector<tree::Node*>& sel=GetSelected(level+1);
911     std::vector<tree::Node*>::const_iterator i;
912     
913     for (i=sel.begin(); i!=sel.end(); ++i)
914       {
915         std::string filename=(*i)->GetAttribute("FullFileName");
916         s.push_back(filename);
917       }
918   }
919
920    //================================================================
921   void WxTreeView::SetColor(int l, int item)
922   {
923           int colorId=12;
924           GetCtrl(l)->SetItemTextColour(item, wxColourDatabase().Find
925                    (crea::std2wx(mColorPalette[colorId])));
926           GetCtrl(l)->SetItemState(item,wxLIST_STATE_SELECTED | wxLIST_STATE_FOCUSED, wxLIST_STATE_SELECTED);  /*
927           int colorId=0;
928           //Setting the color according to the parent
929                 if(l==0)
930                 {
931                 item.SetBackgroundColour
932                   (wxColourDatabase().Find
933                    (crea::std2wx(mColorPalette[colorId]))); 
934                 mColorMap.insert
935                   (NodeColorPair
936                    (*j,wxColourDatabase().Find
937                     (crea::std2wx(mColorPalette[colorId]))));
938                 if(colorId<64)
939                   {
940                     colorId++;
941                   }
942                 else
943                         {
944                           colorId=0;
945                         }
946                 }
947                 else if(l!=mLevelList.size()-1)
948                   {
949                     item.SetBackgroundColour(mColorMap[*i]); 
950                         mColorMap.insert(NodeColorPair(*j,mColorMap[*i]));
951                 }
952                 else
953                 {
954                         item.SetBackgroundColour(mColorMap[*i]); 
955                 }*/
956   }
957   //================================================================
958   void WxTreeView::CreateColorPalette()
959   {
960   GimmickDebugMessage(6,"WxTreeView::CreateColorPalette");
961   mColorPalette.push_back("WHITE");
962   mColorPalette.push_back("LIGHT GREY");
963   mColorPalette.push_back("AQUAMARINE");
964   mColorPalette.push_back("MEDIUM FOREST GREEN");
965   mColorPalette.push_back("INDIAN RED");
966   mColorPalette.push_back("KHAKI");
967   mColorPalette.push_back("ORANGE");
968   mColorPalette.push_back("LIGHT BLUE");
969   mColorPalette.push_back("LIGHT STEEL BLUE");
970   mColorPalette.push_back("PINK");
971   mColorPalette.push_back("PLUM");
972   mColorPalette.push_back("PURPLE");
973   mColorPalette.push_back("RED");
974   mColorPalette.push_back("SEA GREEN");
975   mColorPalette.push_back("SIENNA");
976   mColorPalette.push_back("SKY BLUE");
977   mColorPalette.push_back("SLATE BLUE");
978   mColorPalette.push_back("SPRING GREEN");
979   mColorPalette.push_back("TAN");
980   mColorPalette.push_back("THISTLE");
981   mColorPalette.push_back("TURQUOISE");
982   mColorPalette.push_back("VIOLET");
983   mColorPalette.push_back("VIOLET RED");
984   mColorPalette.push_back("WHEAT");
985   mColorPalette.push_back("YELLOW");
986   mColorPalette.push_back("YELLOW GREEN");
987   mColorPalette.push_back("BLUE");
988   mColorPalette.push_back("BLUE VIOLET");
989   mColorPalette.push_back("BROWN");
990   mColorPalette.push_back("CADET BLUE");
991   mColorPalette.push_back("CORAL");
992   mColorPalette.push_back("CORNFLOWER BLUE");
993   mColorPalette.push_back("CYAN");
994   mColorPalette.push_back("DARK GREY");
995   mColorPalette.push_back("DARK GREEN");
996   mColorPalette.push_back("DARK OLIVE GREEN");
997   mColorPalette.push_back("DARK ORCHID");
998   mColorPalette.push_back("DARK SLATE BLUE");
999   mColorPalette.push_back("DARK SLATE GREY");
1000   mColorPalette.push_back("DARK TURQUOISE");
1001   mColorPalette.push_back("FIREBRICK");
1002   mColorPalette.push_back("FOREST GREEN");
1003   mColorPalette.push_back("GOLD");
1004   mColorPalette.push_back("GOLDENROD");
1005   mColorPalette.push_back("GREY");
1006   mColorPalette.push_back("GREEN");
1007   mColorPalette.push_back("GREEN YELLOW");
1008   mColorPalette.push_back("LIME GREEN");
1009   mColorPalette.push_back("MAGENTA");
1010   mColorPalette.push_back("MAROON");
1011   mColorPalette.push_back("MEDIUM AQUAMARINE");
1012   mColorPalette.push_back("MEDIUM BLUE");
1013   mColorPalette.push_back("MEDIUM GOLDENROD");
1014   mColorPalette.push_back("MEDIUM ORCHID");
1015   mColorPalette.push_back("MEDIUM SEA GREEN");
1016   mColorPalette.push_back("MEDIUM SLATE BLUE");
1017   mColorPalette.push_back("MEDIUM SPRING GREEN");
1018   mColorPalette.push_back("MEDIUM TURQUOISE");
1019   mColorPalette.push_back("MEDIUM VIOLET RED");
1020   mColorPalette.push_back("MIDNIGHT BLUE");
1021   mColorPalette.push_back("NAVY");
1022   mColorPalette.push_back("ORANGE RED");
1023   mColorPalette.push_back("ORCHID, PALE GREEN");
1024   mColorPalette.push_back("STEEL BLUE");
1025   mColorPalette.push_back("BLACK");
1026
1027
1028   }
1029   //================================================================
1030   BEGIN_EVENT_TABLE(WxTreeView, wxPanel)   
1031   /*
1032     EVT_SIZE(MyFrame::OnSize)
1033
1034     EVT_MENU(LIST_QUIT, MyFrame::OnQuit)
1035     EVT_MENU(LIST_ABOUT, MyFrame::OnAbout)
1036     EVT_MENU(LIST_LIST_VIEW, MyFrame::OnListView)
1037     EVT_MENU(LIST_REPORT_VIEW, MyFrame::OnReportView)
1038     EVT_MENU(LIST_ICON_VIEW, MyFrame::OnIconView)
1039     EVT_MENU(LIST_ICON_TEXT_VIEW, MyFrame::OnIconTextView)
1040     EVT_MENU(LIST_SMALL_ICON_VIEW, MyFrame::OnSmallIconView)
1041     EVT_MENU(LIST_SMALL_ICON_TEXT_VIEW, MyFrame::OnSmallIconTextView)
1042     EVT_MENU(LIST_VIRTUAL_VIEW, MyFrame::OnVirtualView)
1043     EVT_MENU(LIST_SMALL_VIRTUAL_VIEW, MyFrame::OnSmallVirtualView)
1044
1045     EVT_MENU(LIST_FOCUS_LAST, MyFrame::OnFocusLast)
1046     EVT_MENU(LIST_TOGGLE_FIRST, MyFrame::OnToggleFirstSel)
1047     EVT_MENU(LIST_DESELECT_ALL, MyFrame::OnDeselectAll)
1048     EVT_MENU(LIST_SELECT_ALL, MyFrame::OnSelectAll)
1049     EVT_MENU(LIST_DELETE, MyFrame::OnDelete)
1050     EVT_MENU(LIST_ADD, MyFrame::OnAdd)
1051     EVT_MENU(LIST_EDIT, MyFrame::OnEdit)
1052     EVT_MENU(LIST_DELETE_ALL, MyFrame::OnDeleteAll)
1053     EVT_MENU(LIST_SORT, MyFrame::OnSort)
1054     EVT_MENU(LIST_SET_FG_COL, MyFrame::OnSetFgColour)
1055     EVT_MENU(LIST_SET_BG_COL, MyFrame::OnSetBgColour)
1056     EVT_MENU(LIST_TOGGLE_MULTI_SEL, MyFrame::OnToggleMultiSel)
1057     EVT_MENU(LIST_SHOW_COL_INFO, MyFrame::OnShowColInfo)
1058     EVT_MENU(LIST_SHOW_SEL_INFO, MyFrame::OnShowSelInfo)
1059     EVT_MENU(LIST_FREEZE, MyFrame::OnFreeze)
1060     EVT_MENU(LIST_THAW, MyFrame::OnThaw)
1061     EVT_MENU(LIST_TOGGLE_LINES, MyFrame::OnToggleLines)
1062     EVT_MENU(LIST_MAC_USE_GENERIC, MyFrame::OnToggleMacUseGeneric)
1063
1064     EVT_UPDATE_UI(LIST_SHOW_COL_INFO, MyFrame::OnUpdateShowColInfo)
1065     EVT_UPDATE_UI(LIST_TOGGLE_MULTI_SEL, MyFrame::OnUpdateToggleMultiSel)
1066 END_EVENT_TABLE()
1067
1068 BEGIN_EVENT_TABLE(MyListCtrl, wxListCtrl)
1069     EVT_LIST_BEGIN_DRAG(LIST_CTRL, MyListCtrl::OnBeginDrag)
1070     EVT_LIST_BEGIN_RDRAG(LIST_CTRL, MyListCtrl::OnBeginRDrag)
1071         
1072     EVT_LIST_BEGIN_LABEL_EDIT(-1, WxTreeView::OnBeginLabelEdit)
1073     EVT_LIST_END_LABEL_EDIT(-1, WxTreeView::OnEndLabelEdit)
1074         
1075     EVT_LIST_DELETE_ITEM(LIST_CTRL, MyListCtrl::OnDeleteItem)
1076     EVT_LIST_DELETE_ALL_ITEMS(LIST_CTRL, MyListCtrl::OnDeleteAllItems)
1077 #if WXWIN_COMPATIBILITY_2_4
1078     EVT_LIST_GET_INFO(LIST_CTRL, MyListCtrl::OnGetInfo)
1079     EVT_LIST_SET_INFO(LIST_CTRL, MyListCtrl::OnSetInfo)
1080 #endif
1081   */
1082     EVT_LIST_KEY_DOWN(-1, WxTreeView::OnKeyDown)
1083     EVT_LIST_ITEM_SELECTED(-1, WxTreeView::OnItemSelected)
1084   
1085     EVT_LIST_ITEM_DESELECTED(-1, WxTreeView::OnItemDeSelected)
1086         /*
1087     EVT_LIST_KEY_DOWN(LIST_CTRL, MyListCtrl::OnListKeyDown)
1088     EVT_LIST_ITEM_ACTIVATED(LIST_CTRL, MyListCtrl::OnActivated)
1089     EVT_LIST_ITEM_FOCUSED(LIST_CTRL, MyListCtrl::OnFocused)
1090 */
1091     EVT_LIST_COL_RIGHT_CLICK(-1, WxTreeView::OnColClick)
1092         
1093     EVT_LIST_COL_CLICK(-1, WxTreeView::OnColClick)
1094
1095         //EVT_LEFT_DOWN(WxTreeView::OnMouseClick)
1096         /*
1097     EVT_LIST_COL_BEGIN_DRAG(LIST_CTRL, MyListCtrl::OnColBeginDrag)
1098     EVT_LIST_COL_DRAGGING(LIST_CTRL, MyListCtrl::OnColDragging)
1099     EVT_LIST_COL_END_DRAG(LIST_CTRL, MyListCtrl::OnColEndDrag)
1100
1101     EVT_LIST_CACHE_HINT(LIST_CTRL, MyListCtrl::OnCacheHint)
1102
1103 #if USE_CONTEXT_MENU
1104     EVT_CONTEXT_MENU(MyListCtrl::OnContextMenu)
1105 #endif
1106     EVT_CHAR(MyListCtrl::OnChar)
1107
1108     EVT_RIGHT_DOWN(MyListCtrl::OnRightClick)
1109   */
1110 END_EVENT_TABLE()
1111   
1112 } // EO namespace creaImageIO
1113