Commit 3f70e5f046b3900999ad8f745e081f9bf94868c8

Authored by tatiana
1 parent d8121b0d

ENH: When DICOM import is cancelled, does not show import_panel

invesalius/control.py
... ... @@ -25,6 +25,7 @@ class Controller():
25 25 self.__bind_events()
26 26 self.frame = frame
27 27 self.progress_dialog = None
  28 +
28 29  
29 30 def __bind_events(self):
30 31 ps.Publisher().subscribe(self.OnImportMedicalImages, 'Import directory')
... ... @@ -36,7 +37,12 @@ class Controller():
36 37 ps.Publisher().subscribe(self.OnOpenDicomGroup,
37 38 'Open DICOM group')
38 39 ps.Publisher().subscribe(self.Progress, "Update dicom load")
39   - ps.Publisher().subscribe(self.LoadPanel, "End dicom load")
  40 + ps.Publisher().subscribe(self.OnLoadImportPanel, "End dicom load")
  41 + ps.Publisher().subscribe(self.OnCancelImport, 'Cancel DICOM load')
  42 + ps.Publisher().subscribe(self.OnLoadImportPanel, "Show import panel in frame")
  43 +
  44 + def OnCancelImport(self, pubsub_evt):
  45 + self.cancel_import = True
40 46  
41 47 def StartImportPanel(self, pubsub_evt):
42 48 # path to directory
... ... @@ -69,9 +75,18 @@ class Controller():
69 75 self.progress_dialog.Close()
70 76 self.progress_dialog = None
71 77  
72   -
73   - def LoadPanel(self,evt):
  78 + def OnLoadImportPanel(self, evt):
74 79 patient_series = evt.data
  80 + if not self.cancel_import:
  81 + print "----- show"
  82 + self.LoadImportPanel(patient_series)
  83 + ps.Publisher().sendMessage('Show import panel')
  84 + else:
  85 + print "----- hide"
  86 + self.cancel_import = False
  87 + ps.Publisher().sendMessage('Hide import panel')
  88 +
  89 + def LoadImportPanel(self, patient_series):
75 90 if patient_series:
76 91 ps.Publisher().sendMessage("Load import panel", patient_series)
77 92 first_patient = patient_series[0]
... ...
invesalius/gui/dicom_preview_panel.py
... ... @@ -25,6 +25,14 @@ myEVT_SELECT_SERIE = wx.NewEventType()
25 25 # This event occurs when the user select a preview
26 26 EVT_SELECT_SERIE = wx.PyEventBinder(myEVT_SELECT_SERIE, 1)
27 27  
  28 +
  29 +myEVT_CLICK = wx.NewEventType()
  30 +EVT_CLICK = wx.PyEventBinder(myEVT_CLICK, 1)
  31 +
  32 +
  33 +
  34 +
  35 +
28 36 class PreviewEvent(wx.PyCommandEvent):
29 37 def __init__(self , evtType, id):
30 38 wx.PyCommandEvent.__init__(self, evtType, id)
... ... @@ -35,6 +43,12 @@ class PreviewEvent(wx.PyCommandEvent):
35 43 def SetSelectedID(self, id):
36 44 self.SelectedID = id
37 45  
  46 + def GetItemData(self):
  47 + return self.data
  48 +
  49 + def SetItemData(self, data):
  50 + self.data = data
  51 +
38 52  
39 53 class SerieEvent(PreviewEvent):
40 54 def __init__(self , evtType, id):
... ... @@ -47,7 +61,7 @@ class Preview(wx.Panel):
47 61 def __init__(self, parent):
48 62 super(Preview, self).__init__(parent)
49 63 # Will it be white?
50   - self.SetBackgroundColour((255, 255, 255))
  64 + self.select_on = False
51 65 self._init_ui()
52 66 self._init_vtk()
53 67 self._bind_events()
... ... @@ -62,6 +76,8 @@ class Preview(wx.Panel):
62 76  
63 77 self.panel = wx.Panel(self, -1)
64 78  
  79 + self.SetBackgroundColour((255,255,255))
  80 +
