Commit 1a15b12cdce9ad70e461fd3177fe10d77d35f52d

Authored by tatiana
1 parent 4d583c07

ADD: Project close feature (under devel)

invesalius/constants.py
@@ -85,10 +85,18 @@ SLICE_POSITION = {AXIAL:[AXIAL_SLICE_CAM_VIEW_UP, AXIAL_SLICE_CAM_POSITION], @@ -85,10 +85,18 @@ SLICE_POSITION = {AXIAL:[AXIAL_SLICE_CAM_VIEW_UP, AXIAL_SLICE_CAM_POSITION],
85 PROJ_NEW = 0 85 PROJ_NEW = 0
86 PROJ_OPEN = 1 86 PROJ_OPEN = 1
87 PROJ_CHANGE = 2 87 PROJ_CHANGE = 2
  88 +PROJ_CLOSE = 3
88 89
89 PROJ_MAX = 4 90 PROJ_MAX = 4
90 91
91 92
  93 +####
  94 +MODE_RP = 0
  95 +MODE_NAVIGATOR = 1
  96 +MODE_RADIOLOGY = 2
  97 +MODE_ODONTOLOGY = 3
  98 +
  99 +
92 100
93 #Color Table from Slice 101 #Color Table from Slice
94 #NumberOfColors, SaturationRange, HueRange, ValueRange 102 #NumberOfColors, SaturationRange, HueRange, ValueRange
invesalius/control.py
@@ -27,7 +27,8 @@ import constants as const @@ -27,7 +27,8 @@ import constants as const
27 import project as prj 27 import project as prj
28 28
29 import data.imagedata_utils as utils 29 import data.imagedata_utils as utils
30 -import data.surface as surface 30 +import data.mask as msk
  31 +import data.surface as srf
31 import data.volume as volume 32 import data.volume as volume
32 import reader.dicom_grouper as dg 33 import reader.dicom_grouper as dg
33 import gui.dialogs as dialog 34 import gui.dialogs as dialog
@@ -40,7 +41,7 @@ DEFAULT_THRESH_MODE = 0 @@ -40,7 +41,7 @@ DEFAULT_THRESH_MODE = 0
40 class Controller(): 41 class Controller():
41 42
42 def __init__(self, frame): 43 def __init__(self, frame):
43 - self.surface_manager = surface.SurfaceManager() 44 + self.surface_manager = srf.SurfaceManager()
44 self.volume = volume.Volume() 45 self.volume = volume.Volume()
45 self.__bind_events() 46 self.__bind_events()
46 self.frame = frame 47 self.frame = frame
@@ -51,7 +52,6 @@ class Controller(): @@ -51,7 +52,6 @@ class Controller():
51 52
52 def __bind_events(self): 53 def __bind_events(self):
53 ps.Publisher().subscribe(self.OnImportMedicalImages, 'Import directory') 54 ps.Publisher().subscribe(self.OnImportMedicalImages, 'Import directory')
54 - #ps.Publisher().subscribe(self.StartImportPanel, "Load data to import panel")  
55 ps.Publisher().subscribe(self.OnShowDialogImportDirectory, 55 ps.Publisher().subscribe(self.OnShowDialogImportDirectory,
56 'Show import directory dialog') 56 'Show import directory dialog')
57 ps.Publisher().subscribe(self.OnShowDialogOpenProject, 57 ps.Publisher().subscribe(self.OnShowDialogOpenProject,
@@ -68,8 +68,6 @@ class Controller(): @@ -68,8 +68,6 @@ class Controller():
68 ps.Publisher().subscribe(self.Progress, "Update dicom load") 68 ps.Publisher().subscribe(self.Progress, "Update dicom load")
69 ps.Publisher().subscribe(self.OnLoadImportPanel, "End dicom load") 69 ps.Publisher().subscribe(self.OnLoadImportPanel, "End dicom load")
70 ps.Publisher().subscribe(self.OnCancelImport, 'Cancel DICOM load') 70 ps.Publisher().subscribe(self.OnCancelImport, 'Cancel DICOM load')
71 - #ps.Publisher().subscribe(self.OnSaveProject, 'Save Project')  
72 - #ps.Publisher().subscribe(self.OnOpenProject, 'Open Project')  
73 ps.Publisher().subscribe(self.OnCloseProject, 'Close Project') 71 ps.Publisher().subscribe(self.OnCloseProject, 'Close Project')
74 72
75 73
@@ -110,6 +108,12 @@ class Controller(): @@ -110,6 +108,12 @@ class Controller():
110 session = ses.Session() 108 session = ses.Session()
111 session.OpenProject(path) 109 session.OpenProject(path)
112 110
  111 + mask = msk.Mask()
  112 + mask._set_class_index(proj.last_mask_index)
  113 +
  114 + surface = srf.Surface()
  115 + surface._set_class_index(proj.last_surface_index)
  116 +
113 self.LoadProject() 117 self.LoadProject()
114 118
115 def ShowDialogSaveProject(self, saveas=False): 119 def ShowDialogSaveProject(self, saveas=False):
@@ -139,6 +143,26 @@ class Controller(): @@ -139,6 +143,26 @@ class Controller():
139 proj = prj.Project() 143 proj = prj.Project()
140 prj.Project().SavePlistProject(dirpath, filename) 144 prj.Project().SavePlistProject(dirpath, filename)
141 145
  146 + def CloseProject(self):
  147 + print "Close Project"
  148 + session = ses.Session()
  149 + session.CloseProject()
  150 +
  151 + proj = prj.Project()
  152 + proj.Close()
  153 +
  154 + # TODO:
  155 + # Remove items from combo of masks
  156 + # Remove items from combo of surfaces
  157 + # Remove items from dictionaries
  158 + # Slice
  159 + # Surface
  160 + # --------------
  161 + #
  162 +
  163 + ps.Publisher().sendMessage('Hide content panel')
  164 +
  165 +
142 ################################## 166 ##################################
143 167
144 168
@@ -348,11 +372,15 @@ class Controller(): @@ -348,11 +372,15 @@ class Controller():
348 answer = dialog.SaveChangesDialog(filename) 372 answer = dialog.SaveChangesDialog(filename)
349 if not answer: 373 if not answer:
350 print "Close without changes" 374 print "Close without changes"
  375 + self.CloseProject()
351 elif answer == 1: 376 elif answer == 1:
  377 + self.ShowDialogSaveProject()
352 print "Save changes and close" 378 print "Save changes and close"
  379 + self.CloseProject()
353 #else: 380 #else:
354 # print "Cancel" 381 # print "Cancel"
355 else: 382 else:
356 print ":) Close without changes" 383 print ":) Close without changes"
  384 + self.CloseProject()
357 385
358 386
invesalius/data/mask.py
@@ -78,4 +78,5 @@ class Mask(): @@ -78,4 +78,5 @@ class Mask():
78 else: 78 else:
79 setattr(self, key, mask[key]) 79 setattr(self, key, mask[key])
80 80
81 - 81 + def _set_class_index(self, index):
  82 + Mask.general_index = index
invesalius/data/slice_.py
@@ -85,6 +85,19 @@ class Slice(object): @@ -85,6 +85,19 @@ class Slice(object):
85 ps.Publisher().subscribe(self.InputImageWidget, 'Input Image in the widget') 85 ps.Publisher().subscribe(self.InputImageWidget, 'Input Image in the widget')
86 ps.Publisher().subscribe(self.OnExportMask,'Export mask to file') 86 ps.Publisher().subscribe(self.OnExportMask,'Export mask to file')
87 87
  88 + ps.Publisher().subscribe(self.OnCloseProject, 'Close Project')
  89 +
  90 + def OnCloseProject(self, pubsub_evt):
  91 + self.CloseProject()
  92 +
  93 + def CloseProject(self):
  94 + self.imagedata = None
  95 + self.current_mask = None
  96 + self.blend_filter = None
  97 + #self.blend_filter = None
  98 + #self.num_gradient = 0
  99 +
  100 +
88 def __set_current_mask_threshold_limits(self, pubsub_evt): 101 def __set_current_mask_threshold_limits(self, pubsub_evt):
89 thresh_min = pubsub_evt.data[0] 102 thresh_min = pubsub_evt.data[0]
90 thresh_max = pubsub_evt.data[1] 103 thresh_max = pubsub_evt.data[1]
@@ -523,8 +536,8 @@ class Slice(object): @@ -523,8 +536,8 @@ class Slice(object):
523 536
524 # insert new mask into project and retrieve its index 537 # insert new mask into project and retrieve its index
525 proj = Project() 538 proj = Project()
526 - proj.AddMask(future_mask.index, future_mask)  
527 - 539 + index = proj.AddMask(future_mask)
  540 + future_mask.index = index
528 541
529 # update gui related to mask 542 # update gui related to mask
530 ps.Publisher().sendMessage('Add mask', 543 ps.Publisher().sendMessage('Add mask',
invesalius/data/surface.py
@@ -71,7 +71,8 @@ class Surface(): @@ -71,7 +71,8 @@ class Surface():
71 else: 71 else:
72 setattr(self, key, surface[key]) 72 setattr(self, key, surface[key])
73 73
74 - 74 + def _set_class_index(self, index):
  75 + Surface.general_index = index
75 76
76 77
77 # TODO: will be initialized inside control as it is being done? 78 # TODO: will be initialized inside control as it is being done?
@@ -102,6 +103,15 @@ class SurfaceManager(): @@ -102,6 +103,15 @@ class SurfaceManager():
102 ps.Publisher().subscribe(self.OnShowSurface, 'Show surface') 103 ps.Publisher().subscribe(self.OnShowSurface, 'Show surface')
103 ps.Publisher().subscribe(self.OnExportSurface,'Export surface to file') 104 ps.Publisher().subscribe(self.OnExportSurface,'Export surface to file')
104 ps.Publisher().subscribe(self.OnLoadSurfaceDict, 'Load surface dict') 105 ps.Publisher().subscribe(self.OnLoadSurfaceDict, 'Load surface dict')
  106 + ps.Publisher().subscribe(self.OnCloseProject, 'Close Project')
  107 +
  108 + def OnCloseProject(self, pubsub_evt):
  109 + self.CloseProject()
  110 +
  111 + def CloseProject(self):
  112 + del self.actors_dict
  113 + self.actors_dict = {}
  114 +
105 115
106 def OnLoadSurfaceDict(self, pubsub_evt): 116 def OnLoadSurfaceDict(self, pubsub_evt):
107 surface_dict = pubsub_evt.data 117 surface_dict = pubsub_evt.data
@@ -291,7 +301,8 @@ class SurfaceManager(): @@ -291,7 +301,8 @@ class SurfaceManager():
291 301
292 # Append surface into Project.surface_dict 302 # Append surface into Project.surface_dict
293 proj = prj.Project() 303 proj = prj.Project()
294 - proj.surface_dict[surface.index] = surface 304 + index = proj.AddSurface(surface)
  305 + surface.index = index
295 306
296 307
297 session = ses.Session() 308 session = ses.Session()
invesalius/gui/data_notebook.py
@@ -84,7 +84,13 @@ class MasksListCtrlPanel(wx.ListCtrl, listmix.TextEditMixin): @@ -84,7 +84,13 @@ class MasksListCtrlPanel(wx.ListCtrl, listmix.TextEditMixin):
84 'Change mask colour in notebook') 84 'Change mask colour in notebook')
85 85
86 ps.Publisher().subscribe(self.OnChangeCurrentMask, 'Change mask selected') 86 ps.Publisher().subscribe(self.OnChangeCurrentMask, 'Change mask selected')
87 - 87 + ps.Publisher().subscribe(self.OnCloseProject, 'Close Project')
  88 +
  89 + def OnCloseProject(self, pubsub_evt):
  90 + self.DeleteAllItems()
  91 + self.mask_list_index = {}
  92 + self.mask_bmp_idx_to_name = {}
  93 +
88 def OnChangeCurrentMask(self, pubsub_evt): 94 def OnChangeCurrentMask(self, pubsub_evt):
89 95
90 mask_index = pubsub_evt.data 96 mask_index = pubsub_evt.data
@@ -211,6 +217,12 @@ class SurfacesListCtrlPanel(wx.ListCtrl, listmix.TextEditMixin): @@ -211,6 +217,12 @@ class SurfacesListCtrlPanel(wx.ListCtrl, listmix.TextEditMixin):
211 'Set surface transparency') 217 'Set surface transparency')
212 ps.Publisher().subscribe(self.EditSurfaceColour, 218 ps.Publisher().subscribe(self.EditSurfaceColour,
213 'Set surface colour') 219 'Set surface colour')
  220 + ps.Publisher().subscribe(self.OnCloseProject, 'Close Project')
  221 +
  222 + def OnCloseProject(self, pubsub_evt):
  223 + self.DeleteAllItems()
  224 + self.surface_list_index = {}
  225 + self.surface_bmp_idx_to_name = {}
214 226
215 def __bind_events_wx(self): 227 def __bind_events_wx(self):
216 self.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self.OnItemActivated) 228 self.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self.OnItemActivated)
invesalius/gui/dialogs.py
@@ -132,13 +132,9 @@ WILDCARD_OPEN = "InVesalius 3 project (*.inv3)|*.inv3|"\ @@ -132,13 +132,9 @@ WILDCARD_OPEN = "InVesalius 3 project (*.inv3)|*.inv3|"\
132 132
133 def ShowOpenProjectDialog(): 133 def ShowOpenProjectDialog():
134 # Default system path 134 # Default system path
135 - if sys.platform == 'win32':  
136 - default_path = ""  
137 - else:  
138 - default_path = os.getcwd()  
139 135
140 dlg = wx.FileDialog(None, message="Open InVesalius 3 project...", 136 dlg = wx.FileDialog(None, message="Open InVesalius 3 project...",
141 - defaultDir=default_path, 137 + defaultDir="",
142 defaultFile="", wildcard=WILDCARD_OPEN, 138 defaultFile="", wildcard=WILDCARD_OPEN,
143 style=wx.OPEN|wx.CHANGE_DIR) 139 style=wx.OPEN|wx.CHANGE_DIR)
144 140
invesalius/gui/frame.py
@@ -89,7 +89,7 @@ class Frame(wx.Frame): @@ -89,7 +89,7 @@ class Frame(wx.Frame):
89 ps.Publisher().subscribe(self.HideImportPanel, 'Hide import panel') 89 ps.Publisher().subscribe(self.HideImportPanel, 'Hide import panel')
90 ps.Publisher().subscribe(self.BeginBusyCursor, 'Begin busy cursor') 90 ps.Publisher().subscribe(self.BeginBusyCursor, 'Begin busy cursor')
91 ps.Publisher().subscribe(self.EndBusyCursor, 'End busy cursor') 91 ps.Publisher().subscribe(self.EndBusyCursor, 'End busy cursor')
92 - 92 + ps.Publisher().subscribe(self.HideContentPanel, 'Hide content panel')
93 93
94 def EndBusyCursor(self, pubsub_evt=None): 94 def EndBusyCursor(self, pubsub_evt=None):
95 wx.EndBusyCursor() 95 wx.EndBusyCursor()
@@ -209,6 +209,12 @@ class Frame(wx.Frame): @@ -209,6 +209,12 @@ class Frame(wx.Frame):
209 aui_manager.GetPane("Tasks").Show(1) 209 aui_manager.GetPane("Tasks").Show(1)
210 aui_manager.Update() 210 aui_manager.Update()
211 211
  212 + def HideContentPanel(self, pubsub_evt):
  213 + aui_manager = self.aui_manager
  214 + aui_manager.GetPane("Data").Show(0)
  215 + aui_manager.GetPane("Tasks").Show(1)
  216 + aui_manager.Update()
  217 +
