creaImageIO_lib
creaImageIOWxTreeView.cpp
Go to the documentation of this file.
1 /*
2 # ---------------------------------------------------------------------
3 #
4 # Copyright (c) CREATIS (Centre de Recherche en Acquisition et Traitement de l'Image
5 # pour la Santé)
6 # Authors : Eduardo Davila, Frederic Cervenansky, Claire Mouton
7 # Previous Authors : Laurent Guigues, Jean-Pierre Roux
8 # CreaTools website : www.creatis.insa-lyon.fr/site/fr/creatools_accueil
9 #
10 # This software is governed by the CeCILL-B license under French law and
11 # abiding by the rules of distribution of free software. You can use,
12 # modify and/ or redistribute the software under the terms of the CeCILL-B
13 # license as circulated by CEA, CNRS and INRIA at the following URL
14 # http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
15 # or in the file LICENSE.txt.
16 #
17 # As a counterpart to the access to the source code and rights to copy,
18 # modify and redistribute granted by the license, users are provided only
19 # with a limited warranty and the software's author, the holder of the
20 # economic rights, and the successive licensors have only limited
21 # liability.
22 #
23 # The fact that you are presently reading this means that you have had
24 # knowledge of the CeCILL-B license and that you accept its terms.
25 # ------------------------------------------------------------------------
26 */
27 
28 #include <creaImageIOWxTreeView.h>
29 #include <creaImageIOGimmickView.h>
30 
31 #include <wx/splitter.h>
32 #include <wx/gdicmn.h>
33 #include <boost/date_time/gregorian/gregorian.hpp>
34 #include <creaImageIOGimmick.h>
35 #ifdef _DEBUG
36 #define new DEBUG_NEW
37 #endif
38 //=====================================================================
39 namespace creaImageIO
40 {
41 
42  //=====================================================================
43 }
44 //=====================================================================
45 
46 //=====================================================================
48 int wxCALLBACK CompareFunctionStrings(long item1, long item2, long sortData)
49 {
52 
53  const std::string& s1(*(data1->attr));
54  const std::string& s2(*(data2->attr));
55  if(sortData==1)
56  {
57  // inverse the order
58  if (s1 < s2)
59  return 1;
60  if (s1 > s2)
61  return -1;
62 
63  return 0;
64  }
65  else
66  {
67  if (s1 < s2)
68  return -1;
69  if (s1 > s2)
70  return 1;
71 
72  return 0;
73 
74  }
75 }
76 //=====================================================================
77 
78 //=====================================================================
80 int wxCALLBACK CompareFunctionInts(long item1, long item2, long sortData)
81 {
84 
85  const std::string& s1(*(data1->attr));
86  const std::string& s2(*(data2->attr));
87 
88  int val1=atoi(s1.c_str());
89  int val2=atoi(s2.c_str());
90 
91  if(sortData==1)
92  {
93  // inverse the order
94  if (val1 < val2)
95  return 1;
96  if (val1 > val2)
97  return -1;
98 
99  return 0;
100  }
101  else
102  {
103  if (val1 < val2)
104  return -1;
105  if (val1 > val2)
106  return 1;
107 
108  return 0;
109 
110  }
111 
112 }
113 
114 //=====================================================================
115 
116 
117 //=====================================================================
118 namespace creaImageIO
119 {
120  //=====================================================================
121  // CTor
123  GimmickView* gimmick,
124  wxWindow* parent,
125  const wxWindowID id)
126  : wxPanel(parent,id),
127  TreeView(handler, gimmick)
128  {
129  GimmickDebugMessage(1,"WxTreeView::WxTreeView"
130  <<std::endl);
131 
132 
133  // Split part below toolbar into notebook for views and panel
134  // for preview, messages...
135  // TO DO : Splitter
136  // mSplitter = new wxSplitterWindow( this , -1);
137 
138  // Global sizer
139  msizer = new wxBoxSizer(wxHORIZONTAL);
140 
141  int ctrl_style = wxLC_REPORT | wxLC_VRULES;
142  int col_style = wxLIST_FORMAT_LEFT;
143 
144  // Creating the ListCtrl for the levels > 0 (not for Root level)
145  for (int i = 0;
146  i < handler->GetTree().GetNumberOfLevels() -1;
147  ++i)
148  {
149  GimmickDebugMessage(5,"Creating view for level "<<i
150  <<std::endl);
151  LevelType level;
152  level.SelectedUpToDate = true;
153  level.SortColumn = 0;
154 
155  // If the first level : parent = this
156  wxWindow* sparent = this;
157  // else parent = last splitter
158  if (i>0)
159  sparent = mLevelList[i-1].wxSplitter;
160 
161  level.wxSplitter = new wxSplitterWindow( sparent , -1);
162  if(i!=0)
163  {
164  level.wxSplitter->Show(false);
165  }
166  // level.wxSplitter->SetMinimumPaneSize(100);
167 
168  wxListCtrl* ctrl = new wxListCtrl(level.wxSplitter,
169  i,
170  wxDefaultPosition,
171  wxDefaultSize,
172  ctrl_style);
173  level.wxCtrl = ctrl;
174  level.wxSplitter->Initialize(ctrl);
175 
176  // Create the columns : one for each attribute of the level
177  int col = 0;
178  std::string title;
179 
180  tree::LevelDescriptor::AttributeDescriptorListType::const_iterator a;
181  for (a = handler->GetTree().GetAttributeDescriptorList(i+1).begin();
182  a != handler->GetTree().GetAttributeDescriptorList(i+1).end();
183  ++a)
184 
185 {
186 
187  GimmickDebugMessage(5,"Creating column "<<col<<" : "
188  <<a->GetName()
189  <<std::endl);
190 
192  {
193 
194  if(a->GetName()=="UNKNOWN")
195  {
196  title = "#";
197  title += handler->GetTree().GetLevelDescriptor(i+1).GetName();
198  if (title[title.size()-1]!='s')
199  title += "s";
200 
201  }
202  else
203  {
204  title=a->GetName();
205  }
206  std::string temp = a->GetKey();
207  if (temp.compare("ID") != 0)
208  {
209 
210  ctrl->InsertColumn(col,
211  crea::std2wx(title),
212  col_style);
213  col++;
214  }
215  level.key.push_back(a->GetKey());
216  }
217 
218  }
219 
220  mLevelList.push_back(level);
221  }
222 
223 #if wxUSE_MENUS
224 
225  // Column Menu
226  menu =new wxMenu;
227  wxMenuItem* m1=menu->Append(wxID_ANY, _T("&Sort ascending"));
228  wxMenuItem* m2=menu->Append(wxID_ANY, _T("&Sort descending"));
229  wxMenuItem* m3=menu->Append(wxID_ANY, _T("&Filter"));
230  mAscendingID=m1->GetId();
231  mDescendingID=m2->GetId();
232  mFilterID=m3->GetId();
233  Connect( mAscendingID, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(WxTreeView::OnPopupSort) );
234  Connect( mDescendingID, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(WxTreeView::OnPopupSort) );
235  Connect( mFilterID, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(WxTreeView::OnPopupFilter) );
236 
237 
239  subExportMenu = new wxMenu;
240  wxMenuItem *subExp1 = subExportMenu->Append(wxID_ANY, _T("&Export to Storage"));
241  Connect( subExp1->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(WxTreeView::OnExportToStorage) );
242 
243  //ItemMenu
244  menuItem =new wxMenu;
245 
246 
247  wxMenuItem* m2Item=menuItem->Append(wxID_ANY, _T("&Local Copy"));
248  wxMenuItem* m3Item=menuItem->Append(wxID_ANY, _T("&Edit Fields"));
249  wxMenuItem* m4Item=menuItem->Append(wxID_ANY, _T("&Display Dicom Tags"));
250  menuItem->AppendSubMenu(subExportMenu, wxT("&Export"));
251 
252 
253  wxMenuItem* m1Item=menuItem->Append(wxID_ANY, _T("&Anonymize"));
254  mAnonymizingID=m1Item->GetId();
255  Connect( mAnonymizingID, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(WxTreeView::OnAnonymizer) );
256 
257  mLocalCopyID=m2Item->GetId();
258  mEditFieldID=m3Item->GetId();
259  mDumpID=m4Item->GetId();
260 
261 
262  Connect( mLocalCopyID, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(WxTreeView::OnLocalCopy) );
263  Connect( mEditFieldID, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(WxTreeView::OnEditField) );
264  Connect( mDumpID, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(WxTreeView::OnDumpTags) );
265 
266 
267 
268 #endif // wxUSE_MENUS
269 
270 
271  msizer->Add( mLevelList[0].wxSplitter ,1, wxGROW ,0);
272  // mColumnSelected=1;
273  mLastSelected=0;
274  mLastLevel=0;
275  // mDirection=true;
276 
277  mIgnoreSelectedChanged = false;
278 
279  //CreateColorPalette();
280  UpdateLevel(1);
281 
282  SetSizer( msizer );
283  SetAutoLayout(true);
284  Layout();
285 
286  }
287  //=====================================================================
288 
289  //=====================================================================
292  {
293  GimmickDebugMessage(1,"WxTreeView::~WxTreeView"
294  <<std::endl);
295  delete menu;
296  delete menuItem;
297 
298  }
299  //=====================================================================
300 
301 
302 
303  //=====================================================================
304  const std::vector<tree::Node*>& WxTreeView::GetSelected(int level)
305  {
306  std::vector<tree::Node*>& sel = mLevelList[0].Selected;
307  // if (GetSelectedUpToDate(level))
308  int l = level - 1;
309  // the selection of upper level
310  if(mLevelList.size() == level -1)
311  sel = mLevelList.back().Selected;
312  else
313  sel= mLevelList[l].Selected;
314  if (sel.size() > 0)
315  {
316  sel.clear();
317  }
318  if (level == 1)
319  {
320  sel.push_back(GetTreeHandler()->GetTree().GetTree());
321  }
322  else if (level < mLevelList.size()+2 )
323  {
324  long item = -1;
325  for ( ;; )
326  {
327  item = GetCtrl(l-1)->GetNextItem(item,
328  wxLIST_NEXT_ALL,
329  wxLIST_STATE_SELECTED);
330  if ( item == -1 )
331  break;
332  long adr = (long)GetCtrl(l-1)->GetItemData(item);
333  tree::Node* n = ((ItemData*)adr)->node;
334  /* FCY 18-04-2011: don't understand the real purpose of these lines,
335  if uncomment add last frame in first place
336  if(mLastSelected==item)
337  {
338  std::vector<tree::Node*>::iterator it;
339  it = sel.begin();
340  it = sel.insert ( it , n );
341  }
342  else
343  {*/
344 
345  sel.push_back(n);
346  //}
347 
348  }
349  /*int n = GetCtrl(l-1)->GetItemCount();
350  for (int i = 0; i<n; i++)
351  {
352  std::cout<<GetCtrl(l-1)->GetItemState(i,wxLIST_STATE_SELECTED)<<std::endl;
353  if ( GetCtrl(l-1)->GetItemState(i,wxLIST_STATE_SELECTED))
354  {
355  long adr = GetCtrl(l-1)->GetItemData(i);
356  tree::Node* n = ((ItemData*)adr)->node;
357  if(mLastSelected==i)
358  {
359  std::vector<tree::Node*>::iterator it;
360  it = sel.begin();
361  it = sel.insert ( it , n );
362  }
363  else
364  {
365 
366  sel.push_back(n);
367  }
368  }
369  }*/
370  }
371  else
372  {
373  // NOTHING
374  }
375 
376  // return mLevelList[level-1].Selected;
377  return sel;
378  }
379 
380  //=====================================================================
381 
382  //=====================================================================
384  // NOT SPECIFIC
385  void WxTreeView::RemoveSelected(std::string &i_save)
386  {
387  bool erase=false;
388 
389  unsigned int tempLevel = mLastLevel;
390  mLastLevel+=1;
391  const std::vector<tree::Node*>& sel=GetSelected(mLastLevel+1);
392  // if no selection, no remove action.
393  if(sel.size() != 0)
394  {
395 
396  std::stringstream out;
397  std::string levelName=GetTreeHandler()->GetTree().GetLevelDescriptor(mLastLevel).GetName();
398  out<<"Delete ";
399  out<<sel.size();
400  if(sel.size()>1&&levelName.at(levelName.size()-1)!='s')
401  {
402  out<<" "<<levelName;
403  out<<"s?";
404  }
405  else
406  {
408  }
409  if (wxMessageBox(crea::std2wx(out.str()),
410  _T("Remove Files"),
411  wxYES_NO,this ) == wxYES)
412  {
413  erase = true;
414  }
415  if(erase)
416  {
418  bool needRefresh=false;
419  std::vector<tree::Node*>::const_iterator i;
420  for (i=sel.begin(); i!=sel.end(); ++i)
421  {
422  GimmickMessage(1,
423  "deleting '"
424  <<(*i)->GetLabel()
425  <<"'"<<mLastLevel
426  <<std::endl);
427  if((*i)->GetParent()->GetNumberOfChildren()<2)
428  {
429  needRefresh=true;
430  }
431  //tree::Node* n = new (tree::Node*)(*i);
432  GetTreeHandler()->LoadChildren((*i),4);
434  GetTreeHandler()->Remove(*i);
435  }
436 
437  if(needRefresh && mLastLevel>1)
438  {
440  }
441  else if(mLastLevel>1)
442  {
444  }
445  else
446  {
448  }
449  }
450  }
451  else
452  {
453  // no need to incremente level
454  mLastLevel = tempLevel;
455  }
456 
457  if (erase && mLastLevel == 1 && i_save == "0")
458  {
459 
460  RemoveAlertDlg *dial = new RemoveAlertDlg(this, crea::std2wx("Remove files"), wxSize(370,100));
461  //dial->ShowModal();
462  if (dial->ShowModal() == wxID_OK)
463  {
464  i_save = dial->isChecked() == false? "0" : "1";
465  }
466 
467  }
468  }
469 
470 
471  //=====================================================================
473  void WxTreeView::UpdateLevel( int level )
474  {
476  GetTreeHandler()->GetTree().GetLabel()
477  <<"WxTreeView::UpdateLevel(level "
478  <<level
479  <<")"
480  <<std::endl);
481 
482  wxBusyCursor busy;
483  RecursiveUpdateLevel(level);
484  int i;
485  for (i=0; i<level-1; i++)
486  {
487  if (!GetSplitter(i)->IsSplit())
488  GetSplitter(i)->SplitVertically( GetCtrl(i), GetSplitter(i+1),
489  100 );
490  }
491  if (GetSplitter(i)->IsSplit()) GetSplitter(i)->Unsplit();
492 
493  }
494  //=====================================================================
495 
496  //=====================================================================
499  {
501  GetTreeHandler()->GetTree().GetLabel()
502  <<"WxTreeView::RecursiveUpdateLevel(level "
503  <<level
504  <<")"<<std::endl);
505 
506 
507  const std::vector<tree::Node*>& sel(GetSelected(level));
508 
509  int l = level - 1;
510 
511  // to speed up inserting we hide the control temporarily
512  GetCtrl(l)->Hide();
513  GetCtrl(l)->DeleteAllItems();
514 
515  std::vector<tree::Node*>::const_iterator i;
516 
517  for (i=sel.begin(); i!=sel.end(); ++i)
518  {
520  "adding children of '"
521  <<(*i)->GetLabel()
522  <<"'"
523  <<std::endl);
524  int _id=0;
525 
526  //Adds items and sets their attributes
527 
528  GetTreeHandler()->LoadChildren(*i,1);
529  tree::Node::ChildrenListType::reverse_iterator j;
530  for (j = (*i)->GetChildrenList().rbegin();
531  j!= (*i)->GetChildrenList().rend();
532  ++j)
533  {
535  "adding children "
536  <<(*j)->GetLabel()
537  <<"'"
538  <<std::endl);
539 
540  wxListItem item;
541  item.SetMask(wxLIST_MASK_STATE |
542  wxLIST_MASK_TEXT |
543  // wxLIST_MASK_IMAGE |
544  wxLIST_MASK_DATA |
545  // wxLIST_MASK_WIDTH |
546  wxLIST_MASK_FORMAT
547  );
548 
549  ItemData* data = new ItemData();
550  data->node = *j;
551  data->id = _id;
552 
553  item.SetId(_id);
554  item.SetData(data);
555 
556  _id++;
557  GetCtrl(l)->InsertItem(item);
558 
559  //Setting attributes
560  for (int k=0; k<GetCtrl(l)->GetColumnCount(); ++k)
561  {
562  std::string val;
563  // Temporary correction : it works but no explanation about the problem FCY
564 
565  if(k==0 && level <3)
566  {
567  val = (*j)->GetAttribute("NumberOfChildren");
568  }
569  else
570  val = (*j)->GetAttribute(mLevelList[l].key[k]);
571  if(((*j)->GetAttributeDescriptor(mLevelList[l].key[k])).isDateEntry()) // Date
572  {
573  // std::cout << "["<<val<< "]" << std::endl;
574  std::string valtmp(val);
575  try
576  {
577  boost::gregorian::date d1(boost::gregorian::from_undelimited_string(val));
578  val = to_iso_extended_string(d1);
579  }
580  catch (...)
581  {
582  val = valtmp;
583  }
584  // std::cout << "["<<val<< "]" << std::endl;
585  }
586  else if(((*j)->GetAttributeDescriptor(mLevelList[l].key[k])).isTimeEntry()) // Time
587  {
588  if ((val.size()>6) &&
589  (val != "" || val != " "))
590  val = val.substr(0,2) + " : "
591  + val.substr(2,2) + " : "
592  + val.substr(4,2);
593  }
594  else
595  {
596  if (val.size()==0) val = "?";
597  }
598  if (val.size()==0) val = "X";
599  item.SetText( crea::std2wx(val));
600  item.SetColumn(k);
601 
602  GetCtrl(l)->SetItem(item);
603  }
604  item.Clear();
605 
606  }
607  }
608 
609  SortLevel(l);
610  GetCtrl(l)->Show();
611  }
612  //=====================================================================
613 
614 
615  //================================================================
616  void WxTreeView::OnItemDeSelected(wxListEvent& event)
617  {
619  GetTreeHandler()->GetTree().GetLabel()
620  <<" WxTreeView::OnItemDeselected"<<std::endl);
621  // retrieve the level
622  wxObject* obj = event.GetEventObject();
623  unsigned int level = 0;
624  for (level = 0; level<mLevelList.size(); ++level)
625  {
626  if ( GetCtrl(level) == obj ) break;
627  }
628  SetSelectedUpToDate(level,false);
629  // to allow a first selection in images TreeView
630  if (level==mLevelList.size()-1)
631  OnItemSelected(event);
632  }
633  //================================================================
634 
635  //================================================================
636  void WxTreeView::OnItemSelected(wxListEvent& event)
637  {
638 
640  GetTreeHandler()->GetTree().GetLabel()
641  <<" WxTreeView::OnItemSelected"<<std::endl);
642 
644  {
646  " mIgnoreSelectedChanged true: returning"
647  <<std::endl);
648  return;
649  }
650 
651 
652 
653  wxListItem info;
654  info.m_itemId = event.m_itemIndex;
655  mLastSelected = event.m_itemIndex;
656  // retrieve the level
657  wxObject* obj = event.GetEventObject();
658  unsigned int level = 0;
659  for (level = 0; level<mLevelList.size(); ++level)
660  {
661  if ( GetCtrl(level) == obj ) break;
662  }
663  mLastLevel=level;
665  " Level "<<level+1
666  <<std::endl);
667 
668  // Update the children level (if selection not at last level)
669  if (level<mLevelList.size()-1)
670  {
671 
672  UpdateLevel( level + 2 );
673  // Reset the viewer setting the default image
675  }
676  // Select all images if the selection is at series level
677  if (level==mLevelList.size()-2)
678  SelectAll(level+1);
679  // Validate selected images if the selection is at image level
680  if (level==(mLevelList.size()-1)) //&&mProcess)
681  {
682  if(event.GetEventType()==wxEVT_COMMAND_LIST_ITEM_SELECTED)
683  {
684  ValidateSelectedImages (true);
685  }
686  else
687  {
688  ValidateSelectedImages (false);
689  }
690  }
691 
692  }
693  //================================================================
694 
695  //================================================================
696  void WxTreeView::SelectAll(int level)
697  {
698  long item = -1;
699  // int level=mLevelList.size()-1;
700  for ( ;; )
701  {
702  item = GetCtrl(level)->GetNextItem(item,
703  wxLIST_NEXT_ALL);
704  if ( item == -1 )
705  break;
706 
707  if(item==(GetCtrl(level)->GetItemCount()-1))
708  {
709  mIgnoreSelectedChanged = false;//mProcess=true;
710  }
711  else
712  {
713  mIgnoreSelectedChanged = true;// mProcess=false;
714  }
715  GetCtrl(level)->SetItemState(item,wxLIST_STATE_SELECTED, wxLIST_MASK_STATE
716  | wxLIST_MASK_TEXT |wxLIST_MASK_IMAGE | wxLIST_MASK_DATA | wxLIST_MASK_WIDTH | wxLIST_MASK_FORMAT);
717  }
718  }
719 
720  //================================================================
721  //================================================================
722 
723  void WxTreeView::OnColClick(wxListEvent& event)
724  {
725  mColumnSelected = event.m_col;
726  wxPoint clientpt;
727  clientpt.x = wxGetMousePosition().x - this->GetScreenPosition().x;
728  clientpt.y = wxGetMousePosition().y - this->GetScreenPosition().y;
729  senderCtrl = event.GetEventObject();
730  unsigned int level = 0;
731  for (level = 0; level<mLevelList.size(); ++level)
732  {
733  if ( GetCtrl(level) == senderCtrl ) break;
734  }
735  PopupMenu(menu, clientpt);
736 
737  }
738 
739  //================================================================
740  //================================================================
741 
742  void WxTreeView::OnItemMenu(wxListEvent &event)
743  {
744  wxPoint clientpt;
745  clientpt.x = wxGetMousePosition().x - this->GetScreenPosition().x;
746  clientpt.y = wxGetMousePosition().y - this->GetScreenPosition().y;
747  senderCtrl = event.GetEventObject();
748  unsigned int level = 0;
749  for (level = 0; level<mLevelList.size(); ++level)
750  {
751  if ( GetCtrl(level) == senderCtrl ) break;
752  }
753  long* ptr=0;
754  int flag;
755  mLastRightLevel=level;
756  mLastRightSelected=GetCtrl(level)->HitTest(wxPoint(0,clientpt.y-8),flag,ptr);
757  PopupMenu(menuItem, clientpt);
758 
759  }
760 
761  //================================================================
762  //================================================================
763 
764  void WxTreeView::OnPopupFilter(wxCommandEvent& event)
765  {
766  wxBusyCursor busy;
768  "WxTreeView::OnEndLabelEdit"
769  <<std::endl);
770  unsigned int level = 0;
771  for (level = 0; level<mLevelList.size(); ++level)
772  {
773  if ( GetCtrl(level) == senderCtrl ) break;
774  }
775  std::string filter = crea::wx2std(wxGetTextFromUser(_T("Enter the filter to apply"), _T("Filter On Column")));
776 
777  std::string att;
778 
779  long it = -1;
780  UpdateLevel(level+1);
781 
782  std::vector<long> items;
783  bool in=false;
784  int del=0;
785  for ( ;; )
786  {
787  it = GetCtrl(level)->GetNextItem(it,
788  wxLIST_NEXT_ALL);
789  if ( it == -1 )
790  break;
791 
792  long adr = (long)GetCtrl(level)->GetItemData(it);
793  tree::Node* nod = ((ItemData*)adr)->node;
794  att=(*nod).GetAttribute(mLevelList[level].key[mColumnSelected]);
795 
796 
797  if(att.find(filter)>900)
798  {
799 
800  if(!in)
801  {
802  in=true;
803  }
804  else
805  {
806  del+=1;
807  }
808 
809  items.push_back(it-del);
810  }
811 
812  }
813  std::vector<long>::iterator iter;
814  for(iter=items.begin();iter!=items.end();++iter)
815  {
816  GetCtrl(level)->DeleteItem(*iter);
817  }
819  }
820  //================================================================
821 
822  //================================================================
823  void WxTreeView::OnPopupSort(wxCommandEvent& event)
824  {
825  wxBusyCursor busy;
826  unsigned int level = 0;
827  for (level = 0; level<mLevelList.size(); ++level)
828  {
829  if ( GetCtrl(level) == senderCtrl ) break;
830  }
831  mLevelList[level].SortColumn = mColumnSelected;
832 
833  if(event.GetId()==mAscendingID)
834  {
835  mLevelList[level].SortAscending = true;
836  }
837  else if(event.GetId()==mDescendingID)
838  {
839  mLevelList[level].SortAscending = false;
840  }
841 
842  SortLevel(level);
843  }
844  //================================================================
845 
846  void WxTreeView::OnAnonymizer(wxCommandEvent &event)
847  {
848  wxBusyCursor busy;
849  std::vector<std::string> filesname;
850  std::vector<tree::Node*> nodes;
851  nodes.push_back(((ItemData*)GetCtrl(mLastRightLevel)->GetItemData(mLastRightSelected))->node);
852  if(nodes.size() != 0)
853  {
854  GetFilenamesAsString(nodes,filesname);
855  GetGimmickView()->Anonymize(filesname,0);
856  }
857 
858  }
859 
860  //================================================================
861  void WxTreeView::OnLocalCopy(wxCommandEvent& event)
862  {
863  wxBusyCursor busy;
864 
865  unsigned int tempLevel = mLastLevel;
866  mLastLevel+=1;
867  const std::vector<tree::Node*>& sel=GetSelected(mLastLevel+1);
868 
869  if(sel.size() != 0)
870  {
871  bool copy=false;
872  std::stringstream out;
873  std::string levelName=GetTreeHandler()->GetTree().GetLevelDescriptor(mLastLevel).GetName();
874  out<<"Copy ";
875  out<<sel.size();
876  if(sel.size()>1&&levelName.at(levelName.size()-1)!='s')
877  {
878  out<<" "<<levelName;
879  out<<"s to .creaImageIO?";
880  }
881  else
882  {
883  out<<" "<<GetTreeHandler()->GetTree().GetLevelDescriptor(mLastLevel).GetName()<<" to .creaImageIO?";
884  }
885  if (wxMessageBox(crea::std2wx(out.str()),
886  _T("Remove Files"),
887  wxYES_NO,this ) == wxYES)
888  {
889  copy = true;
890  }
891  if(copy)
892  {
893  std::vector<std::string> s;
894  GetFilenamesAsString(sel,s);
896  }
897  }
898  else
899  {
900  mLastLevel = tempLevel;
901  }
902 
903 
904  }
905  //================================================================
906 
907  //================================================================
908  void WxTreeView::OnEditField(wxCommandEvent& event)
909  {
910  if(mLastRightSelected!=-1)
911  {
912  tree::Node* node=((ItemData*)GetCtrl(mLastRightLevel)->GetItemData(mLastRightSelected))->node;
913  tree::LevelDescriptor::AttributeDescriptorListType::const_iterator a;
914  std::vector<std::string> names;
915  std::vector<std::string> keys;
918  ++a)
919  {
921  {
922  names.push_back(a->GetName());
923  keys.push_back(a->GetKey());
924  }
925  }
926  GetGimmickView()->CreateEditFieldsDialog(node,names,keys);
927  }
928  }
929 
930  //================================================================
931 
932  //================================================================
933 
934  void WxTreeView::OnExportToStorage(wxCommandEvent &event)
935  {
936  std::vector<std::string> filesname;
937  std::vector<tree::Node*> nodes;
938  nodes.push_back(((ItemData*)GetCtrl(mLastRightLevel)->GetItemData(mLastRightSelected))->node);
939  GetFilenamesAsString(nodes,filesname);
940  GetGimmickView()->ExportToStorage(filesname);
941  }
942 
943  //================================================================
944 
945  //================================================================
946 
947  void WxTreeView::OnDumpTags(wxCommandEvent &event)
948  {
949  if(mLastRightSelected!=-1)
950  {
951  tree::Node* node=((ItemData*)GetCtrl(mLastRightLevel)->GetItemData(mLastRightSelected))->node;
952  tree::LevelDescriptor::AttributeDescriptorListType::const_iterator a;
953  std::vector<std::string> names;
954  std::vector<std::string> keys;
957  ++a)
958  {
959  if(a->GetKey()=="FullFileName")
960  {
961  GetGimmickView()->DumpTags(node->GetAttribute("FullFileName"));
962  return;
963  }
964  }
965  }
966  }
967 
968 
969  //================================================================
970 
971  //================================================================
972  void WxTreeView::SortLevel(int level)
973  {
975  "WxTreeView::SortLevel("
976  <<level<<")"
977  <<std::endl);
978  //Obtain the column name and the level that needs to be organized
979 
980  // int l = level - 1;
981  //Sets the data for the items to be sorted
982  // std::string att;
983  unsigned int ty=0;
984  int nbselected = 0;
985  int n = GetCtrl(level)->GetItemCount();
986  for (int i = 0; i < n; i++)
987  {
988 
989  //Gets current item data
990  ItemData* data = (ItemData*)GetCtrl(level)->GetItemData(i);
991 
992  //Extracts the node and the type of attribute
993  tree::Node* nod = data->node;
994  if(i==0)
995  {
997  (mLevelList[level].key[mLevelList[level].SortColumn])
998  .DecodeType( ty );
999  }
1000  //Obtains the organizing attribute
1001  data->attr = & (*nod).GetAttribute
1002  (mLevelList[level].key[mLevelList[level].SortColumn]);
1003  //Selected ?
1004  data->selected = false;
1005  if (GetCtrl(level)->GetItemState(i,wxLIST_STATE_SELECTED)>0)
1006  {
1007  data->selected = true;
1008  nbselected++;
1009  }
1010 
1011  }
1013  "WxTreeView::OnSort : "
1014  <<nbselected<<" selected before sorting"
1015  <<std::endl);
1016 
1017  mIgnoreSelectedChanged = true;
1018  //
1019  if (mLevelList[level].SortAscending)
1020  {
1021 
1022  if(ty==1)
1023  {
1024  GetCtrl(level)->SortItems(CompareFunctionInts, 0);
1025  }
1026  else
1027  {
1028  GetCtrl(level)->SortItems(CompareFunctionStrings, 0);
1029  }
1030 
1031  }
1032  else
1033  {
1034  if(ty==1)
1035  {
1036  GetCtrl(level)->SortItems(CompareFunctionInts, 1);
1037  }
1038  else
1039  {
1040  GetCtrl(level)->SortItems(CompareFunctionStrings, 1);
1041  }
1042  }
1043 
1044 
1045  // Reselects the unselected
1046  n = GetCtrl(level)->GetItemCount();
1047  int after = 0;
1048  for (int i = 0; i < n; i++)
1049  {
1050 
1051  //Gets current item data
1052  ItemData* data = (ItemData*)GetCtrl(level)->GetItemData(i);
1053 
1054  // long item = -1;
1055  // for ( ;; )
1056  // {
1057  // item = GetCtrl(level)->GetNextItem(item,wxLIST_NEXT_ALL);
1058  // if ( item == -1 ) break;
1059  //Gets current item data
1060  // ItemData* data = (ItemData*)GetCtrl(level)->GetItemData(item);
1061  // was selected ?
1062 
1063  if (data->selected)
1064  {
1065  nbselected--;
1066  if (nbselected==0)
1067  {
1068  // if it is the last one we must process the selection
1069  mIgnoreSelectedChanged = false;
1070  }
1071  GetCtrl(level)->SetItemState(i,
1072  wxLIST_STATE_SELECTED,
1073  wxLIST_MASK_STATE
1074  | wxLIST_MASK_TEXT
1075  | wxLIST_MASK_IMAGE
1076  | wxLIST_MASK_DATA
1077  | wxLIST_MASK_WIDTH
1078  | wxLIST_MASK_FORMAT);
1079  }
1080  if (GetCtrl(level)->GetItemState(i,wxLIST_STATE_SELECTED)>0)
1081  {
1082  after++;
1083  }
1084 
1085 
1086  }
1087  mIgnoreSelectedChanged = false;
1089  "WxTreeView::SortLevel : "
1090  <<after<<" selected after sorting"
1091  <<std::endl);
1092 
1093  }
1094  //================================================================
1095 
1096 
1097  //================================================================
1098  void WxTreeView::ValidateSelectedImages(bool isSelection)
1099  {
1101  "WxTreeView::ValidateSelectedImages"
1102  <<std::endl);
1103  const std::vector<tree::Node*>& sel(GetSelected((int)mLevelList.size()+1));
1105  isSelection,(mLastSelected-1),
1107 
1108  }
1109  //================================================================
1110 
1111 
1112  //================================================================
1113  void WxTreeView::GetNodes(std::vector<tree::Node*>& nodes, bool direction)
1114  {
1115  long item = mLastSelected;
1116  int level=(int)mLevelList.size()-1;
1117  //Gets current item data
1118  long adr = (long)GetCtrl(level)->GetItemData(item);
1119  //Extracts the node
1120  tree::Node* nod = ((ItemData*)adr)->node;
1121  for ( ;; )
1122  {
1123  if(direction)
1124  {
1125  item = GetCtrl(level)->GetNextItem(item,
1126  wxLIST_NEXT_ABOVE);
1127  }
1128  else
1129  {
1130  item = GetCtrl(level)->GetNextItem(item,
1131  wxLIST_NEXT_BELOW);
1132  }
1133  if ( item == -1 || item==0 )
1134  {
1135  break;
1136  }
1137  if(GetCtrl(level)->GetItemState(item, wxLIST_STATE_SELECTED)==0 )
1138  {
1139 
1140  adr = (long)GetCtrl(level)->GetItemData(item);
1141  nod = ((ItemData*)adr)->node;
1142  nodes.push_back(nod);
1143  }
1144  }
1145 
1146  }
1147  //================================================================
1148  //=================================================
1149  void WxTreeView::OnKeyDown(wxListEvent &event)
1150  {
1151  if(event.GetKeyCode() == WXK_DELETE)
1152  {
1153  wxBusyCursor busy;
1154  std::string temp = "0";
1155  RemoveSelected(temp);
1157  }
1158 
1159  }
1160  //================================================================
1161 
1162  //================================================================
1163  // Should be in another place : not specific !
1164  void WxTreeView::GetSelectedAsString(std::vector<std::string>&s)
1165  {
1166  int level= (int)mLevelList.size();
1167  const std::vector<tree::Node*>& sel=GetSelected(level+1);
1168  std::vector<tree::Node*>::const_iterator i;
1169 
1170  for (i=sel.begin(); i!=sel.end(); ++i)
1171  {
1172  std::string filename=(*i)->GetAttribute("FullFileName");
1173  s.push_back(filename);
1174  }
1175  }
1176 
1177 
1178 
1179  //================================================================
1180  void WxTreeView::GetFilenamesAsString(const std::vector<tree::Node*>& nodes, std::vector<std::string>&s)
1181  {
1182  std::vector<tree::Node*>::const_iterator i;
1183 
1184  for (i=nodes.begin(); i!=nodes.end(); ++i)
1185  {
1186  if((*i)->GetLevel()<mLevelList.size())
1187  {
1188  GetTreeHandler()->LoadChildren(*i,0);
1189  GetFilenamesAsString((*i)->GetChildrenList(),s);
1190  }
1191  else
1192  {
1193  std::string filename=(*i)->GetAttribute("FullFileName");
1194  s.push_back(filename);
1195  }
1196  }
1197  }
1198 
1199  //================================================================
1200 
1201  //================================================================
1202  void WxTreeView::GetAttributes(std::vector<std::string>& areShown, std::vector<std::string>& notShown, int level)
1203  {
1204  areShown.clear();
1205  notShown.clear();
1206  tree::LevelDescriptor::AttributeDescriptorListType::const_iterator a;
1207  for (a = GetTreeHandler()->GetTree().GetAttributeDescriptorList(level).begin();
1208  a != GetTreeHandler()->GetTree().GetAttributeDescriptorList(level).end();
1209  ++a)
1210  {
1211  if(a->GetFlags()==creaImageIO::tree::AttributeDescriptor::EDITABLE && IsAttributeVisible(a->GetName(),level))
1212  {
1213  areShown.push_back(a->GetName());
1214  }
1215  }
1216  notShown=mLevelList[level-1].notShownAtts;
1217  }
1218 
1219  //================================================================
1220  void WxTreeView::SetNonVisibleAttributes(const std::vector<std::string>& notShown, int nlevel)
1221  {
1222  mLevelList[nlevel].notShownAtts=notShown;
1223  }
1224 
1225  //================================================================
1226  void WxTreeView::CreateCtrl(std::vector<std::string>& notShown, int nlevel)
1227  {
1228  int ctrl_style = wxLC_REPORT | wxLC_VRULES;
1229  int col_style = wxLIST_FORMAT_LEFT;
1230  LevelType level;
1231  mLevelList[nlevel].SelectedUpToDate = true;
1232  mLevelList[nlevel].SortColumn = 0;
1233  mLevelList[nlevel].key.clear();
1234 
1235  mLevelList[nlevel].wxCtrl = new wxListCtrl(mLevelList[nlevel].wxSplitter,
1236  nlevel,
1237  wxDefaultPosition,
1238  wxDefaultSize,
1239  ctrl_style);
1240  wxWindow* oldWin=mLevelList[nlevel].wxSplitter->GetWindow1();
1241  mLevelList[nlevel].wxSplitter->ReplaceWindow(oldWin,mLevelList[nlevel].wxCtrl);
1242  mLevelList[nlevel].wxSplitter->Initialize(mLevelList[nlevel].wxCtrl);
1243 
1244  // Create the columns : one for each attribute of the level
1245  int col = 0;
1246  std::string title;
1247 
1248  tree::LevelDescriptor::AttributeDescriptorListType::const_iterator a;
1249  for (a = GetTreeHandler()->GetTree().GetAttributeDescriptorList(nlevel+1).begin();
1250  a != GetTreeHandler()->GetTree().GetAttributeDescriptorList(nlevel+1).end();
1251  ++a)
1252 
1253  {
1254  if(a->GetFlags()!=creaImageIO::tree::AttributeDescriptor::PRIVATE && IsAttributeVisible(a->GetName(),nlevel+1))
1255  {
1256  title=a->GetName();
1257  std::string temp = a->GetKey();
1258  if (temp.compare("ID") != 0)
1259  {
1260  mLevelList[nlevel].wxCtrl->InsertColumn(col,
1261  crea::std2wx(title),
1262  col_style);
1263  col++;
1264  }
1265  mLevelList[nlevel].key.push_back(a->GetKey());
1266  }
1267 
1268  }
1269  oldWin->Destroy();
1270  UpdateLevel(1);
1271  }
1272 
1273  //================================================================
1274  bool WxTreeView::IsAttributeVisible(const std::string& val, int level)
1275  {
1276  std::vector<std::string> ns=mLevelList[level-1].notShownAtts;
1277  std::vector<std::string>::iterator it;
1278  bool found=false;
1279  for(it=ns.begin();it!=ns.end()&&!found;++it)
1280  {
1281  if(val.compare(*it)==0)
1282  {
1283  found=true;
1284  }
1285  }
1286  return !found;
1287  }
1288  //================================================================
1289  //================================================================
1290 
1292  wxString title,
1293  const wxSize& size)
1294  : wxDialog( parent,
1295  wxID_ANY,
1296  title,
1297  wxDefaultPosition,
1298  size,
1299  wxDEFAULT_DIALOG_STYLE)
1300  {
1301  wxBoxSizer *topsizer = new wxBoxSizer(wxVERTICAL);
1302 
1303  //std::string out("To reload deleted patient, you should synchronize your database before."); // JPR
1304  //wxTextCtrl *text = new wxTextCtrl(this, wxID_ANY,crea::std2wx(out),wxDefaultPosition, wxSize(500,20));
1305  wxTextCtrl *text = new wxTextCtrl(this, wxID_ANY,
1306  _T("To reload deleted patient, you should synchronize your database before."),
1307  wxDefaultPosition, wxSize(650,20)); // 650 vs 500 ? // JPRx
1308  mcheck = new wxCheckBox(this, 5478, _T("Do not display this warning again!"));
1309  Connect( mcheck->GetId(), wxEVT_COMMAND_CHECKBOX_CLICKED , (wxObjectEventFunction) &RemoveAlertDlg::onCheck );
1310  wxSizer* buttonsSizer = this->CreateSeparatedButtonSizer(wxOK|wxCANCEL);
1311 
1312  topsizer->Add(text);
1313  topsizer->Add(mcheck,0,wxGROW);
1314  topsizer->Add(buttonsSizer,0,wxGROW);
1315  SetSizer(topsizer, true);
1316  mSave = false;
1317  Layout();
1318  }
1321  {
1322  return mSave;
1323  }
1324  void RemoveAlertDlg::onCheck(wxCommandEvent &Event)
1325  {
1326  mSave = mcheck->IsChecked();
1327  }
1328 
1329 
1330  //================================================================
1331  //================================================================
1332  BEGIN_EVENT_TABLE(WxTreeView, wxPanel)
1333  /*
1334  EVT_SIZE(MyFrame::OnSize)
1335 
1336  EVT_MENU(LIST_QUIT, MyFrame::OnQuit)
1337  EVT_MENU(LIST_ABOUT, MyFrame::OnAbout)
1338  EVT_MENU(LIST_LIST_VIEW, MyFrame::OnListView)
1339  EVT_MENU(LIST_REPORT_VIEW, MyFrame::OnReportView)
1340  EVT_MENU(LIST_ICON_VIEW, MyFrame::OnIconView)
1341  EVT_MENU(LIST_ICON_TEXT_VIEW, MyFrame::OnIconTextView)
1342  EVT_MENU(LIST_SMALL_ICON_VIEW, MyFrame::OnSmallIconView)
1343  EVT_MENU(LIST_SMALL_ICON_TEXT_VIEW, MyFrame::OnSmallIconTextView)
1344  EVT_MENU(LIST_VIRTUAL_VIEW, MyFrame::OnVirtualView)
1345  EVT_MENU(LIST_SMALL_VIRTUAL_VIEW, MyFrame::OnSmallVirtualView)
1346 
1347  EVT_MENU(LIST_FOCUS_LAST, MyFrame::OnFocusLast)
1348  EVT_MENU(LIST_TOGGLE_FIRST, MyFrame::OnToggleFirstSel)
1349  EVT_MENU(LIST_DESELECT_ALL, MyFrame::OnDeselectAll)
1350  EVT_MENU(LIST_SELECT_ALL, MyFrame::OnSelectAll)
1351  EVT_MENU(LIST_DELETE, MyFrame::OnDelete)
1352  EVT_MENU(LIST_ADD, MyFrame::OnAdd)
1353  EVT_MENU(LIST_EDIT, MyFrame::OnEdit)
1354  EVT_MENU(LIST_DELETE_ALL, MyFrame::OnDeleteAll)
1355  EVT_MENU(LIST_SORT, MyFrame::OnSort)
1356  EVT_MENU(LIST_SET_FG_COL, MyFrame::OnSetFgColour)
1357  EVT_MENU(LIST_SET_BG_COL, MyFrame::OnSetBgColour)
1358  EVT_MENU(LIST_TOGGLE_MULTI_SEL, MyFrame::OnToggleMultiSel)
1359  EVT_MENU(LIST_SHOW_COL_INFO, MyFrame::OnShowColInfo)
1360  EVT_MENU(LIST_SHOW_SEL_INFO, MyFrame::OnShowSelInfo)
1361  EVT_MENU(LIST_FREEZE, MyFrame::OnFreeze)
1362  EVT_MENU(LIST_THAW, MyFrame::OnThaw)
1363  EVT_MENU(LIST_TOGGLE_LINES, MyFrame::OnToggleLines)
1364  EVT_MENU(LIST_MAC_USE_GENERIC, MyFrame::OnToggleMacUseGeneric)
1365 
1366  EVT_UPDATE_UI(LIST_SHOW_COL_INFO, MyFrame::OnUpdateShowColInfo)
1367  EVT_UPDATE_UI(LIST_TOGGLE_MULTI_SEL, MyFrame::OnUpdateToggleMultiSel)
1368 END_EVENT_TABLE()
1369 
1370 BEGIN_EVENT_TABLE(MyListCtrl, wxListCtrl)
1371  EVT_LIST_BEGIN_DRAG(LIST_CTRL, MyListCtrl::OnBeginDrag)
1372  EVT_LIST_BEGIN_RDRAG(LIST_CTRL, MyListCtrl::OnBeginRDrag)
1373 
1374  EVT_LIST_BEGIN_LABEL_EDIT(-1, WxTreeView::OnBeginLabelEdit)
1375  EVT_LIST_END_LABEL_EDIT(-1, WxTreeView::OnEndLabelEdit)
1376 
1377  EVT_LIST_DELETE_ITEM(LIST_CTRL, MyListCtrl::OnDeleteItem)
1378  EVT_LIST_DELETE_ALL_ITEMS(LIST_CTRL, MyListCtrl::OnDeleteAllItems)
1379 #if WXWIN_COMPATIBILITY_2_4
1380  EVT_LIST_GET_INFO(LIST_CTRL, MyListCtrl::OnGetInfo)
1381  EVT_LIST_SET_INFO(LIST_CTRL, MyListCtrl::OnSetInfo)
1382 #endif
1383  */
1384  EVT_LIST_KEY_DOWN(-1, WxTreeView::OnKeyDown)
1385  EVT_LIST_ITEM_SELECTED(-1, WxTreeView::OnItemSelected)
1386  EVT_LIST_ITEM_RIGHT_CLICK(-1, WxTreeView::OnItemMenu)
1387  EVT_LIST_ITEM_DESELECTED(-1, WxTreeView::OnItemDeSelected)
1388  /*
1389  EVT_LIST_KEY_DOWN(LIST_CTRL, MyListCtrl::OnListKeyDown)
1390  EVT_LIST_ITEM_ACTIVATED(LIST_CTRL, MyListCtrl::OnActivated)
1391  EVT_LIST_ITEM_FOCUSED(LIST_CTRL, MyListCtrl::OnFocused)
1392 */
1393  EVT_LIST_COL_RIGHT_CLICK(-1, WxTreeView::OnColClick)
1394 
1395  EVT_LIST_COL_CLICK(-1, WxTreeView::OnColClick)
1396 
1397  //EVT_LEFT_DOWN(WxTreeView::OnMouseClick)
1398  /*
1399  EVT_LIST_COL_BEGIN_DRAG(LIST_CTRL, MyListCtrl::OnColBeginDrag)
1400  EVT_LIST_COL_DRAGGING(LIST_CTRL, MyListCtrl::OnColDragging)
1401  EVT_LIST_COL_END_DRAG(LIST_CTRL, MyListCtrl::OnColEndDrag)
1402 
1403  EVT_LIST_CACHE_HINT(LIST_CTRL, MyListCtrl::OnCacheHint)
1404 
1405 #if USE_CONTEXT_MENU
1406  EVT_CONTEXT_MENU(MyListCtrl::OnContextMenu)
1407 #endif
1408  EVT_CHAR(MyListCtrl::OnChar)
1409 
1410  EVT_RIGHT_DOWN(MyListCtrl::OnRightClick)
1411  */
1412 END_EVENT_TABLE()
1413 
1414 } // EO namespace creaImageIO
1415