65 81 self.sizer = wx.BoxSizer(wx.VERTICAL)
66 82 self.sizer.AddSpacer(2)
67 83 self.sizer.Add(self.title, 1,
... ... @@ -105,16 +121,74 @@ class Preview(wx.Panel):
105 121  
106 122  
107 123 def _bind_events(self):
108   - self.Bind( wx.EVT_LEFT_DCLICK, self.OnSelect)
109   - self.interactor.Bind( wx.EVT_LEFT_DCLICK, self.OnSelect)
110   - self.panel.Bind( wx.EVT_LEFT_DCLICK, self.OnSelect)
111   - self.title.Bind( wx.EVT_LEFT_DCLICK, self.OnSelect)
112   - self.subtitle.Bind( wx.EVT_LEFT_DCLICK, self.OnSelect)
  124 + self.Bind( wx.EVT_LEFT_DCLICK, self.OnDClick)
  125 + self.interactor.Bind( wx.EVT_LEFT_DCLICK, self.OnDClick)
  126 + self.panel.Bind( wx.EVT_LEFT_DCLICK, self.OnDClick)
  127 + self.title.Bind( wx.EVT_LEFT_DCLICK, self.OnDClick)
  128 + self.subtitle.Bind( wx.EVT_LEFT_DCLICK, self.OnDClick)
  129 +
  130 + self.Bind(wx.EVT_ENTER_WINDOW, self.OnEnter)
  131 + self.interactor.Bind(wx.EVT_ENTER_WINDOW, self.OnEnter)
  132 + self.panel.Bind(wx.EVT_ENTER_WINDOW, self.OnEnter)
  133 + self.title.Bind(wx.EVT_ENTER_WINDOW, self.OnEnter)
  134 + self.subtitle.Bind(wx.EVT_ENTER_WINDOW, self.OnEnter)
  135 +
  136 + self.Bind(wx.EVT_LEAVE_WINDOW, self.OnLeave)
  137 + self.interactor.Bind(wx.EVT_LEAVE_WINDOW, self.OnLeave)
  138 + self.panel.Bind(wx.EVT_LEAVE_WINDOW, self.OnLeave)
  139 + self.title.Bind(wx.EVT_LEAVE_WINDOW, self.OnLeave)
  140 + self.subtitle.Bind(wx.EVT_LEAVE_WINDOW, self.OnLeave)
  141 +
  142 + self.Bind(wx.EVT_LEFT_DOWN, self.OnSelect)
  143 + self.interactor.Bind(wx.EVT_LEFT_DOWN, self.OnSelect)
  144 + self.panel.Bind(wx.EVT_LEFT_DOWN, self.OnSelect)
  145 + self.title.Bind(wx.EVT_LEFT_DOWN, self.OnSelect)
  146 + self.subtitle.Bind(wx.EVT_LEFT_DOWN, self.OnSelect)
  147 +
  148 +
  149 +
113 150  
  151 + def OnEnter(self, evt):
  152 + if not self.select_on:
  153 + #c = wx.SystemSettings_GetColour(wx.SYS_COLOUR_3DHILIGHT)
  154 + c = wx.SystemSettings_GetColour(wx.SYS_COLOUR_HIGHLIGHT)
  155 + self.SetBackgroundColour(c)
  156 +
  157 +
  158 + def OnLeave(self, evt):
  159 + if not self.select_on:
  160 + c = (255,255,255)
  161 + self.SetBackgroundColour(c)
114 162  
115 163 def OnSelect(self, evt):
  164 + self.select_on = True
  165 + ##c = wx.SystemSettings_GetColour(wx.SYS_COLOUR_BTNHIGHLIGHT)
  166 + ##c = wx.SystemSettings_GetColour(wx.SYS_COLOUR_HOTLIGHT)
  167 + #c = wx.SystemSettings_GetColour(wx.SYS_COLOUR_HIGHLIGHT)
  168 + ##c = wx.SystemSettings_GetColour(wx.SYS_COLOUR_GRADIENTACTIVECAPTION)
  169 + #c = wx.SystemSettings_GetColour(wx.SYS_COLOUR_BTNSHADOW)
  170 + #c = wx.SystemSettings_GetColour(wx.SYS_COLOUR_ACTIVEBORDER)
  171 + #*c = wx.SystemSettings_GetColour(wx.SYS_COLOUR_3DLIGHT)
  172 + #*c = wx.SystemSettings_GetColour(wx.SYS_COLOUR_3DHILIGHT)
  173 + #c = wx.SystemSettings_GetColour(wx.SYS_COLOUR_3DHIGHLIGHT)
  174 + #c = wx.SystemSettings_GetColour(wx.SYS_COLOUR_3DDKSHADOW)
  175 + #c = wx.SystemSettings_GetColour(wx.SYS_COLOUR_3DSHADOW)
  176 + #self.SetBackgroundColour(c)
  177 + self.Select()
  178 +
  179 + def Select(self, on=True):
  180 + self.select_on = on
  181 + if on:
  182 + c = wx.SystemSettings_GetColour(wx.SYS_COLOUR_3DHIGHLIGHT)
  183 + else:
  184 + c = (255,255,255)
  185 + self.SetBackgroundColour(c)
  186 +
  187 +
  188 + def OnDClick(self, evt):
116 189 evt = PreviewEvent(myEVT_SELECT, self.GetId())
117 190 evt.SetSelectedID(self.ID)
  191 + evt.SetItemData(self.data)
118 192 self.GetEventHandler().ProcessEvent(evt)
119 193  
120 194 def SetTitle(self, title):
... ... @@ -154,6 +228,8 @@ class Preview(wx.Panel):
154 228 #TODO: These values are good?
155 229 level = 230
156 230 window = 150
  231 +
  232 + self.data = image_file[-1]
157 233  
158 234 cast.SetWindow(window)
159 235 cast.SetLevel(level)
... ... @@ -161,7 +237,87 @@ class Preview(wx.Panel):
161 237 self.render.ResetCamera()
162 238 self.interactor.Render()
163 239  
  240 + def ShowShadow(self):
  241 + self._nImgSize = 16
  242 + nPadding = 4
  243 + print "ShowShadow"
  244 + dc = wx.BufferedPaintDC(self)
  245 + style = self.GetParent().GetWindowStyleFlag()
  246 +
  247 + backBrush = wx.WHITE_BRUSH
  248 + if 1: #style & INB_BORDER:
  249 + borderPen = wx.Pen(wx.SystemSettings_GetColour(wx.SYS_COLOUR_3DSHADOW))
  250 + #else:
  251 + # borderPen = wx.TRANSPARENT_PEN
  252 +
  253 + size = self.GetSize()
  254 +
  255 + # Background
  256 + dc.SetBrush(backBrush)
  257 +
  258 + borderPen.SetWidth(1)
  259 + dc.SetPen(borderPen)
  260 + dc.DrawRectangle(0, 0, size.x, size.y)
  261 + #bUsePin = (style & INB_USE_PIN_BUTTON and [True] or [False])[0]
  262 +
  263 + borderPen = wx.BLACK_PEN
  264 + borderPen.SetWidth(1)
  265 + dc.SetPen(borderPen)
  266 + dc.DrawLine(0, size.y, size.x, size.y)
  267 + dc.DrawPoint(0, size.y)
  268 +
  269 + clientSize = 0
  270 + #bUseYcoord = (style & INB_RIGHT or style & INB_LEFT)
  271 + bUseYcoord = 1
  272 +
  273 + if bUseYcoord:
  274 + clientSize = size.GetHeight()
  275 + else:
  276 + clientSize = size.GetWidth()
  277 +
  278 +
  279 + if 1:
  280 + # Default values for the surronounding rectangle
  281 + # around a button
  282 + rectWidth = self._nImgSize * 2 # To avoid the recangle to 'touch' the borders
  283 + rectHeight = self._nImgSize * 2
  284 +
  285 + # Incase the style requires non-fixed button (fit to text)
  286 + # recalc the rectangle width
  287 + if 1:
  288 + #if style & INB_FIT_BUTTON and \
  289 + # not ((style & INB_LEFT) or (style & INB_RIGHT)) and \
  290 + # not self._pagesInfoVec[i].GetCaption() == "" and \
  291 + # not (style & INB_SHOW_ONLY_IMAGES):
  292 +
  293 +
  294 + #rectWidth = ((textWidth + nPadding * 2) > rectWidth and [nPadding * 2 + textWidth] or [rectWidth])[0]
  295 +
  296 + rectWidth = ((nPadding * 2) > rectWidth and [nPadding * 2] or [rectWidth])[0]
  297 + # Make the width an even number
  298 + if rectWidth % 2 != 0:
  299 + rectWidth += 1
  300 +
  301 + # If Pin button is used, consider its space as well (applicable for top/botton style)
  302 + # since in the left/right, its size is already considered in 'pos'
  303 + #pinBtnSize = (bUsePin and [20] or [0])[0]
  304 +
  305 + #if pos + rectWidth + pinBtnSize > clientSize:
  306 + # break
164 307  
  308 + # Calculate the button rectangle
  309 + modRectWidth = rectWidth - 2# or [rectWidth])[0]
  310 + modRectHeight = rectHeight# or [rectHeight - 2])[0]
  311 +
  312 + pos = rectWidth
  313 +
  314 + if bUseYcoord:
  315 + buttonRect = wx.Rect(1, pos, modRectWidth, modRectHeight)
  316 + else:
  317 + buttonRect = wx.Rect(pos , 1, modRectWidth, modRectHeight)
  318 +
  319 + def ShowShadow2(self):
  320 + pass
165 321  
166 322  
167 323 class DicomPreviewSeries(wx.Panel):
... ... @@ -207,10 +363,16 @@ class DicomPreviewSeries(wx.Panel):
207 363 for i in xrange(NROWS):
208 364 for j in xrange(NCOLS):
209 365 p = Preview(self)
  366 + if (i == j == 0):
  367 + self._show_shadow(p)
210 368 #p.Hide()
211 369 self.previews.append(p)
212 370 self.grid.Add(p, 1, flag=wx.EXPAND)
213 371  
  372 + def _show_shadow(self, preview):
  373 + preview.ShowShadow()
  374 +
  375 +
214 376 def _bind_events(self):
215 377 # When the user scrolls the window
216 378 self.Bind(wx.EVT_SCROLL, self.OnScroll)
... ... @@ -219,6 +381,7 @@ class DicomPreviewSeries(wx.Panel):
219 381 def OnSelect(self, evt):
220 382 my_evt = SerieEvent(myEVT_SELECT_SERIE, self.GetId())
221 383 my_evt.SetSelectedID(evt.GetSelectID())
  384 + my_evt.SetItemData(self.group_list)
222 385 self.GetEventHandler().ProcessEvent(my_evt)
223 386  
224 387 def SetPatientGroups(self, patient):
... ... @@ -226,6 +389,7 @@ class DicomPreviewSeries(wx.Panel):
226 389 self.displayed_position = 0
227 390 self.nhidden_last_display = 0
228 391 group_list = patient.GetGroups()
  392 + self.group_list = group_list
229 393 print "LEN:", len(group_list)
230 394 n = 0
231 395 for group in group_list:
... ... @@ -234,7 +398,8 @@ class DicomPreviewSeries(wx.Panel):
234 398 float(group.dicom.image.level),
235 399 group.title,
236 400 "%d Images" %(group.nslices),
237   - n)
  401 + n,
  402 + group_list)
