Commit cfadc61673e9c29ec69a824fae95d65b2804bfbf

Authored by Paulo Henrique Junqueira Amorim
1 parent a724a203

ADD: Added new feature to selecting images with shift button to importation

invesalius/control.py
@@ -437,14 +437,13 @@ class Controller(): @@ -437,14 +437,13 @@ class Controller():
437 proj.SavePlistProject(dirpath, filename) 437 proj.SavePlistProject(dirpath, filename)
438 438
439 def OnOpenDicomGroup(self, pubsub_evt): 439 def OnOpenDicomGroup(self, pubsub_evt):
440 - group, interval = pubsub_evt.data  
441 - imagedata, dicom = self.OpenDicomGroup(group, interval, gui=True) 440 + group, interval, file_range = pubsub_evt.data
  441 + imagedata, dicom = self.OpenDicomGroup(group, interval, file_range, gui=True)
442 self.CreateDicomProject(imagedata, dicom) 442 self.CreateDicomProject(imagedata, dicom)
443 self.LoadProject() 443 self.LoadProject()
444 ps.Publisher().sendMessage("Enable state project", True) 444 ps.Publisher().sendMessage("Enable state project", True)
445 445
446 - def OpenDicomGroup(self, dicom_group, interval, gui=True):  
447 - 446 + def OpenDicomGroup(self, dicom_group, interval, file_range, gui=True):
448 # Retrieve general DICOM headers 447 # Retrieve general DICOM headers
449 dicom = dicom_group.GetDicomSample() 448 dicom = dicom_group.GetDicomSample()
450 449
@@ -454,7 +453,10 @@ class Controller(): @@ -454,7 +453,10 @@ class Controller():
454 if not filelist: 453 if not filelist:
455 debug("Not used the IPPSorter") 454 debug("Not used the IPPSorter")
456 filelist = [i.image.file for i in dicom_group.GetHandSortedList()[::interval]] 455 filelist = [i.image.file for i in dicom_group.GetHandSortedList()[::interval]]
457 - 456 +
  457 + if file_range != None and file_range[1] > file_range[0]:
  458 + filelist = filelist[file_range[0]:file_range[1] + 1]
  459 +
458 zspacing = dicom_group.zspacing * interval 460 zspacing = dicom_group.zspacing * interval
459 size = dicom.image.size 461 size = dicom.image.size
460 bits = dicom.image.bits_allocad 462 bits = dicom.image.bits_allocad
invesalius/gui/dicom_preview_panel.py
@@ -29,6 +29,7 @@ import vtk @@ -29,6 +29,7 @@ import vtk
29 29
30 from vtk.util import numpy_support 30 from vtk.util import numpy_support
31 from vtk.wx.wxVTKRenderWindowInteractor import wxVTKRenderWindowInteractor 31 from vtk.wx.wxVTKRenderWindowInteractor import wxVTKRenderWindowInteractor
  32 +import wx.lib.pubsub as ps
32 33
33 import constants as const 34 import constants as const
34 from reader import dicom_reader 35 from reader import dicom_reader
@@ -68,6 +69,7 @@ EVT_CLICK_SERIE = wx.PyEventBinder(myEVT_CLICK_SERIE, 1) @@ -68,6 +69,7 @@ EVT_CLICK_SERIE = wx.PyEventBinder(myEVT_CLICK_SERIE, 1)
68 myEVT_CLICK = wx.NewEventType() 69 myEVT_CLICK = wx.NewEventType()
69 EVT_CLICK = wx.PyEventBinder(myEVT_CLICK, 1) 70 EVT_CLICK = wx.PyEventBinder(myEVT_CLICK, 1)
70 71
  72 +