212 def OnSize(self, evt): 218 def OnSize(self, evt):
213 ps.Publisher().sendMessage(('ProgressBar Reposition')) 219 ps.Publisher().sendMessage(('ProgressBar Reposition'))
214 evt.Skip() 220 evt.Skip()
invesalius/gui/task_slice.py
@@ -291,6 +291,19 @@ class MaskProperties(wx.Panel): @@ -291,6 +291,19 @@ class MaskProperties(wx.Panel):
291 'Set threshold values in gradient') 291 'Set threshold values in gradient')
292 ps.Publisher().subscribe(self.SelectMaskName, 'Select mask name in combo') 292 ps.Publisher().subscribe(self.SelectMaskName, 'Select mask name in combo')
293 ps.Publisher().subscribe(self.ChangeMaskName, 'Change mask name') 293 ps.Publisher().subscribe(self.ChangeMaskName, 'Change mask name')
  294 + ps.Publisher().subscribe(self.OnCloseProject, 'Close Project')
  295 +
  296 + def OnCloseProject(self, pubsub_evt):
  297 + self.CloseProject()
  298 +
  299 + def CloseProject(self):
  300 + n = self.combo_mask_name.GetCount()
  301 + for i in xrange(n-1, -1, -1):
  302 + self.combo_mask_name.Delete(i)
  303 + n = self.combo_thresh.GetCount()
  304 + for i in xrange(n-1, -1, -1):
  305 + self.combo_thresh.Delete(i)
  306 +