238 403 self.files.append(info)
239 404 n+=1
240 405  
... ... @@ -271,6 +436,7 @@ class DicomPreviewSeries(wx.Panel):
271 436  
272 437  
273 438 for f, p in zip(self.files[initial:final], self.previews):
  439 + #print "f", f
274 440 p.SetImage(f)
275 441 #p.interactor.Render()
276 442  
... ... @@ -344,6 +510,7 @@ class DicomPreview(wx.Panel):
344 510 self.displayed_position = 0
345 511 self.nhidden_last_display = 0
346 512 group = self.group_list[pos]
  513 + self.group = group
347 514 #dicom_files = group.GetList()
348 515 dicom_files = group.GetHandSortedList()
349 516 n = 0
... ... @@ -353,7 +520,8 @@ class DicomPreview(wx.Panel):
353 520 dicom.image.level,
354 521 "Image %d" % (dicom.image.number),
355 522 "%.2f" % (dicom.image.position[2]),
356   - n)
  523 + n,
  524 + dicom)
357 525 self.files.append(info)
358 526 n+=1
359 527  
... ...
invesalius/gui/frame.py
... ... @@ -78,15 +78,20 @@ class Frame(wx.Frame):
78 78  
79 79 def __bind_events(self):
80 80 ps.Publisher().subscribe(self.ShowContentPanel, 'Show content panel')
81   - ps.Publisher().subscribe(self.ShowImportPanel, "Show import panel")
  81 + ps.Publisher().subscribe(self.ShowImportPanel, "Show import panel in frame")
