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