294 307
295 def __bind_events_wx(self): 308 def __bind_events_wx(self):
296 self.Bind(grad.EVT_THRESHOLD_CHANGE, self.OnSlideChanged, self.gradient) 309 self.Bind(grad.EVT_THRESHOLD_CHANGE, self.OnSlideChanged, self.gradient)
invesalius/gui/task_surface.py
@@ -339,11 +339,19 @@ class SurfaceProperties(wx.Panel): @@ -339,11 +339,19 @@ class SurfaceProperties(wx.Panel):
339 def __bind_events(self): 339 def __bind_events(self):
340 ps.Publisher().subscribe(self.InsertNewSurface, 340 ps.Publisher().subscribe(self.InsertNewSurface,
341 'Update surface info in GUI') 341 'Update surface info in GUI')
342 - ps.Publisher().subscribe(self.ChangeMaskName, 342 + ps.Publisher().subscribe(self.ChangeSurfaceName,
343 'Change surface name') 343 'Change surface name')
  344 + ps.Publisher().subscribe(self.OnCloseProject, 'Close Project')
344 345
  346 + def OnCloseProject(self, pubsub_evt):
  347 + self.CloseProject()
345 348
346 - def ChangeMaskName(self, pubsub_evt): 349 + def CloseProject(self):
  350 + n = self.combo_surface_name.GetCount()
  351 + for i in xrange(n-1, -1, -1):
  352 + self.combo_surface_name.Delete(i)
  353 +
  354 + def ChangeSurfaceName(self, pubsub_evt):