82 82 ps.Publisher().subscribe(self.UpdateAui, "Update AUI")
83 83 ps.Publisher().subscribe(self.ShowTask, 'Show task panel')
84 84 ps.Publisher().subscribe(self.HideTask, 'Hide task panel')
85 85 ps.Publisher().subscribe(self.SetProjectName, 'Set project name')
  86 + ps.Publisher().subscribe(self.ShowContentPanel, 'Cancel DICOM load')
  87 + ps.Publisher().subscribe(self.HideImportPanel, 'Hide import panel')
86 88  
87 89 def SetProjectName(self, pubsub_evt):
88 90 proj_name = pubsub_evt.data
89   - self.SetTitle("InVesalius 3 - %s"%(proj_name))
  91 + if sys.platform != 'darwin':
  92 + self.SetTitle("%s - InVesalius 3"%(proj_name))
  93 + else:
  94 + self.SetTitle("%s"%(proj_name))
90 95  
91 96 def UpdateAui(self, pubsub_evt):
92 97 self.aui_manager.Update()
... ... @@ -173,8 +178,21 @@ class Frame(wx.Frame):
173 178 aui_manager.GetPane("Tasks").Show(0)
174 179 aui_manager.Update()
175 180  
  181 + def HideImportPanel(self, evt_pubsub):
  182 + print "HideImportPanel"
  183 + path = evt_pubsub.data
  184 + #ps.Publisher().sendMessage("Load data to import panel", path)
  185 +
  186 + aui_manager = self.aui_manager
  187 + aui_manager.GetPane("Import").Show(0)
  188 + aui_manager.GetPane("Data").Show(0)
  189 + aui_manager.GetPane("Tasks").Show(1)
  190 + aui_manager.Update()
  191 +
  192 +