71 class SelectionEvent(wx.PyCommandEvent): 73 class SelectionEvent(wx.PyCommandEvent):
72 pass 74 pass
73 75
@@ -85,9 +87,15 @@ class PreviewEvent(wx.PyCommandEvent): @@ -85,9 +87,15 @@ class PreviewEvent(wx.PyCommandEvent):
85 def GetItemData(self): 87 def GetItemData(self):
86 return self.data 88 return self.data
87 89
  90 + def GetPressedShift(self):
  91 + return self.pressed_shift
  92 +
88 def SetItemData(self, data): 93 def SetItemData(self, data):
89 self.data = data 94 self.data = data
90 95
  96 + def SetShiftStatus(self, status):
  97 + self.pressed_shift = status
  98 +
91 99
92 class SerieEvent(PreviewEvent): 100 class SerieEvent(PreviewEvent):
93 def __init__(self , evtType, id): 101 def __init__(self , evtType, id):
@@ -168,16 +176,12 @@ class Preview(wx.Panel): @@ -168,16 +176,12 @@ class Preview(wx.Panel):
168 The little previews. 176 The little previews.
169 """ 177 """
170 def __init__(self, parent): 178 def __init__(self, parent):
171 - super(Preview, self).__init__(parent, style=wx.TAB_TRAVERSAL|wx.NO_BORDER) 179 + super(Preview, self).__init__(parent)
172 # Will it be white? 180 # Will it be white?
173 self.select_on = False 181 self.select_on = False
174 self.dicom_info = None 182 self.dicom_info = None
175 self._init_ui() 183 self._init_ui()
176 -  
177 - self.selected_images = []  
178 - self.pressed_shift = 0  
179 self._bind_events() 184 self._bind_events()
180 - self.parent = parent  
181 185
182 def _init_ui(self): 186 def _init_ui(self):
183 self.SetBackgroundColour(PREVIEW_BACKGROUND) 187 self.SetBackgroundColour(PREVIEW_BACKGROUND)
@@ -222,23 +226,11 @@ class Preview(wx.Panel): @@ -222,23 +226,11 @@ class Preview(wx.Panel):
222 #self.subtitle.Bind(wx.EVT_LEAVE_WINDOW, self.OnLeave) 226 #self.subtitle.Bind(wx.EVT_LEAVE_WINDOW, self.OnLeave)
223 227
224 self.Bind(wx.EVT_LEFT_DOWN, self.OnSelect) 228 self.Bind(wx.EVT_LEFT_DOWN, self.OnSelect)
225 -  
226 self.title.Bind(wx.EVT_LEFT_DOWN, self.OnSelect) 229 self.title.Bind(wx.EVT_LEFT_DOWN, self.OnSelect)
227 self.subtitle.Bind(wx.EVT_LEFT_DOWN, self.OnSelect) 230 self.subtitle.Bind(wx.EVT_LEFT_DOWN, self.OnSelect)
228 self.image_viewer.Bind(wx.EVT_LEFT_DOWN, self.OnSelect) 231 self.image_viewer.Bind(wx.EVT_LEFT_DOWN, self.OnSelect)
229 232
230 #self.Bind(wx.EVT_SIZE, self.OnSize) 233 #self.Bind(wx.EVT_SIZE, self.OnSize)
231 -  
232 -  
233 - def OnPressedShift(self, evt):  
234 - print "ddddddddddddddddddddddddd"  
235 - if evt.GetKeyCode() == wx.WXK_SHIFT:  
236 - self.pressed_shift = 1  
237 -  
238 -  
239 - def OnReleasedShift(self, evt):  
240 - if evt.GetKeyCode() == wx.WXK_SHIFT:  
241 - self.pressed_shift = 0  
242 234
243 def SetDicomToPreview(self, dicom_info): 235 def SetDicomToPreview(self, dicom_info):
244 """ 236 """
@@ -277,6 +269,12 @@ class Preview(wx.Panel): @@ -277,6 +269,12 @@ class Preview(wx.Panel):
277 self.SetBackgroundColour(c) 269 self.SetBackgroundColour(c)
278 270
279 def OnSelect(self, evt): 271 def OnSelect(self, evt):
  272 +
  273 + shift_pressed = False
  274 + if evt.m_shiftDown:
  275 + shift_pressed = True
  276 +
  277 + dicom_id = self.dicom_info.id