347 index, name = pubsub_evt.data 355 index, name = pubsub_evt.data
348 self.combo_surface_name.SetString(index, name) 356 self.combo_surface_name.SetString(index, name)
349 self.combo_surface_name.Refresh() 357 self.combo_surface_name.Refresh()
invesalius/project.py
@@ -43,80 +43,61 @@ class Project(object): @@ -43,80 +43,61 @@ class Project(object):
43 __metaclass__= Singleton 43 __metaclass__= Singleton
44 44
45 def __init__(self): 45 def __init__(self):
46 - # TODO: Discuss  
47 - # [Tati] Will this type of data be written on project file? What if user  
48 - # changes file name and directory? I guess no... But, who knows...  
49 - #self.name = "Default"  
50 - #self.dir_ = "C:\\"  
51 -  
52 - # Original vtkImageData, build based on medical images read.  
53 - # To be used for general 2D slices rendering both on 2D and 3D  
54 - # coordinate systems. It might be used, as well, for 3D raycasting.  
55 - # rendering.  
56 - # TODO: Discuss when this will be used.  
57 - self.imagedata = ''  
58 - 46 + # Patient/ acquistion information
59 self.name = '' 47 self.name = ''
60 #self.dicom = '' 48 #self.dicom = ''
61 self.modality = '' 49 self.modality = ''
62 - self.original_orientation = -1  
63 -  
64 - # Masks are related to vtkImageData  
65 - self.mask_dict = {}  
66 - # Predefined threshold values 50 + self.original_orientation = ''
67 self.min_threshold = '' 51 self.min_threshold = ''
68 self.max_threshold = '' 52 self.max_threshold = ''
69 -  
70 self.window = '' 53 self.window = ''
71 self.level = '' 54 self.level = ''
72 55
  56 + # Original imagedata (shouldn't be changed)
  57 + self.imagedata = ''
  58 +
  59 + # Masks (vtkImageData)
  60 + self.mask_dict = {}
  61 + self.last_mask_index = 0
  62 +
  63 + # Surfaces are (vtkPolyData)
  64 + self.surface_dict = {}
  65 + self.last_surface_index = -1
  66 +
  67 + # TODO: Future
  68 + self.measure_dict = {}
  69 +
  70 + # TODO: Future ++
  71 + self.annotation_dict = {}
  72 +
  73 + # InVesalius related data
  74 + # So we can find bugs and reproduce user-related problems
  75 + self.invesalius_version = version.get_svn_revision()
  76 +