176 193  
177 194 def ShowContentPanel(self, evt_pubsub):
  195 + print "ShowContentPanel"
178 196 aui_manager = self.aui_manager
179 197 aui_manager.GetPane("Import").Show(0)
180 198 aui_manager.GetPane("Data").Show(1)
... ...
invesalius/gui/import_panel.py
... ... @@ -52,7 +52,7 @@ class InnerPanel(wx.Panel):
52 52  
53 53 def __bind_evt(self):
54 54 ps.Publisher().subscribe(self.ShowDicomPreview, "Load import panel")
55   -
  55 +
56 56 def ShowDicomPreview(self, pubsub_evt):
57 57 dicom_groups = pubsub_evt.data
58 58 self.text_panel.Populate(dicom_groups)
... ... @@ -64,7 +64,13 @@ class TextPanel(wx.Panel):
64 64 self.SetBackgroundColour((255,0,0))
65 65 self.Bind(wx.EVT_SIZE, self.OnSize)
66 66  
67   -
  67 + self.__init_gui()
  68 + self.__bind_evt()
  69 +
  70 + def __bind_evt(self):
  71 + ps.Publisher().subscribe(self.SelectSeries, 'Select series in import panel')
  72 +
  73 + def __init_gui(self):
68 74 tree = gizmos.TreeListCtrl(self, -1, style =
69 75 wx.TR_DEFAULT_STYLE
70 76 | wx.TR_HIDE_ROOT
... ... @@ -105,6 +111,9 @@ class TextPanel(wx.Panel):
105 111 self.root = tree.AddRoot("InVesalius Database")
106 112 self.tree = tree
107 113  
  114 + def SelectSeries(self, pubsub_evt):
  115 + group_index = pubsub_evt.data
  116 +
108 117 def Populate(self, patient_list):
109 118 tree = self.tree
110 119  
... ... @@ -157,25 +166,17 @@ class TextPanel(wx.Panel):
157 166  
158 167  
159 168 def OnSelChanged(self, evt):
160   - print "OnLeftUp"
161 169 item = self.tree.GetSelection()
162 170 group = self.tree.GetItemPyData(item)
163 171 if isinstance(group, dcm.DicomGroup):
164   - print " :)"
165 172 ps.Publisher().sendMessage('Load group into import panel',
166 173 group)
167 174 elif isinstance(group, dcm.PatientGroup):
168   - print " :) patient"
169 175 ps.Publisher().sendMessage('Load patient into import panel',
170 176 group)
171 177  
172   - else:
173   - print " :("
174   -
175   -
176 178  
177 179 def OnActivate(self, evt):
178   - print "OnActivate"
179 180 item = evt.GetItem()
180 181 group = self.tree.GetItemPyData(item)
181 182 if isinstance(group, dcm.DicomGroup):
... ... @@ -189,10 +190,8 @@ class TextPanel(wx.Panel):
189 190  
190 191 def OnSize(self, evt):
191 192 self.tree.SetSize(self.GetSize())
192   -
193 193  
194 194  
195   -
196 195 class ImagePanel(wx.Panel):
197 196 def __init__(self, parent):
198 197 wx.Panel.__init__(self, parent, -1)
... ... @@ -255,7 +254,6 @@ class SeriesPanel(wx.Panel):
255 254  
256 255 def SetDicomSeries(self, pubsub_evt):
257 256 group = pubsub_evt.data
258   - print "X"
259 257 self.dicom_preview.SetDicomGroup(group)
260 258 self.dicom_preview.Show(1)
261 259 self.serie_preview.Show(0)
... ... @@ -264,23 +262,24 @@ class SeriesPanel(wx.Panel):
264 262  
265 263  
266 264 def SetPatientSeries(self, pubsub_evt):
267   - print "Z"
268 265 patient = pubsub_evt.data
269   -
  266 +
270 267 self.dicom_preview.Show(0)
271 268 self.serie_preview.Show(1)
272   -
273   -
  269 +
  270 +
274 271 self.serie_preview.SetPatientGroups(patient)
275 272 self.dicom_preview.SetPatientGroups(patient)
276   -
  273 +
277 274 self.Update()
278 275  
279 276  
280 277 def OnSelectSerie(self, evt):
281 278 serie = evt.GetSelectID()
282 279 self.dicom_preview.SetDicomSerie(serie)
283   -
  280 +
  281 + data = evt.GetItemData()
  282 +
284 283 self.dicom_preview.Show(1)
285 284 self.serie_preview.Show(0)
286 285 self.sizer.Layout()
... ... @@ -289,7 +288,6 @@ class SeriesPanel(wx.Panel):
289 288  
290 289  
291 290 def ShowDicomSeries(self, pubsub_evt):
292   - print "---- ShowDicomSeries ----"
293 291 patient = pubsub_evt.data
294 292 self.serie_preview.SetPatientGroups(patient)
295 293 self.dicom_preview.SetPatientGroups(patient)
... ...
invesalius/gui/task_importer.py
... ... @@ -144,7 +144,7 @@ class InnerTaskPanel(wx.Panel):
144 144  
145 145 if dlg.ShowModal() == wx.ID_OK:
146 146 path = dlg.GetPath()
147   - ps.Publisher().sendMessage("Show import panel", path)
  147 + ps.Publisher().sendMessage("Show import panel in frame", path)
148 148  
149 149 # Only destroy a dialog after you're done with it.
150 150 dlg.Destroy()
... ...
invesalius/reader/dicom_grouper.py
... ... @@ -57,7 +57,11 @@ ORIENT_MAP = {"SAGITTAL":0, "CORONAL":1, "AXIAL":2, "OBLIQUE":2}
57 57  
58 58  
59 59 class DicomGroup:
  60 +
  61 + general_index = -1
60 62 def __init__(self):
  63 + DicomGroup.general_index += 1
  64 + self.index = DicomGroup.general_index
61 65 # key:
62 66 # (dicom.patient.name, dicom.acquisition.id_study,
63 67 # dicom.acquisition.series_number,
... ...