Commit cfadc61673e9c29ec69a824fae95d65b2804bfbf
1 parent
a724a203
Exists in
master
and in
67 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 | ... | ... |