73 self.presets = Presets() 77 self.presets = Presets()
  78 +
74 self.threshold_modes = self.presets.thresh_ct 79 self.threshold_modes = self.presets.thresh_ct
75 self.threshold_range = '' 80 self.threshold_range = ''
76 -  
77 - self.original_orientation = ''  
78 - # MRI ? CT?  
79 81
  82 + self.raycasting_preset = ''
80 83
81 - # TODO: define how we will relate these threshold values to  
82 - # default threshold labels  
83 - # TODO: Future +  
84 - # Allow insertion of new threshold modes  
85 84
86 - # Surfaces are related to vtkPolyDataa  
87 - self.surface_dict = {}  
88 #self.surface_quality_list = ["Low", "Medium", "High", "Optimal *", 85 #self.surface_quality_list = ["Low", "Medium", "High", "Optimal *",
89 - # "Custom"] 86 + # "Custom"i]
  87 +
90 # TOOD: define how we will relate this quality possibilities to 88 # TOOD: define how we will relate this quality possibilities to
91 # values set as decimate / smooth 89 # values set as decimate / smooth
92 # TODO: Future + 90 # TODO: Future +
93 # Allow insertion of new surface quality modes 91 # Allow insertion of new surface quality modes
94 92
95 - self.measure_dict = {} 93 + def Close(self):
  94 + for name in self.__dict__:
  95 + attr = getattr(self, name)
  96 + del attr
