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