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