96 97
97 - # TODO: Future ++  
98 - #self.annotation_dict = {} 98 + self.__init__()
99 99
100 - # TODO: Future +  
101 - # Volume rendering modes related to vtkImageData  
102 - # this will need to be inserted both in the project and in the user  
103 - # InVesalius configuration file  
104 - # self.render_mode = {}  
105 -  
106 - # The raycasting preset setted in this project  
107 - self.raycasting_preset = ''  
108 -  
109 - self.invesalius_version = version.get_svn_revision()  
110 - print self.invesalius_version  
111 -  
112 - #self.save_as = True  
113 -  
114 - #self.path = ""  
115 - self.debug = 0  
116 -  
117 - ####### MASK OPERATIONS  
118 -  
119 - def AddMask(self, index, mask): 100 + def AddMask(self, mask):
120 """ 101 """
121 Insert new mask (Mask) into project data. 102 Insert new mask (Mask) into project data.
122 103
@@ -126,11 +107,37 @@ class Project(object): @@ -126,11 +107,37 @@ class Project(object):
126 output 107 output
127 @ index: index of item that was inserted 108 @ index: index of item that was inserted
128 """ 109 """
  110 + self.last_mask_index = mask.index
  111 + index = len(self.mask_dict)
129 self.mask_dict[index] = mask 112 self.mask_dict[index] = mask
  113 + return index
  114 +
  115 + def RemoveMask(self, index):
  116 + new_dict = {}
  117 + for i in self.mask_dict:
  118 + if i < index:
  119 + new_dict[i] = self.mask_dict[i]
  120 + if i > index:
  121 + new_dict[i-1] = self.mask_dict[i]
  122 + self.mask_dict = new_dict
