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