280 self.select_on = True 278 self.select_on = True
281 self.dicom_info.selected = True 279 self.dicom_info.selected = True
282 ##c = wx.SystemSettings_GetColour(wx.SYS_COLOUR_BTNHIGHLIGHT) 280 ##c = wx.SystemSettings_GetColour(wx.SYS_COLOUR_BTNHIGHLIGHT)
@@ -292,19 +290,16 @@ class Preview(wx.Panel): @@ -292,19 +290,16 @@ class Preview(wx.Panel):
292 #c = wx.SystemSettings_GetColour(wx.SYS_COLOUR_3DSHADOW) 290 #c = wx.SystemSettings_GetColour(wx.SYS_COLOUR_3DSHADOW)
293 #self.SetBackgroundColour(c) 291 #self.SetBackgroundColour(c)
294 self.Select() 292 self.Select()
295 - print evt.m_shiftDown  
296 - print "SHIFTHHHHHHHHHHHHHHH>>>>", self.pressed_shift  
297 - if (self.pressed_shift):  
298 - dicom_id = self.dicom_info.id  
299 - print "=======>>>>>>>>>>>>>>>>>>>>>>>>>>>>", self.dicom_info.id  
300 - 293 +
301 # Generating a EVT_PREVIEW_CLICK event 294 # Generating a EVT_PREVIEW_CLICK event
302 my_evt = SerieEvent(myEVT_PREVIEW_CLICK, self.GetId()) 295 my_evt = SerieEvent(myEVT_PREVIEW_CLICK, self.GetId())
303 my_evt.SetSelectedID(self.dicom_info.id) 296 my_evt.SetSelectedID(self.dicom_info.id)
304 my_evt.SetItemData(self.dicom_info.dicom) 297 my_evt.SetItemData(self.dicom_info.dicom)
  298 + my_evt.SetShiftStatus(shift_pressed)
305 my_evt.SetEventObject(self) 299 my_evt.SetEventObject(self)
306 self.GetEventHandler().ProcessEvent(my_evt) 300 self.GetEventHandler().ProcessEvent(my_evt)
307 - 301 + evt.Skip()
  302 +
308 303
309 def OnSize(self, evt): 304 def OnSize(self, evt):
310 if self.dicom_info: 305 if self.dicom_info:
@@ -319,7 +314,6 @@ class Preview(wx.Panel): @@ -319,7 +314,6 @@ class Preview(wx.Panel):
319 self.SetBackgroundColour(c) 314 self.SetBackgroundColour(c)
320 self.Refresh() 315 self.Refresh()
321 316
322 -  
323 def OnDClick(self, evt): 317 def OnDClick(self, evt):
324 my_evt = SerieEvent(myEVT_PREVIEW_DBLCLICK, self.GetId()) 318 my_evt = SerieEvent(myEVT_PREVIEW_DBLCLICK, self.GetId())
325 my_evt.SetSelectedID(self.dicom_info.id) 319 my_evt.SetSelectedID(self.dicom_info.id)
@@ -475,6 +469,8 @@ class DicomPreviewSlice(wx.Panel): @@ -475,6 +469,8 @@ class DicomPreviewSlice(wx.Panel):
475 self.nhidden_last_display = 0 469 self.nhidden_last_display = 0
476 self.selected_dicom = None 470 self.selected_dicom = None
477 self.selected_panel = None 471 self.selected_panel = None
  472 + self.first_selection = None
  473 + self.last_selection = None