130 123
131 def GetMask(self, index): 124 def GetMask(self, index):
132 return self.mask_dict[index] 125 return self.mask_dict[index]
133 126
  127 + def AddSurface(self, surface):
  128 + self.last_surface_index = surface.index
  129 + index = len(self.surface_dict)
  130 + self.surface_dict[index] = surface
  131 + return index
  132 +
  133 + def RemoveSurface(self, index):
  134 + new_dict = {}
  135 + for i in self.surface_dict:
  136 + if i < index:
  137 + new_dict[i] = self.surface_dict[i]
  138 + if i > index:
  139 + new_dict[i-1] = self.surface_dict[i]
  140 + self.surface_dict = new_dict
134 141
135 def SetAcquisitionModality(self, type_=None): 142 def SetAcquisitionModality(self, type_=None):
136 if type_ is None: 143 if type_ is None:
invesalius/session.py
@@ -11,10 +11,11 @@ class Session(object): @@ -11,10 +11,11 @@ class Session(object):
11 def __init__(self): 11 def __init__(self):
12 self.project_path = () 12 self.project_path = ()
13 13
14 - self.project_status = const.PROJ_NEW  
15 - # const.PROJ_NEW*, const.PROJ_OPEN, const.PROJ_CHANGE* 14 + self.project_status = const.PROJ_CLOSE
  15 + # const.PROJ_NEW*, const.PROJ_OPEN, const.PROJ_CHANGE*,
  16 + # const.PROJ_CLOSE
16 17
17 - self.mode = "" 18 + self.mode = const.MODE_RP
18 # const.MODE_RP, const.MODE_NAVIGATOR, const.MODE_RADIOLOGY, 19 # const.MODE_RP, const.MODE_NAVIGATOR, const.MODE_RADIOLOGY,
19 # const.MODE_ODONTOLOGY 20 # const.MODE_ODONTOLOGY
20 21
@@ -30,6 +31,11 @@ class Session(object): @@ -30,6 +31,11 @@ class Session(object):
30 # Recent projects list 31 # Recent projects list
31 self.recent_projects = [] 32 self.recent_projects = []
32 33
  34 + def CloseProject(self):
  35 + self.project_path = ()
  36 + self.project_status = const.PROJ_CLOSE
  37 + self.mode = const.MODE_RP
  38 + self.temp_item = False
33 39
34 def SaveProject(self, path=()): 40 def SaveProject(self, path=()):
35 self.project_status = const.PROJ_OPEN 41 self.project_status = const.PROJ_OPEN