]> Creatis software - creaImageIO.git/blob - src2/creaImageIOWxTreeView.cpp
1f3ccfeb1ff109fa35ba57ee90497ccb41cabd92
[creaImageIO.git] / src2 / creaImageIOWxTreeView.cpp
1 #include <creaImageIOWxTreeView.h>
2 #include <creaImageIOSystem.h>
3 #include <wx/splitter.h>
4 int wxCALLBACK CompareFunctionStrings(long item1, long item2, long sortData)
5 {       
6         std::string s1((char*)((long*)item1)[1]);
7         std::string s2((char*)((long*)item2)[1]);
8          GimmickMessage(1,
9                 " Check: STRING 1: " 
10                         <<s1
11                         <<" STRING 2: "
12                         <<s2
13                         <<std::endl);
14         if(sortData==1)
15         {
16                 // inverse the order
17                 if (s1 < s2)
18                         return 1;
19                 if (s1 > s2)
20                         return -1;
21
22                 return 0;
23         }
24         else
25         {
26                 if (s1 < s2)
27                         return -1;
28                 if (s1 > s2)
29                         return 1;
30
31                 return 0;
32
33         }
34         
35 }
36
37 int wxCALLBACK CompareFunctionInts(long item1, long item2, long sortData)
38 {       
39         int val1=atoi((char*)((long*)item1)[1]);
40         int val2=atoi((char*)((long*)item2)[1]);
41          GimmickMessage(1,
42                 " Check: STRING 1: " 
43                         <<val1
44                         <<" STRING 2: "
45                         <<val2
46                         <<std::endl);
47         if(sortData==1)
48         {
49                 // inverse the order
50                 if (val1 < val2)
51                         return 1;
52                 if (val1 > val2)
53                         return -1;
54
55                 return 0;
56         }
57         else
58         {
59                 if (val1 < val2)
60                         return -1;
61                 if (val1 > val2)
62                         return 1;
63
64                 return 0;
65
66         }
67         
68 }
69
70 namespace creaImageIO
71 {
72   //=====================================================================
73   // CTor
74   WxTreeView::WxTreeView(TreeHandler* handler,
75                          wxWindow* parent,
76                          const wxWindowID id)
77     : wxPanel(parent,id),
78       TreeView(handler)
79   {
80     GimmickDebugMessage(1,"WxTreeView::WxTreeView"
81                         <<std::endl);
82
83     
84     // Split part below toolbar into notebook for views and panel
85     // for preview, messages...
86     // TO DO : Splitter
87     //    mSplitter = new wxSplitterWindow( this , -1);
88
89     // Global sizer
90     wxBoxSizer  *sizer = new wxBoxSizer(wxHORIZONTAL);
91     
92     int ctrl_style = wxLC_REPORT | wxLC_VRULES;
93     int col_style = wxLIST_FORMAT_LEFT;
94
95     // Creating the ListCtrl for the levels > 0 (not for Root level)
96     for (int i = 1;
97          i < handler->GetTree().GetNumberOfLevels();
98          ++i)
99       {
100
101         GimmickDebugMessage(5,"Creating view for level "<<i
102                             <<std::endl);
103         LevelType level;
104
105         // If the first level : parent = this
106         wxWindow* sparent = this;
107         // else parent = last splitter
108         if (i>1) sparent = mLevelList[i-2].wxSplitter;
109
110         level.wxSplitter = new wxSplitterWindow( sparent , -1);
111         //          level.wxSplitter->SetMinimumPaneSize(100);
112         
113         wxListCtrl* ctrl = new wxListCtrl(level.wxSplitter,
114                                           i,
115                                           wxDefaultPosition, 
116                                           wxDefaultSize,
117                                           ctrl_style);
118         level.wxCtrl = ctrl;
119         level.wxSplitter->Initialize(ctrl);
120
121         // Create the columns : one for each attribute of the level
122         int col = 0;
123         
124         tree::LevelDescriptor::AttributeDescriptorListType::const_iterator a;
125         for (a  = handler->GetTree().GetAttributeDescriptorList(i).begin();
126              a != handler->GetTree().GetAttributeDescriptorList(i).end();
127              ++a)
128           {
129                   if(col==0)
130                   {
131                     wxListItem it;
132                     it.SetTextColour(*wxRED);
133                     it.SetText(_T("#C"));
134                 
135                     ctrl->InsertColumn(col,it);
136                     col++;
137                   }
138                   
139                 GimmickDebugMessage(5,"Creating column "<<col<<" : "
140                                 <<a->GetName()
141                                 <<std::endl);
142                 ctrl->InsertColumn(col, 
143                                 crea::std2wx(a->GetName()),
144                                 col_style);
145                 level.key.push_back(a->GetKey());
146                 //          ctrl->SetColumnWidth(col, wxLIST_AUTOSIZE );
147                 col++;
148                 
149                 
150           }
151           
152         mLevelList.push_back(level);
153       }
154     
155
156     /// Initialize the first level splitter
157  
158       sizer->Add( mLevelList[0].wxSplitter ,1, wxGROW  ,0);
159         mColumnSelected=1;
160         mDirection=true;
161     UpdateLevel(1);
162
163     SetSizer( sizer );     
164     SetAutoLayout(true);
165     Layout();
166
167   }
168   //=====================================================================
169
170   //=====================================================================
171   /// Destructor
172   WxTreeView::~WxTreeView()
173   {
174     GimmickDebugMessage(1,"WxTreeView::~WxTreeView"
175                         <<std::endl);
176   }
177   //=====================================================================
178   
179   
180   //=====================================================================
181   struct ItemData
182   {
183     tree::Node* node;
184         int id;
185   };
186  
187   //=====================================================================
188    std::vector<tree::Node*> WxTreeView::GetSelected(int level)
189   {
190     int l = level - 1;
191     // the selection of upper level
192     std::vector<tree::Node*> sel;
193         
194     if (level == 1) 
195       {
196         sel.push_back(GetTreeHandler()->GetTree().GetTree());
197       }
198     else 
199       {
200         int n = GetCtrl(l-1)->GetItemCount();
201         for (int i = 0; i < n; i++)
202           {
203             if ( GetCtrl(l-1)->GetItemState(i,wxLIST_STATE_SELECTED))
204               {
205                 long adr = GetCtrl(l-1)->GetItemData(i);
206                 tree::Node* n = ((ItemData*)adr)->node;
207                 sel.push_back(n);
208               }
209           }     
210       }
211         
212           return sel;
213   }
214
215   //=====================================================================
216   
217   ///Removes selected nodes on given level
218   void WxTreeView::RemoveSelected( int level )
219   {
220           std::vector<tree::Node*> sel=GetSelected(level+1);
221           bool erase=false;
222           if (wxMessageBox(_T("Delete file(s) ?"),
223                          _T("Remove Files"),
224                          wxYES_NO,this ) == wxYES)
225           {
226             erase = true;
227           }
228           if(erase)
229           {
230                 std::vector<tree::Node*>::iterator i;
231                 for (i=sel.begin(); i!=sel.end(); ++i)
232                 {
233                         GimmickDebugMessage(2,
234                                         "deleting '"
235                                         <<(*i)->GetLabel()
236                                         <<"'"<<level
237                                         <<std::endl);
238                                 GetTreeHandler()->Remove(*i);
239                 }
240
241                 UpdateLevel(level);
242           }
243           
244   }
245     
246
247   //=====================================================================
248
249  
250   //=====================================================================
251   /// 
252   void WxTreeView::UpdateLevel( int level )
253   {
254     GimmickDebugMessage(1,
255                         GetTreeHandler()->GetTree().GetLabel()
256                         <<" view : updating level "<<level
257                         <<std::endl);
258     
259     wxBusyCursor busy;
260     RecursiveUpdateLevel(level);
261     int i;
262     for (i=0; i<level-1; i++)
263       {
264         if (!GetSplitter(i)->IsSplit()) 
265           GetSplitter(i)->SplitVertically(  GetCtrl(i), GetSplitter(i+1),
266                                             100 );
267       }
268     if (GetSplitter(i)->IsSplit()) GetSplitter(i)->Unsplit();    
269     
270   }
271   //=====================================================================
272   
273   /// 
274   void WxTreeView::RecursiveUpdateLevel( int level )
275   {
276           GimmickDebugMessage(2,
277                         GetTreeHandler()->GetTree().GetLabel()
278                         <<" view : updating level (recursive)"<<level
279                         <<std::endl);
280
281
282     std::vector<tree::Node*> sel=GetSelected(level);
283
284           int l = level - 1;
285  
286     // to speed up inserting we hide the control temporarily
287     GetCtrl(l)->Hide();
288     GetCtrl(l)->DeleteAllItems();
289     
290     std::vector<tree::Node*>::iterator i;
291     for (i=sel.begin(); i!=sel.end(); ++i)
292       {
293         GimmickDebugMessage(2,
294                             "adding children of '"
295                             <<(*i)->GetLabel()
296                             <<"'"<<level
297                             <<std::endl);
298         int _id=0;
299         //Adds columns
300         GetTreeHandler()->LoadChildren(*i,1);
301         tree::Node::ChildrenListType::reverse_iterator j;
302         for (j = (*i)->GetChildrenList().rbegin(); 
303              j!= (*i)->GetChildrenList().rend(); 
304              ++j)
305           {
306             wxListItem item;
307             item.SetMask(wxLIST_MASK_STATE | 
308                          wxLIST_MASK_TEXT |
309                          //                      wxLIST_MASK_IMAGE |
310                          wxLIST_MASK_DATA |
311                          //                      wxLIST_MASK_WIDTH |
312                          wxLIST_MASK_FORMAT
313                          );
314
315             ItemData* data = new ItemData;
316             
317                 data->node = *j;
318                 item.SetId(_id);
319                 /*
320                 std::string a=(*j)->GetAttribute(mLevelList[l].key[mColumnSelected-1]);
321                 GimmickMessage(1,
322                         "State Check: Att VAL"
323                             <<a
324                             <<std::endl);
325         */
326                 data->id = _id;
327             item.SetData(data);
328             
329                 _id++;
330           
331             long id = GetCtrl(l)->InsertItem(item);
332
333             std::ostringstream oss;
334             int n= GetTreeHandler()->GetNumberOfChildren(*j);
335             
336             oss << n;
337             std::string s(oss.str());
338             
339                 
340             item.SetText( crea::std2wx(s));
341             //      item.SetTextColour(*wxRED);
342             //      item.SetBackgroundColour(*wxBLACK); 
343             item.SetColumn(0);
344
345                 //Sets the last level as selecte....How to make it select only the first time?
346                 //if (level==mLevelList.size()) item.SetState(wxLIST_STATE_SELECTED);
347
348             GetCtrl(l)->SetItem(item);
349                 
350             //      GetCtrl(l)->SetItem(id,0, crea::std2wx(s));
351             //      GetCtrl(l)->SetColumnWidth(0, wxLIST_AUTOSIZE );
352
353           for (int k=1; k<GetCtrl(l)->GetColumnCount(); k++)
354               {
355   
356                 std::string val = (*j)->GetAttribute(mLevelList[l].key[k-1]);
357                 if (val.size()==0) val = "?";
358                 item.SetText( crea::std2wx(val));
359                 //              item.SetTextColour(*wxBLACK);
360                 //              item.SetBackgroundColour(*wxWHITE); 
361                 item.SetColumn(k);
362                 GetCtrl(l)->SetItem(item);
363
364                 //              GetCtrl(l)->SetItem(id,k, crea::std2wx(val));
365                 // GetCtrl(l)->SetColumnWidth(k, wxLIST_AUTOSIZE );
366                 
367               }
368             
369           }
370       }
371     
372     GetCtrl(l)->Show();
373
374     
375     if (level<mLevelList.size()) UpdateLevel(level+1);
376  }
377   //=====================================================================
378
379
380   //================================================================
381   void WxTreeView::OnSelectedChanged(wxListEvent& event)
382   { 
383     GimmickDebugMessage(1,
384                         GetTreeHandler()->GetTree().GetLabel()
385                         <<" view : item selected "
386                         <<std::endl);
387
388     wxListItem info;
389     info.m_itemId = event.m_itemIndex;
390     
391
392     // retrieve the level
393     wxObject* obj = event.GetEventObject();   
394     unsigned int level = 0;
395     for (level = 0; level<mLevelList.size(); ++level)
396       {
397         if ( GetCtrl(level) == obj ) break;
398       }
399     GimmickDebugMessage(1,
400                         " Level "<<level+1
401                         <<std::endl);
402     if (level<mLevelList.size()-1) UpdateLevel( level + 2 ); 
403         if (level==mLevelList.size()-1) ValidateSelectedImages ();
404
405   }
406   //================================================================
407
408 //================================================================
409   void WxTreeView::OnColClick(wxListEvent& event)
410   {       
411         //Obtain the column name and the level that needs to be organized
412         mColumnSelected=event.m_col;
413     GimmickMessage(1,
414                         " Column " <<event.m_col
415                         <<std::endl);
416
417         
418     wxObject* ctrl = event.GetEventObject(); 
419         unsigned int level = 0;
420     for (level = 0; level<mLevelList.size(); ++level)
421       {
422         if ( GetCtrl(level) == ctrl ) break;
423       }
424           UpdateLevel(level+1);
425           wxBusyCursor busy;
426  
427           int l = level - 1;
428
429           //Sets the data for the items to be sorted
430         std::string att;
431         unsigned int ty=0;
432         int n = GetCtrl(level)->GetItemCount();
433         for (int i = 0; i < n; i++)
434           {
435                   
436             //Gets current item data
437                 long adr = GetCtrl(level)->GetItemData(i);
438                 //Extracts the node and the type of attribute
439                 tree::Node* nod = ((ItemData*)adr)->node;
440                 if(i==0)
441                   {
442                         (*nod).GetAttributeDescriptor(mLevelList[level].key[mColumnSelected-1]).DecodeType(ty);
443                   }
444                 //Obtains the organizing attribute
445                 att=(*nod).GetAttribute(mLevelList[level].key[mColumnSelected-1]);
446                 
447                 char* d= new char [att.size()+1];
448                 strcpy (d, att.c_str());
449
450                 //Creates array
451                 long* lp= new long[2];
452                 lp[0]=adr;
453                 lp[1]=(long)d;
454                  
455                 //Sets it as the data
456                 GetCtrl(level)->SetItemData(i,(long)lp);
457           }     
458           
459           //int ty=GetAttributeDescriptor(mLevelList[level].key[mColumnSelected-1]).GetType();
460           if(mDirection)
461           {
462                   if(ty==1)
463                   {
464                           GetCtrl(level)->SortItems(CompareFunctionInts, 0);
465                   }
466                   else
467                   {
468                           GetCtrl(level)->SortItems(CompareFunctionStrings, 0);
469                   }
470                 
471                 mDirection=false;
472           }
473           else
474           {
475                  if(ty==1)
476                   {
477                           GetCtrl(level)->SortItems(CompareFunctionInts, 1);
478                   }
479                   else
480                   {
481                           GetCtrl(level)->SortItems(CompareFunctionStrings, 1);
482                   }
483                   mDirection=true;
484           }
485
486         //Resets original data
487                 
488         long it = -1;
489         for ( ;; )
490     {
491         it = GetCtrl(level)->GetNextItem(it,
492                                      wxLIST_NEXT_ALL);
493         if ( it == -1 )
494             break;
495                   //Gets current item data, extracts the node and resets it
496                 long item = GetCtrl(level)->GetItemData(it);
497                 GetCtrl(level)->SetItemData(it,((long*)item)[0]);
498                 
499           }
500         
501    }
502   //================================================================
503
504   void WxTreeView::ValidateSelectedImages()
505   {
506                 //Send an event telling wether the selection is valid or not
507                 wxCommandEvent event( 0, GetId() );
508                 event.SetEventObject( this );
509                 std::vector<tree::Node*> sel=GetSelected((mLevelList.size()+1));
510                 event.SetClientData(&sel);
511                 GetEventHandler()->ProcessEvent( event );
512   }
513   //================================================================
514   void WxTreeView::GetSelectedAsString(std::vector<std::string>&s)
515   {
516           int level=mLevelList.size();
517         std::vector<tree::Node*> sel=GetSelected(level+1);
518         std::vector<tree::Node*>::iterator i;
519         
520     for (i=sel.begin(); i!=sel.end(); ++i)
521       {
522                   std::string filename=(*i)->GetAttribute("FullFileName");
523                   s.push_back(filename);
524           }
525   }
526   //================================================================
527   BEGIN_EVENT_TABLE(WxTreeView, wxPanel)
528   /*
529     EVT_SIZE(MyFrame::OnSize)
530
531     EVT_MENU(LIST_QUIT, MyFrame::OnQuit)
532     EVT_MENU(LIST_ABOUT, MyFrame::OnAbout)
533     EVT_MENU(LIST_LIST_VIEW, MyFrame::OnListView)
534     EVT_MENU(LIST_REPORT_VIEW, MyFrame::OnReportView)
535     EVT_MENU(LIST_ICON_VIEW, MyFrame::OnIconView)
536     EVT_MENU(LIST_ICON_TEXT_VIEW, MyFrame::OnIconTextView)
537     EVT_MENU(LIST_SMALL_ICON_VIEW, MyFrame::OnSmallIconView)
538     EVT_MENU(LIST_SMALL_ICON_TEXT_VIEW, MyFrame::OnSmallIconTextView)
539     EVT_MENU(LIST_VIRTUAL_VIEW, MyFrame::OnVirtualView)
540     EVT_MENU(LIST_SMALL_VIRTUAL_VIEW, MyFrame::OnSmallVirtualView)
541
542     EVT_MENU(LIST_FOCUS_LAST, MyFrame::OnFocusLast)
543     EVT_MENU(LIST_TOGGLE_FIRST, MyFrame::OnToggleFirstSel)
544     EVT_MENU(LIST_DESELECT_ALL, MyFrame::OnDeselectAll)
545     EVT_MENU(LIST_SELECT_ALL, MyFrame::OnSelectAll)
546     EVT_MENU(LIST_DELETE, MyFrame::OnDelete)
547     EVT_MENU(LIST_ADD, MyFrame::OnAdd)
548     EVT_MENU(LIST_EDIT, MyFrame::OnEdit)
549     EVT_MENU(LIST_DELETE_ALL, MyFrame::OnDeleteAll)
550     EVT_MENU(LIST_SORT, MyFrame::OnSort)
551     EVT_MENU(LIST_SET_FG_COL, MyFrame::OnSetFgColour)
552     EVT_MENU(LIST_SET_BG_COL, MyFrame::OnSetBgColour)
553     EVT_MENU(LIST_TOGGLE_MULTI_SEL, MyFrame::OnToggleMultiSel)
554     EVT_MENU(LIST_SHOW_COL_INFO, MyFrame::OnShowColInfo)
555     EVT_MENU(LIST_SHOW_SEL_INFO, MyFrame::OnShowSelInfo)
556     EVT_MENU(LIST_FREEZE, MyFrame::OnFreeze)
557     EVT_MENU(LIST_THAW, MyFrame::OnThaw)
558     EVT_MENU(LIST_TOGGLE_LINES, MyFrame::OnToggleLines)
559     EVT_MENU(LIST_MAC_USE_GENERIC, MyFrame::OnToggleMacUseGeneric)
560
561     EVT_UPDATE_UI(LIST_SHOW_COL_INFO, MyFrame::OnUpdateShowColInfo)
562     EVT_UPDATE_UI(LIST_TOGGLE_MULTI_SEL, MyFrame::OnUpdateToggleMultiSel)
563 END_EVENT_TABLE()
564
565 BEGIN_EVENT_TABLE(MyListCtrl, wxListCtrl)
566     EVT_LIST_BEGIN_DRAG(LIST_CTRL, MyListCtrl::OnBeginDrag)
567     EVT_LIST_BEGIN_RDRAG(LIST_CTRL, MyListCtrl::OnBeginRDrag)
568     EVT_LIST_BEGIN_LABEL_EDIT(LIST_CTRL, MyListCtrl::OnBeginLabelEdit)
569     EVT_LIST_END_LABEL_EDIT(LIST_CTRL, MyListCtrl::OnEndLabelEdit)
570     EVT_LIST_DELETE_ITEM(LIST_CTRL, MyListCtrl::OnDeleteItem)
571     EVT_LIST_DELETE_ALL_ITEMS(LIST_CTRL, MyListCtrl::OnDeleteAllItems)
572 #if WXWIN_COMPATIBILITY_2_4
573     EVT_LIST_GET_INFO(LIST_CTRL, MyListCtrl::OnGetInfo)
574     EVT_LIST_SET_INFO(LIST_CTRL, MyListCtrl::OnSetInfo)
575 #endif
576   */
577     EVT_LIST_ITEM_SELECTED(-1, WxTreeView::OnSelectedChanged)
578   
579     EVT_LIST_ITEM_DESELECTED(-1, WxTreeView::OnSelectedChanged)
580         /*
581     EVT_LIST_KEY_DOWN(LIST_CTRL, MyListCtrl::OnListKeyDown)
582     EVT_LIST_ITEM_ACTIVATED(LIST_CTRL, MyListCtrl::OnActivated)
583     EVT_LIST_ITEM_FOCUSED(LIST_CTRL, MyListCtrl::OnFocused)
584
585     EVT_LIST_COL_RIGHT_CLICK(LIST_CTRL, MyListCtrl::OnColRightClick)
586         */
587     EVT_LIST_COL_CLICK(-1, WxTreeView::OnColClick)
588         /*
589     EVT_LIST_COL_BEGIN_DRAG(LIST_CTRL, MyListCtrl::OnColBeginDrag)
590     EVT_LIST_COL_DRAGGING(LIST_CTRL, MyListCtrl::OnColDragging)
591     EVT_LIST_COL_END_DRAG(LIST_CTRL, MyListCtrl::OnColEndDrag)
592
593     EVT_LIST_CACHE_HINT(LIST_CTRL, MyListCtrl::OnCacheHint)
594
595 #if USE_CONTEXT_MENU
596     EVT_CONTEXT_MENU(MyListCtrl::OnContextMenu)
597 #endif
598     EVT_CHAR(MyListCtrl::OnChar)
599
600     EVT_RIGHT_DOWN(MyListCtrl::OnRightClick)
601   */
602 END_EVENT_TABLE()
603   
604 } // EO namespace creaImageIO
605