Commit cfadc61673e9c29ec69a824fae95d65b2804bfbf
1 parent
a724a203
Exists in
master
and in
5 other branches
ADD: Added new feature to selecting images with shift button to importation
Showing
3 changed files
with
94 additions
and
36 deletions
Show diff stats
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 |