478 self._init_ui() 474 self._init_ui()
479 475
480 def _init_ui(self): 476 def _init_ui(self):
@@ -598,18 +594,61 @@ class DicomPreviewSlice(wx.Panel): @@ -598,18 +594,61 @@ class DicomPreviewSlice(wx.Panel):
598 p.Show() 594 p.Show()
599 595
600 def OnPreviewClick(self, evt): 596 def OnPreviewClick(self, evt):
  597 +
  598 + dicom_id = evt.GetSelectID()
  599 +
  600 + if self.first_selection is None:
  601 + self.first_selection = dicom_id
  602 +
  603 + if self.last_selection is None:
  604 + self.last_selection = dicom_id
  605 +
  606 +
  607 + if evt.GetPressedShift():
  608 +
  609 + if dicom_id < self.first_selection and dicom_id < self.last_selection:
  610 + self.first_selection = dicom_id
  611 + else:
  612 + self.last_selection = dicom_id
  613 + else:
  614 + self.first_selection = dicom_id
  615 + self.last_selection = dicom_id
  616 +
  617 + for i in xrange(len(self.files)):
  618 +
  619 + if i == dicom_id:
  620 + self.files[i].selected = True
  621 + else:
  622 + self.files[i].selected = False
  623 +
  624 +
601 my_evt = SerieEvent(myEVT_CLICK_SLICE, self.GetId()) 625 my_evt = SerieEvent(myEVT_CLICK_SLICE, self.GetId())
602 my_evt.SetSelectedID(evt.GetSelectID()) 626 my_evt.SetSelectedID(evt.GetSelectID())
603 my_evt.SetItemData(evt.GetItemData()) 627 my_evt.SetItemData(evt.GetItemData())
  628 +
604 if self.selected_dicom: 629 if self.selected_dicom:
605 self.selected_dicom.selected = self.selected_dicom is \ 630 self.selected_dicom.selected = self.selected_dicom is \
606 evt.GetEventObject().dicom_info 631 evt.GetEventObject().dicom_info
607 self.selected_panel.select_on = self.selected_panel is evt.GetEventObject() 632 self.selected_panel.select_on = self.selected_panel is evt.GetEventObject()
608 - self.selected_panel.Select() 633 +
  634 + if self.first_selection != self.last_selection:
  635 + for i in xrange(len(self.files)):
  636 + if i >= self.first_selection and i <= self.last_selection:
  637 + self.files[i].selected = True
  638 + else:
  639 + self.files[i].selected = False
  640 +
  641 + else:
  642 + self.selected_panel.Select()
  643 +
  644 + self._display_previews()
609 self.selected_panel = evt.GetEventObject() 645 self.selected_panel = evt.GetEventObject()
610 self.selected_dicom = self.selected_panel.dicom_info 646 self.selected_dicom = self.selected_panel.dicom_info
611 self.GetEventHandler().ProcessEvent(my_evt) 647 self.GetEventHandler().ProcessEvent(my_evt)
612 648
  649 + ps.Publisher().sendMessage("Selected Import Images", [self.first_selection, \
  650 + self.last_selection])
  651 +
613 def OnScroll(self, evt=None): 652 def OnScroll(self, evt=None):
614 if evt: 653 if evt:
615 if self.displayed_position != evt.GetPosition(): 654 if self.displayed_position != evt.GetPosition():
invesalius/gui/import_panel.py
@@ -78,7 +78,8 @@ class InnerPanel(wx.Panel): @@ -78,7 +78,8 @@ class InnerPanel(wx.Panel):
78 #size=wx.Size(680, 656)) 78 #size=wx.Size(680, 656))
79 79
80 self.patients = [] 80 self.patients = []
81 - 81 + self.first_image_selection = None
  82 + self.last_image_selection = None
82 self._init_ui() 83 self._init_ui()
83 self._bind_events() 84 self._bind_events()
84 self._bind_pubsubevt() 85 self._bind_pubsubevt()
@@ -126,7 +127,12 @@ class InnerPanel(wx.Panel): @@ -126,7 +127,12 @@ class InnerPanel(wx.Panel):
126 127
127 def _bind_pubsubevt(self): 128 def _bind_pubsubevt(self):
128 ps.Publisher().subscribe(self.ShowDicomPreview, "Load import panel") 129 ps.Publisher().subscribe(self.ShowDicomPreview, "Load import panel")
  130 + ps.Publisher().subscribe(self.GetSelectedImages ,"Selected Import Images")
