From 3f70e5f046b3900999ad8f745e081f9bf94868c8 Mon Sep 17 00:00:00 2001 From: tatiana Date: Sun, 25 Oct 2009 16:50:31 +0000 Subject: [PATCH] ENH: When DICOM import is cancelled, does not show import_panel --- invesalius/control.py | 21 ++++++++++++++++++--- invesalius/gui/dicom_preview_panel.py | 184 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------- invesalius/gui/frame.py | 22 ++++++++++++++++++++-- invesalius/gui/import_panel.py | 38 ++++++++++++++++++-------------------- invesalius/gui/task_importer.py | 2 +- invesalius/reader/dicom_grouper.py | 4 ++++ 6 files changed, 237 insertions(+), 34 deletions(-) diff --git a/invesalius/control.py b/invesalius/control.py index 3bc5608..c5e31f5 100755 --- a/invesalius/control.py +++ b/invesalius/control.py @@ -25,6 +25,7 @@ class Controller(): self.__bind_events() self.frame = frame self.progress_dialog = None + def __bind_events(self): ps.Publisher().subscribe(self.OnImportMedicalImages, 'Import directory') @@ -36,7 +37,12 @@ class Controller(): ps.Publisher().subscribe(self.OnOpenDicomGroup, 'Open DICOM group') ps.Publisher().subscribe(self.Progress, "Update dicom load") - ps.Publisher().subscribe(self.LoadPanel, "End dicom load") + ps.Publisher().subscribe(self.OnLoadImportPanel, "End dicom load") + ps.Publisher().subscribe(self.OnCancelImport, 'Cancel DICOM load') + ps.Publisher().subscribe(self.OnLoadImportPanel, "Show import panel in frame") + + def OnCancelImport(self, pubsub_evt): + self.cancel_import = True def StartImportPanel(self, pubsub_evt): # path to directory @@ -69,9 +75,18 @@ class Controller(): self.progress_dialog.Close() self.progress_dialog = None - - def LoadPanel(self,evt): + def OnLoadImportPanel(self, evt): patient_series = evt.data + if not self.cancel_import: + print "----- show" + self.LoadImportPanel(patient_series) + ps.Publisher().sendMessage('Show import panel') + else: + print "----- hide" + self.cancel_import = False + ps.Publisher().sendMessage('Hide import panel') + + def LoadImportPanel(self, patient_series): if patient_series: ps.Publisher().sendMessage("Load import panel", patient_series) first_patient = patient_series[0] diff --git a/invesalius/gui/dicom_preview_panel.py b/invesalius/gui/dicom_preview_panel.py index 653e613..f0cb602 100755 --- a/invesalius/gui/dicom_preview_panel.py +++ b/invesalius/gui/dicom_preview_panel.py @@ -25,6 +25,14 @@ myEVT_SELECT_SERIE = wx.NewEventType() # This event occurs when the user select a preview EVT_SELECT_SERIE = wx.PyEventBinder(myEVT_SELECT_SERIE, 1) + +myEVT_CLICK = wx.NewEventType() +EVT_CLICK = wx.PyEventBinder(myEVT_CLICK, 1) + + + + + class PreviewEvent(wx.PyCommandEvent): def __init__(self , evtType, id): wx.PyCommandEvent.__init__(self, evtType, id) @@ -35,6 +43,12 @@ class PreviewEvent(wx.PyCommandEvent): def SetSelectedID(self, id): self.SelectedID = id + def GetItemData(self): + return self.data + + def SetItemData(self, data): + self.data = data + class SerieEvent(PreviewEvent): def __init__(self , evtType, id): @@ -47,7 +61,7 @@ class Preview(wx.Panel): def __init__(self, parent): super(Preview, self).__init__(parent) # Will it be white? - self.SetBackgroundColour((255, 255, 255)) + self.select_on = False self._init_ui() self._init_vtk() self._bind_events() @@ -62,6 +76,8 @@ class Preview(wx.Panel): self.panel = wx.Panel(self, -1) + self.SetBackgroundColour((255,255,255)) + self.sizer = wx.BoxSizer(wx.VERTICAL) self.sizer.AddSpacer(2) self.sizer.Add(self.title, 1, @@ -105,16 +121,74 @@ class Preview(wx.Panel): def _bind_events(self): - self.Bind( wx.EVT_LEFT_DCLICK, self.OnSelect) - self.interactor.Bind( wx.EVT_LEFT_DCLICK, self.OnSelect) - self.panel.Bind( wx.EVT_LEFT_DCLICK, self.OnSelect) - self.title.Bind( wx.EVT_LEFT_DCLICK, self.OnSelect) - self.subtitle.Bind( wx.EVT_LEFT_DCLICK, self.OnSelect) + self.Bind( wx.EVT_LEFT_DCLICK, self.OnDClick) + self.interactor.Bind( wx.EVT_LEFT_DCLICK, self.OnDClick) + self.panel.Bind( wx.EVT_LEFT_DCLICK, self.OnDClick) + self.title.Bind( wx.EVT_LEFT_DCLICK, self.OnDClick) + self.subtitle.Bind( wx.EVT_LEFT_DCLICK, self.OnDClick) + + self.Bind(wx.EVT_ENTER_WINDOW, self.OnEnter) + self.interactor.Bind(wx.EVT_ENTER_WINDOW, self.OnEnter) + self.panel.Bind(wx.EVT_ENTER_WINDOW, self.OnEnter) + self.title.Bind(wx.EVT_ENTER_WINDOW, self.OnEnter) + self.subtitle.Bind(wx.EVT_ENTER_WINDOW, self.OnEnter) + + self.Bind(wx.EVT_LEAVE_WINDOW, self.OnLeave) + self.interactor.Bind(wx.EVT_LEAVE_WINDOW, self.OnLeave) + self.panel.Bind(wx.EVT_LEAVE_WINDOW, self.OnLeave) + self.title.Bind(wx.EVT_LEAVE_WINDOW, self.OnLeave) + self.subtitle.Bind(wx.EVT_LEAVE_WINDOW, self.OnLeave) + + self.Bind(wx.EVT_LEFT_DOWN, self.OnSelect) + self.interactor.Bind(wx.EVT_LEFT_DOWN, self.OnSelect) + self.panel.Bind(wx.EVT_LEFT_DOWN, self.OnSelect) + self.title.Bind(wx.EVT_LEFT_DOWN, self.OnSelect) + self.subtitle.Bind(wx.EVT_LEFT_DOWN, self.OnSelect) + + + + def OnEnter(self, evt): + if not self.select_on: + #c = wx.SystemSettings_GetColour(wx.SYS_COLOUR_3DHILIGHT) + c = wx.SystemSettings_GetColour(wx.SYS_COLOUR_HIGHLIGHT) + self.SetBackgroundColour(c) + + + def OnLeave(self, evt): + if not self.select_on: + c = (255,255,255) + self.SetBackgroundColour(c) def OnSelect(self, evt): + self.select_on = True + ##c = wx.SystemSettings_GetColour(wx.SYS_COLOUR_BTNHIGHLIGHT) + ##c = wx.SystemSettings_GetColour(wx.SYS_COLOUR_HOTLIGHT) + #c = wx.SystemSettings_GetColour(wx.SYS_COLOUR_HIGHLIGHT) + ##c = wx.SystemSettings_GetColour(wx.SYS_COLOUR_GRADIENTACTIVECAPTION) + #c = wx.SystemSettings_GetColour(wx.SYS_COLOUR_BTNSHADOW) + #c = wx.SystemSettings_GetColour(wx.SYS_COLOUR_ACTIVEBORDER) + #*c = wx.SystemSettings_GetColour(wx.SYS_COLOUR_3DLIGHT) + #*c = wx.SystemSettings_GetColour(wx.SYS_COLOUR_3DHILIGHT) + #c = wx.SystemSettings_GetColour(wx.SYS_COLOUR_3DHIGHLIGHT) + #c = wx.SystemSettings_GetColour(wx.SYS_COLOUR_3DDKSHADOW) + #c = wx.SystemSettings_GetColour(wx.SYS_COLOUR_3DSHADOW) + #self.SetBackgroundColour(c) + self.Select() + + def Select(self, on=True): + self.select_on = on + if on: + c = wx.SystemSettings_GetColour(wx.SYS_COLOUR_3DHIGHLIGHT) + else: + c = (255,255,255) + self.SetBackgroundColour(c) + + + def OnDClick(self, evt): evt = PreviewEvent(myEVT_SELECT, self.GetId()) evt.SetSelectedID(self.ID) + evt.SetItemData(self.data) self.GetEventHandler().ProcessEvent(evt) def SetTitle(self, title): @@ -154,6 +228,8 @@ class Preview(wx.Panel): #TODO: These values are good? level = 230 window = 150 + + self.data = image_file[-1] cast.SetWindow(window) cast.SetLevel(level) @@ -161,7 +237,87 @@ class Preview(wx.Panel): self.render.ResetCamera() self.interactor.Render() + def ShowShadow(self): + self._nImgSize = 16 + nPadding = 4 + print "ShowShadow" + dc = wx.BufferedPaintDC(self) + style = self.GetParent().GetWindowStyleFlag() + + backBrush = wx.WHITE_BRUSH + if 1: #style & INB_BORDER: + borderPen = wx.Pen(wx.SystemSettings_GetColour(wx.SYS_COLOUR_3DSHADOW)) + #else: + # borderPen = wx.TRANSPARENT_PEN + + size = self.GetSize() + + # Background + dc.SetBrush(backBrush) + + borderPen.SetWidth(1) + dc.SetPen(borderPen) + dc.DrawRectangle(0, 0, size.x, size.y) + #bUsePin = (style & INB_USE_PIN_BUTTON and [True] or [False])[0] + + borderPen = wx.BLACK_PEN + borderPen.SetWidth(1) + dc.SetPen(borderPen) + dc.DrawLine(0, size.y, size.x, size.y) + dc.DrawPoint(0, size.y) + + clientSize = 0 + #bUseYcoord = (style & INB_RIGHT or style & INB_LEFT) + bUseYcoord = 1 + + if bUseYcoord: + clientSize = size.GetHeight() + else: + clientSize = size.GetWidth() + + + if 1: + # Default values for the surronounding rectangle + # around a button + rectWidth = self._nImgSize * 2 # To avoid the recangle to 'touch' the borders + rectHeight = self._nImgSize * 2 + + # Incase the style requires non-fixed button (fit to text) + # recalc the rectangle width + if 1: + #if style & INB_FIT_BUTTON and \ + # not ((style & INB_LEFT) or (style & INB_RIGHT)) and \ + # not self._pagesInfoVec[i].GetCaption() == "" and \ + # not (style & INB_SHOW_ONLY_IMAGES): + + + #rectWidth = ((textWidth + nPadding * 2) > rectWidth and [nPadding * 2 + textWidth] or [rectWidth])[0] + + rectWidth = ((nPadding * 2) > rectWidth and [nPadding * 2] or [rectWidth])[0] + # Make the width an even number + if rectWidth % 2 != 0: + rectWidth += 1 + + # If Pin button is used, consider its space as well (applicable for top/botton style) + # since in the left/right, its size is already considered in 'pos' + #pinBtnSize = (bUsePin and [20] or [0])[0] + + #if pos + rectWidth + pinBtnSize > clientSize: + # break + # Calculate the button rectangle + modRectWidth = rectWidth - 2# or [rectWidth])[0] + modRectHeight = rectHeight# or [rectHeight - 2])[0] + + pos = rectWidth + + if bUseYcoord: + buttonRect = wx.Rect(1, pos, modRectWidth, modRectHeight) + else: + buttonRect = wx.Rect(pos , 1, modRectWidth, modRectHeight) + + def ShowShadow2(self): + pass class DicomPreviewSeries(wx.Panel): @@ -207,10 +363,16 @@ class DicomPreviewSeries(wx.Panel): for i in xrange(NROWS): for j in xrange(NCOLS): p = Preview(self) + if (i == j == 0): + self._show_shadow(p) #p.Hide() self.previews.append(p) self.grid.Add(p, 1, flag=wx.EXPAND) + def _show_shadow(self, preview): + preview.ShowShadow() + + def _bind_events(self): # When the user scrolls the window self.Bind(wx.EVT_SCROLL, self.OnScroll) @@ -219,6 +381,7 @@ class DicomPreviewSeries(wx.Panel): def OnSelect(self, evt): my_evt = SerieEvent(myEVT_SELECT_SERIE, self.GetId()) my_evt.SetSelectedID(evt.GetSelectID()) + my_evt.SetItemData(self.group_list) self.GetEventHandler().ProcessEvent(my_evt) def SetPatientGroups(self, patient): @@ -226,6 +389,7 @@ class DicomPreviewSeries(wx.Panel): self.displayed_position = 0 self.nhidden_last_display = 0 group_list = patient.GetGroups() + self.group_list = group_list print "LEN:", len(group_list) n = 0 for group in group_list: @@ -234,7 +398,8 @@ class DicomPreviewSeries(wx.Panel): float(group.dicom.image.level), group.title, "%d Images" %(group.nslices), - n) + n, + group_list) self.files.append(info) n+=1 @@ -271,6 +436,7 @@ class DicomPreviewSeries(wx.Panel): for f, p in zip(self.files[initial:final], self.previews): + #print "f", f p.SetImage(f) #p.interactor.Render() @@ -344,6 +510,7 @@ class DicomPreview(wx.Panel): self.displayed_position = 0 self.nhidden_last_display = 0 group = self.group_list[pos] + self.group = group #dicom_files = group.GetList() dicom_files = group.GetHandSortedList() n = 0 @@ -353,7 +520,8 @@ class DicomPreview(wx.Panel): dicom.image.level, "Image %d" % (dicom.image.number), "%.2f" % (dicom.image.position[2]), - n) + n, + dicom) self.files.append(info) n+=1 diff --git a/invesalius/gui/frame.py b/invesalius/gui/frame.py index 75e8e5f..376496c 100755 --- a/invesalius/gui/frame.py +++ b/invesalius/gui/frame.py @@ -78,15 +78,20 @@ class Frame(wx.Frame): def __bind_events(self): ps.Publisher().subscribe(self.ShowContentPanel, 'Show content panel') - ps.Publisher().subscribe(self.ShowImportPanel, "Show import panel") + ps.Publisher().subscribe(self.ShowImportPanel, "Show import panel in frame") ps.Publisher().subscribe(self.UpdateAui, "Update AUI") ps.Publisher().subscribe(self.ShowTask, 'Show task panel') ps.Publisher().subscribe(self.HideTask, 'Hide task panel') ps.Publisher().subscribe(self.SetProjectName, 'Set project name') + ps.Publisher().subscribe(self.ShowContentPanel, 'Cancel DICOM load') + ps.Publisher().subscribe(self.HideImportPanel, 'Hide import panel') def SetProjectName(self, pubsub_evt): proj_name = pubsub_evt.data - self.SetTitle("InVesalius 3 - %s"%(proj_name)) + if sys.platform != 'darwin': + self.SetTitle("%s - InVesalius 3"%(proj_name)) + else: + self.SetTitle("%s"%(proj_name)) def UpdateAui(self, pubsub_evt): self.aui_manager.Update() @@ -173,8 +178,21 @@ class Frame(wx.Frame): aui_manager.GetPane("Tasks").Show(0) aui_manager.Update() + def HideImportPanel(self, evt_pubsub): + print "HideImportPanel" + path = evt_pubsub.data + #ps.Publisher().sendMessage("Load data to import panel", path) + + aui_manager = self.aui_manager + aui_manager.GetPane("Import").Show(0) + aui_manager.GetPane("Data").Show(0) + aui_manager.GetPane("Tasks").Show(1) + aui_manager.Update() + + def ShowContentPanel(self, evt_pubsub): + print "ShowContentPanel" aui_manager = self.aui_manager aui_manager.GetPane("Import").Show(0) aui_manager.GetPane("Data").Show(1) diff --git a/invesalius/gui/import_panel.py b/invesalius/gui/import_panel.py index e1d8e91..59137a4 100644 --- a/invesalius/gui/import_panel.py +++ b/invesalius/gui/import_panel.py @@ -52,7 +52,7 @@ class InnerPanel(wx.Panel): def __bind_evt(self): ps.Publisher().subscribe(self.ShowDicomPreview, "Load import panel") - + def ShowDicomPreview(self, pubsub_evt): dicom_groups = pubsub_evt.data self.text_panel.Populate(dicom_groups) @@ -64,7 +64,13 @@ class TextPanel(wx.Panel): self.SetBackgroundColour((255,0,0)) self.Bind(wx.EVT_SIZE, self.OnSize) - + self.__init_gui() + self.__bind_evt() + + def __bind_evt(self): + ps.Publisher().subscribe(self.SelectSeries, 'Select series in import panel') + + def __init_gui(self): tree = gizmos.TreeListCtrl(self, -1, style = wx.TR_DEFAULT_STYLE | wx.TR_HIDE_ROOT @@ -105,6 +111,9 @@ class TextPanel(wx.Panel): self.root = tree.AddRoot("InVesalius Database") self.tree = tree + def SelectSeries(self, pubsub_evt): + group_index = pubsub_evt.data + def Populate(self, patient_list): tree = self.tree @@ -157,25 +166,17 @@ class TextPanel(wx.Panel): def OnSelChanged(self, evt): - print "OnLeftUp" item = self.tree.GetSelection() group = self.tree.GetItemPyData(item) if isinstance(group, dcm.DicomGroup): - print " :)" ps.Publisher().sendMessage('Load group into import panel', group) elif isinstance(group, dcm.PatientGroup): - print " :) patient" ps.Publisher().sendMessage('Load patient into import panel', group) - else: - print " :(" - - def OnActivate(self, evt): - print "OnActivate" item = evt.GetItem() group = self.tree.GetItemPyData(item) if isinstance(group, dcm.DicomGroup): @@ -189,10 +190,8 @@ class TextPanel(wx.Panel): def OnSize(self, evt): self.tree.SetSize(self.GetSize()) - - class ImagePanel(wx.Panel): def __init__(self, parent): wx.Panel.__init__(self, parent, -1) @@ -255,7 +254,6 @@ class SeriesPanel(wx.Panel): def SetDicomSeries(self, pubsub_evt): group = pubsub_evt.data - print "X" self.dicom_preview.SetDicomGroup(group) self.dicom_preview.Show(1) self.serie_preview.Show(0) @@ -264,23 +262,24 @@ class SeriesPanel(wx.Panel): def SetPatientSeries(self, pubsub_evt): - print "Z" patient = pubsub_evt.data - + self.dicom_preview.Show(0) self.serie_preview.Show(1) - - + + self.serie_preview.SetPatientGroups(patient) self.dicom_preview.SetPatientGroups(patient) - + self.Update() def OnSelectSerie(self, evt): serie = evt.GetSelectID() self.dicom_preview.SetDicomSerie(serie) - + + data = evt.GetItemData() + self.dicom_preview.Show(1) self.serie_preview.Show(0) self.sizer.Layout() @@ -289,7 +288,6 @@ class SeriesPanel(wx.Panel): def ShowDicomSeries(self, pubsub_evt): - print "---- ShowDicomSeries ----" patient = pubsub_evt.data self.serie_preview.SetPatientGroups(patient) self.dicom_preview.SetPatientGroups(patient) diff --git a/invesalius/gui/task_importer.py b/invesalius/gui/task_importer.py index be9daa0..aa21e04 100644 --- a/invesalius/gui/task_importer.py +++ b/invesalius/gui/task_importer.py @@ -144,7 +144,7 @@ class InnerTaskPanel(wx.Panel): if dlg.ShowModal() == wx.ID_OK: path = dlg.GetPath() - ps.Publisher().sendMessage("Show import panel", path) + ps.Publisher().sendMessage("Show import panel in frame", path) # Only destroy a dialog after you're done with it. dlg.Destroy() diff --git a/invesalius/reader/dicom_grouper.py b/invesalius/reader/dicom_grouper.py index b519991..604b39b 100644 --- a/invesalius/reader/dicom_grouper.py +++ b/invesalius/reader/dicom_grouper.py @@ -57,7 +57,11 @@ ORIENT_MAP = {"SAGITTAL":0, "CORONAL":1, "AXIAL":2, "OBLIQUE":2} class DicomGroup: + + general_index = -1 def __init__(self): + DicomGroup.general_index += 1 + self.index = DicomGroup.general_index # key: # (dicom.patient.name, dicom.acquisition.id_study, # dicom.acquisition.series_number, -- libgit2 0.21.2