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