129 131
  132 + def GetSelectedImages(self, pubsub_evt):
  133 + self.first_image_selection = pubsub_evt.data[0]
  134 + self.last_image_selection = pubsub_evt.data[1]
  135 +
130 def _bind_events(self): 136 def _bind_events(self):
131 self.Bind(EVT_SELECT_SERIE, self.OnSelectSerie) 137 self.Bind(EVT_SELECT_SERIE, self.OnSelectSerie)
132 self.Bind(EVT_SELECT_SLICE, self.OnSelectSlice) 138 self.Bind(EVT_SELECT_SLICE, self.OnSelectSlice)
@@ -171,11 +177,18 @@ class InnerPanel(wx.Panel): @@ -171,11 +177,18 @@ class InnerPanel(wx.Panel):
171 interval = self.combo_interval.GetSelection() 177 interval = self.combo_interval.GetSelection()
172 if not isinstance(group, dcm.DicomGroup): 178 if not isinstance(group, dcm.DicomGroup):
173 group = max(group.GetGroups(), key=lambda g: g.nslices) 179 group = max(group.GetGroups(), key=lambda g: g.nslices)
174 -  
175 - nslices_result = group.nslices / (interval + 1)  
176 - 180 +
  181 + slice_amont = group.nslices
  182 + if (self.first_image_selection != None) and (self.first_image_selection != self.last_image_selection):
  183 + slice_amont = (self.last_image_selection) - self.first_image_selection
  184 + slice_amont += 1
  185 + if slice_amont == 0:
  186 + slice_amont = group.nslices
  187 +
  188 + nslices_result = slice_amont / (interval + 1)
177 if (nslices_result > 1): 189 if (nslices_result > 1):
178 - ps.Publisher().sendMessage('Open DICOM group', (group, interval)) 190 + ps.Publisher().sendMessage('Open DICOM group', (group, interval,
  191 + [self.first_image_selection, self.last_image_selection]))
179 else: 192 else:
180 dlg.MissingFilesForReconstruction() 193 dlg.MissingFilesForReconstruction()
181 194
@@ -391,6 +404,7 @@ class SeriesPanel(wx.Panel): @@ -391,6 +404,7 @@ class SeriesPanel(wx.Panel):
391 self.serie_preview = dpp.DicomPreviewSeries(self) 404 self.serie_preview = dpp.DicomPreviewSeries(self)
392 self.dicom_preview = dpp.DicomPreviewSlice(self) 405 self.dicom_preview = dpp.DicomPreviewSlice(self)
393 self.dicom_preview.Show(0) 406 self.dicom_preview.Show(0)
  407 +
394 408
395 self.sizer = wx.BoxSizer(wx.HORIZONTAL) 409 self.sizer = wx.BoxSizer(wx.HORIZONTAL)
396 self.sizer.Add(self.serie_preview, 1, wx.EXPAND | wx.ALL, 5) 410 self.sizer.Add(self.serie_preview, 1, wx.EXPAND | wx.ALL, 5)
@@ -423,6 +437,9 @@ class SeriesPanel(wx.Panel): @@ -423,6 +437,9 @@ class SeriesPanel(wx.Panel):
423 self.sizer.Layout() 437 self.sizer.Layout()
424 self.Update() 438 self.Update()
425 439
  440 + def GetSelectedImagesRange(self):
  441 + return [self.dicom_preview.first_selected, self.dicom_preview_last_selection]
  442 +
426 def SetPatientSeries(self, pubsub_evt): 443 def SetPatientSeries(self, pubsub_evt):
427 patient = pubsub_evt.data 444 patient = pubsub_evt.data
428 445