Commit 1a15b12cdce9ad70e461fd3177fe10d77d35f52d
1 parent
4d583c07
Exists in
master
and in
68 other branches
ADD: Project close feature (under devel)
Showing
12 changed files
with
183 additions
and
74 deletions
Show diff stats
invesalius/constants.py
| ... | ... | @@ -85,10 +85,18 @@ SLICE_POSITION = {AXIAL:[AXIAL_SLICE_CAM_VIEW_UP, AXIAL_SLICE_CAM_POSITION], |
| 85 | 85 | PROJ_NEW = 0 |
| 86 | 86 | PROJ_OPEN = 1 |
| 87 | 87 | PROJ_CHANGE = 2 |
| 88 | +PROJ_CLOSE = 3 | |
| 88 | 89 | |
| 89 | 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 | 101 | #Color Table from Slice |
| 94 | 102 | #NumberOfColors, SaturationRange, HueRange, ValueRange | ... | ... |
invesalius/control.py
| ... | ... | @@ -27,7 +27,8 @@ import constants as const |
| 27 | 27 | import project as prj |
| 28 | 28 | |
| 29 | 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 | 32 | import data.volume as volume |
| 32 | 33 | import reader.dicom_grouper as dg |
| 33 | 34 | import gui.dialogs as dialog |
| ... | ... | @@ -40,7 +41,7 @@ DEFAULT_THRESH_MODE = 0 |
| 40 | 41 | class Controller(): |
| 41 | 42 | |
| 42 | 43 | def __init__(self, frame): |
| 43 | - self.surface_manager = surface.SurfaceManager() | |
| 44 | + self.surface_manager = srf.SurfaceManager() | |
| 44 | 45 | self.volume = volume.Volume() |
| 45 | 46 | self.__bind_events() |
| 46 | 47 | self.frame = frame |
| ... | ... | @@ -51,7 +52,6 @@ class Controller(): |
| 51 | 52 | |
| 52 | 53 | def __bind_events(self): |
| 53 | 54 | ps.Publisher().subscribe(self.OnImportMedicalImages, 'Import directory') |
| 54 | - #ps.Publisher().subscribe(self.StartImportPanel, "Load data to import panel") | |
| 55 | 55 | ps.Publisher().subscribe(self.OnShowDialogImportDirectory, |
| 56 | 56 | 'Show import directory dialog') |
| 57 | 57 | ps.Publisher().subscribe(self.OnShowDialogOpenProject, |
| ... | ... | @@ -68,8 +68,6 @@ class Controller(): |
| 68 | 68 | ps.Publisher().subscribe(self.Progress, "Update dicom load") |
| 69 | 69 | ps.Publisher().subscribe(self.OnLoadImportPanel, "End dicom load") |
| 70 | 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 | 71 | ps.Publisher().subscribe(self.OnCloseProject, 'Close Project') |
| 74 | 72 | |
| 75 | 73 | |
| ... | ... | @@ -110,6 +108,12 @@ class Controller(): |
| 110 | 108 | session = ses.Session() |
| 111 | 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 | 117 | self.LoadProject() |
| 114 | 118 | |
| 115 | 119 | def ShowDialogSaveProject(self, saveas=False): |
| ... | ... | @@ -139,6 +143,26 @@ class Controller(): |
| 139 | 143 | proj = prj.Project() |
| 140 | 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 | 372 | answer = dialog.SaveChangesDialog(filename) |
| 349 | 373 | if not answer: |
| 350 | 374 | print "Close without changes" |
| 375 | + self.CloseProject() | |
| 351 | 376 | elif answer == 1: |
| 377 | + self.ShowDialogSaveProject() | |
| 352 | 378 | print "Save changes and close" |
| 379 | + self.CloseProject() | |
| 353 | 380 | #else: |
| 354 | 381 | # print "Cancel" |
| 355 | 382 | else: |
| 356 | 383 | print ":) Close without changes" |
| 384 | + self.CloseProject() | |
| 357 | 385 | |
| 358 | 386 | ... | ... |
invesalius/data/mask.py
invesalius/data/slice_.py
| ... | ... | @@ -85,6 +85,19 @@ class Slice(object): |
| 85 | 85 | ps.Publisher().subscribe(self.InputImageWidget, 'Input Image in the widget') |
| 86 | 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 | 101 | def __set_current_mask_threshold_limits(self, pubsub_evt): |
| 89 | 102 | thresh_min = pubsub_evt.data[0] |
| 90 | 103 | thresh_max = pubsub_evt.data[1] |
| ... | ... | @@ -523,8 +536,8 @@ class Slice(object): |
| 523 | 536 | |
| 524 | 537 | # insert new mask into project and retrieve its index |
| 525 | 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 | 542 | # update gui related to mask |
| 530 | 543 | ps.Publisher().sendMessage('Add mask', | ... | ... |
invesalius/data/surface.py
| ... | ... | @@ -71,7 +71,8 @@ class Surface(): |
| 71 | 71 | else: |
| 72 | 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 | 78 | # TODO: will be initialized inside control as it is being done? |
| ... | ... | @@ -102,6 +103,15 @@ class SurfaceManager(): |
| 102 | 103 | ps.Publisher().subscribe(self.OnShowSurface, 'Show surface') |
| 103 | 104 | ps.Publisher().subscribe(self.OnExportSurface,'Export surface to file') |
| 104 | 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 | 116 | def OnLoadSurfaceDict(self, pubsub_evt): |
| 107 | 117 | surface_dict = pubsub_evt.data |
| ... | ... | @@ -291,7 +301,8 @@ class SurfaceManager(): |
| 291 | 301 | |
| 292 | 302 | # Append surface into Project.surface_dict |
| 293 | 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 | 308 | session = ses.Session() | ... | ... |
invesalius/gui/data_notebook.py
| ... | ... | @@ -84,7 +84,13 @@ class MasksListCtrlPanel(wx.ListCtrl, listmix.TextEditMixin): |
| 84 | 84 | 'Change mask colour in notebook') |
| 85 | 85 | |
| 86 | 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 | 94 | def OnChangeCurrentMask(self, pubsub_evt): |
| 89 | 95 | |
| 90 | 96 | mask_index = pubsub_evt.data |
| ... | ... | @@ -211,6 +217,12 @@ class SurfacesListCtrlPanel(wx.ListCtrl, listmix.TextEditMixin): |
| 211 | 217 | 'Set surface transparency') |
| 212 | 218 | ps.Publisher().subscribe(self.EditSurfaceColour, |
| 213 | 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 | 227 | def __bind_events_wx(self): |
| 216 | 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 | 132 | |
| 133 | 133 | def ShowOpenProjectDialog(): |
| 134 | 134 | # Default system path |
| 135 | - if sys.platform == 'win32': | |
| 136 | - default_path = "" | |
| 137 | - else: | |
| 138 | - default_path = os.getcwd() | |
| 139 | 135 | |
| 140 | 136 | dlg = wx.FileDialog(None, message="Open InVesalius 3 project...", |
| 141 | - defaultDir=default_path, | |
| 137 | + defaultDir="", | |
| 142 | 138 | defaultFile="", wildcard=WILDCARD_OPEN, |
| 143 | 139 | style=wx.OPEN|wx.CHANGE_DIR) |
| 144 | 140 | ... | ... |
invesalius/gui/frame.py
| ... | ... | @@ -89,7 +89,7 @@ class Frame(wx.Frame): |
| 89 | 89 | ps.Publisher().subscribe(self.HideImportPanel, 'Hide import panel') |
| 90 | 90 | ps.Publisher().subscribe(self.BeginBusyCursor, 'Begin busy cursor') |
| 91 | 91 | ps.Publisher().subscribe(self.EndBusyCursor, 'End busy cursor') |
| 92 | - | |
| 92 | + ps.Publisher().subscribe(self.HideContentPanel, 'Hide content panel') | |
| 93 | 93 | |
| 94 | 94 | def EndBusyCursor(self, pubsub_evt=None): |
| 95 | 95 | wx.EndBusyCursor() |
| ... | ... | @@ -209,6 +209,12 @@ class Frame(wx.Frame): |
| 209 | 209 | aui_manager.GetPane("Tasks").Show(1) |
| 210 | 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 | 218 | def OnSize(self, evt): |
| 213 | 219 | ps.Publisher().sendMessage(('ProgressBar Reposition')) |
| 214 | 220 | evt.Skip() | ... | ... |
invesalius/gui/task_slice.py
| ... | ... | @@ -291,6 +291,19 @@ class MaskProperties(wx.Panel): |
| 291 | 291 | 'Set threshold values in gradient') |
| 292 | 292 | ps.Publisher().subscribe(self.SelectMaskName, 'Select mask name in combo') |
| 293 | 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 | 308 | def __bind_events_wx(self): |
| 296 | 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 | 339 | def __bind_events(self): |
| 340 | 340 | ps.Publisher().subscribe(self.InsertNewSurface, |
| 341 | 341 | 'Update surface info in GUI') |
| 342 | - ps.Publisher().subscribe(self.ChangeMaskName, | |
| 342 | + ps.Publisher().subscribe(self.ChangeSurfaceName, | |
| 343 | 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 | 355 | index, name = pubsub_evt.data |
| 348 | 356 | self.combo_surface_name.SetString(index, name) |
| 349 | 357 | self.combo_surface_name.Refresh() | ... | ... |
invesalius/project.py
| ... | ... | @@ -43,80 +43,61 @@ class Project(object): |
| 43 | 43 | __metaclass__= Singleton |
| 44 | 44 | |
| 45 | 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 | 47 | self.name = '' |
| 60 | 48 | #self.dicom = '' |
| 61 | 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 | 51 | self.min_threshold = '' |
| 68 | 52 | self.max_threshold = '' |
| 69 | - | |
| 70 | 53 | self.window = '' |
| 71 | 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 | 77 | self.presets = Presets() |
| 78 | + | |
| 74 | 79 | self.threshold_modes = self.presets.thresh_ct |
| 75 | 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 | 85 | #self.surface_quality_list = ["Low", "Medium", "High", "Optimal *", |
| 89 | - # "Custom"] | |
| 86 | + # "Custom"i] | |
| 87 | + | |
| 90 | 88 | # TOOD: define how we will relate this quality possibilities to |
| 91 | 89 | # values set as decimate / smooth |
| 92 | 90 | # TODO: Future + |
| 93 | 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 | 102 | Insert new mask (Mask) into project data. |
| 122 | 103 | |
| ... | ... | @@ -126,11 +107,37 @@ class Project(object): |
| 126 | 107 | output |
| 127 | 108 | @ index: index of item that was inserted |
| 128 | 109 | """ |
| 110 | + self.last_mask_index = mask.index | |
| 111 | + index = len(self.mask_dict) | |
| 129 | 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 | 124 | def GetMask(self, index): |
| 132 | 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 | 142 | def SetAcquisitionModality(self, type_=None): |
| 136 | 143 | if type_ is None: | ... | ... |
invesalius/session.py
| ... | ... | @@ -11,10 +11,11 @@ class Session(object): |
| 11 | 11 | def __init__(self): |
| 12 | 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 | 19 | # const.MODE_RP, const.MODE_NAVIGATOR, const.MODE_RADIOLOGY, |
| 19 | 20 | # const.MODE_ODONTOLOGY |
| 20 | 21 | |
| ... | ... | @@ -30,6 +31,11 @@ class Session(object): |
| 30 | 31 | # Recent projects list |
| 31 | 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 | 40 | def SaveProject(self, path=()): |
| 35 | 41 | self.project_status = const.PROJ_OPEN | ... | ... |