Commit 088d7b8b7090e0e55678f33f32c1d6085ee1b2e6
1 parent
a3665303
Exists in
master
and in
68 other branches
FIX: Save existing project under OSX
Showing
9 changed files
with
246 additions
and
64 deletions
Show diff stats
invesalius/constants.py
| @@ -78,10 +78,17 @@ SLICE_POSITION = {AXIAL:[AXIAL_SLICE_CAM_VIEW_UP, AXIAL_SLICE_CAM_POSITION], | @@ -78,10 +78,17 @@ SLICE_POSITION = {AXIAL:[AXIAL_SLICE_CAM_VIEW_UP, AXIAL_SLICE_CAM_POSITION], | ||
| 78 | SAGITAL:[SAGITAL_SLICE_CAM_VIEW_UP, SAGITAL_SLICE_CAM_POSITION], | 78 | SAGITAL:[SAGITAL_SLICE_CAM_VIEW_UP, SAGITAL_SLICE_CAM_POSITION], |
| 79 | CORONAL:[CORONAL_SLICE_CAM_VIEW_UP, CORONAL_SLICE_CAM_POSITION]} | 79 | CORONAL:[CORONAL_SLICE_CAM_VIEW_UP, CORONAL_SLICE_CAM_POSITION]} |
| 80 | #Project Status | 80 | #Project Status |
| 81 | -NEW_PROJECT = 0 | ||
| 82 | -OPEN_PROJECT = 1 | ||
| 83 | -CHANGE_PROJECT = 2 | ||
| 84 | -SAVE_PROJECT = 3 | 81 | +#NEW_PROJECT = 0 |
| 82 | +#OPEN_PROJECT = 1 | ||
| 83 | +#CHANGE_PROJECT = 2 | ||
| 84 | +#SAVE_PROJECT = 3 | ||
| 85 | +PROJ_NEW = 0 | ||
| 86 | +PROJ_OPEN = 1 | ||
| 87 | +PROJ_CHANGE = 2 | ||
| 88 | + | ||
| 89 | +PROJ_MAX = 4 | ||
| 90 | + | ||
| 91 | + | ||
| 85 | 92 | ||
| 86 | #Color Table from Slice | 93 | #Color Table from Slice |
| 87 | #NumberOfColors, SaturationRange, HueRange, ValueRange | 94 | #NumberOfColors, SaturationRange, HueRange, ValueRange |
invesalius/control.py
| @@ -33,7 +33,7 @@ import reader.dicom_grouper as dg | @@ -33,7 +33,7 @@ import reader.dicom_grouper as dg | ||
| 33 | import gui.dialogs as dialog | 33 | import gui.dialogs as dialog |
| 34 | import reader.dicom_reader as dcm | 34 | import reader.dicom_reader as dcm |
| 35 | import reader.analyze_reader as analyze | 35 | import reader.analyze_reader as analyze |
| 36 | -import session | 36 | +import session as ses |
| 37 | 37 | ||
| 38 | DEFAULT_THRESH_MODE = 0 | 38 | DEFAULT_THRESH_MODE = 0 |
| 39 | 39 | ||
| @@ -47,7 +47,7 @@ class Controller(): | @@ -47,7 +47,7 @@ class Controller(): | ||
| 47 | self.progress_dialog = None | 47 | self.progress_dialog = None |
| 48 | self.cancel_import = False | 48 | self.cancel_import = False |
| 49 | #Init session | 49 | #Init session |
| 50 | - session.Session() | 50 | + session = ses.Session() |
| 51 | 51 | ||
| 52 | def __bind_events(self): | 52 | def __bind_events(self): |
| 53 | ps.Publisher().subscribe(self.OnImportMedicalImages, 'Import directory') | 53 | ps.Publisher().subscribe(self.OnImportMedicalImages, 'Import directory') |
| @@ -63,6 +63,7 @@ class Controller(): | @@ -63,6 +63,7 @@ class Controller(): | ||
| 63 | ps.Publisher().subscribe(self.OnCancelImport, 'Cancel DICOM load') | 63 | ps.Publisher().subscribe(self.OnCancelImport, 'Cancel DICOM load') |
| 64 | ps.Publisher().subscribe(self.OnSaveProject, 'Save Project') | 64 | ps.Publisher().subscribe(self.OnSaveProject, 'Save Project') |
| 65 | ps.Publisher().subscribe(self.OnOpenProject, 'Open Project') | 65 | ps.Publisher().subscribe(self.OnOpenProject, 'Open Project') |
| 66 | + ps.Publisher().subscribe(self.OnCloseProject, 'Close Project') | ||
| 66 | 67 | ||
| 67 | 68 | ||
| 68 | def OnCancelImport(self, pubsub_evt): | 69 | def OnCancelImport(self, pubsub_evt): |
| @@ -136,6 +137,13 @@ class Controller(): | @@ -136,6 +137,13 @@ class Controller(): | ||
| 136 | 137 | ||
| 137 | def LoadProject(self): | 138 | def LoadProject(self): |
| 138 | proj = prj.Project() | 139 | proj = prj.Project() |
| 140 | + | ||
| 141 | + const.THRESHOLD_OUTVALUE = proj.threshold_range[0] | ||
| 142 | + const.THRESHOLD_INVALUE = proj.threshold_range[1] | ||
| 143 | + const.WINDOW_LEVEL['Default'] = (proj.window, proj.level) | ||
| 144 | + const.WINDOW_LEVEL['Manual'] = (proj.window, proj.level) | ||
| 145 | + | ||
| 146 | + | ||
| 139 | ps.Publisher().sendMessage('Set project name', proj.name) | 147 | ps.Publisher().sendMessage('Set project name', proj.name) |
| 140 | ps.Publisher().sendMessage('Load slice to viewer', | 148 | ps.Publisher().sendMessage('Load slice to viewer', |
| 141 | (proj.imagedata, | 149 | (proj.imagedata, |
| @@ -162,11 +170,6 @@ class Controller(): | @@ -162,11 +170,6 @@ class Controller(): | ||
| 162 | proj.window = proj.threshold_range[1] - proj.threshold_range[0] | 170 | proj.window = proj.threshold_range[1] - proj.threshold_range[0] |
| 163 | proj.level = (0.5 * (proj.threshold_range[1] + proj.threshold_range[0])) | 171 | proj.level = (0.5 * (proj.threshold_range[1] + proj.threshold_range[0])) |
| 164 | 172 | ||
| 165 | - const.THRESHOLD_OUTVALUE = proj.threshold_range[0] | ||
| 166 | - const.THRESHOLD_INVALUE = proj.threshold_range[1] | ||
| 167 | - const.WINDOW_LEVEL['Default'] = (proj.window, proj.level) | ||
| 168 | - const.WINDOW_LEVEL['Manual'] = (proj.window, proj.level) | ||
| 169 | - | ||
| 170 | 173 | ||
| 171 | def CreateDicomProject(self, imagedata, dicom): | 174 | def CreateDicomProject(self, imagedata, dicom): |
| 172 | name_to_const = {"AXIAL":const.AXIAL, | 175 | name_to_const = {"AXIAL":const.AXIAL, |
| @@ -185,10 +188,14 @@ class Controller(): | @@ -185,10 +188,14 @@ class Controller(): | ||
| 185 | proj.level = float(dicom.image.level) | 188 | proj.level = float(dicom.image.level) |
| 186 | proj.threshold_range = imagedata.GetScalarRange() | 189 | proj.threshold_range = imagedata.GetScalarRange() |
| 187 | 190 | ||
| 188 | - const.THRESHOLD_OUTVALUE = proj.threshold_range[0] | ||
| 189 | - const.THRESHOLD_INVALUE = proj.threshold_range[1] | ||
| 190 | - const.WINDOW_LEVEL['Default'] = (proj.window, proj.level) | ||
| 191 | - const.WINDOW_LEVEL['Manual'] = (proj.window, proj.level) | 191 | + |
| 192 | + ###### | ||
| 193 | + session = ses.Session() | ||
| 194 | + filename = proj.name+".inv3" | ||
| 195 | + dirpath = session.CreateProject(filename) | ||
| 196 | + proj.SavePlistProject(dirpath, filename) | ||
| 197 | + | ||
| 198 | + | ||
| 192 | 199 | ||
| 193 | def OnOpenDicomGroup(self, pubsub_evt): | 200 | def OnOpenDicomGroup(self, pubsub_evt): |
| 194 | group = pubsub_evt.data | 201 | group = pubsub_evt.data |
| @@ -259,33 +266,68 @@ class Controller(): | @@ -259,33 +266,68 @@ class Controller(): | ||
| 259 | plistlib.writePlist(preset, preset_dir) | 266 | plistlib.writePlist(preset, preset_dir) |
| 260 | 267 | ||
| 261 | def OnSaveProject(self, pubsub_evt): | 268 | def OnSaveProject(self, pubsub_evt): |
| 269 | + session = ses.Session() | ||
| 262 | 270 | ||
| 263 | - if not(pubsub_evt.data): | ||
| 264 | - filename = prj.Project().path | ||
| 265 | - else: | ||
| 266 | - filename = pubsub_evt.data | ||
| 267 | - dir_,filename = os.path.split(filename) | ||
| 268 | - | ||
| 269 | - if not (filename): | ||
| 270 | - filename = prj.Project().name | 271 | + path = pubsub_evt.data |
| 272 | + if path: | ||
| 273 | + print "----- FILENAME" | ||
| 274 | + dirpath, filename = os.path.split(path) | ||
| 275 | + session.SaveProject((dirpath, filename)) | ||
| 271 | else: | 276 | else: |
| 272 | - filename = filename.replace(' ','_') | ||
| 273 | - prj.Project().name = filename | ||
| 274 | - prj.Project().path = filename | ||
| 275 | - print prj.Project().path | ||
| 276 | - prj.Project().SavePlistProject(dir_, filename) | ||
| 277 | - session.Session().project_status = const.SAVE_PROJECT | 277 | + dirpath, filename = session.project_path |
| 278 | + | ||
| 279 | + print "$$$$$$$$$$$$$$$$$$$$$$$$$$" | ||
| 280 | + print "filename: ", filename | ||
| 281 | + print "dirpath: ", dirpath | ||
| 282 | + | ||
| 283 | + proj = prj.Project() | ||
| 284 | + prj.Project().SavePlistProject(dirpath, filename) | ||
| 285 | + | ||
| 286 | + | ||
| 287 | + | ||
| 288 | + | ||
| 289 | + #if not(pubsub_evt.data): | ||
| 290 | + # filename = prj.Project().path | ||
| 291 | + #else: | ||
| 292 | + # filename = pubsub_evt.data | ||
| 293 | + #dir_,filename = os.path.split(filename) | ||
| 294 | + | ||
| 295 | + #if not (filename): | ||
| 296 | + # filename = prj.Project().name | ||
| 297 | + #else: | ||
| 298 | + # filename = filename.replace(' ','_') | ||
| 299 | + # prj.Project().name = filename | ||
| 300 | + #prj.Project().path = filename | ||
| 301 | + #print prj.Project().path | ||
| 302 | + | ||
| 303 | + #prj.Project().SavePlistProject(dirpath, filename) | ||
| 304 | + | ||
| 305 | + #session.project_status = const.PROJ_OPEN | ||
| 306 | + #session.project_path = (dirpath, filename) | ||
| 278 | 307 | ||
| 279 | def OnOpenProject(self, pubsub_evt): | 308 | def OnOpenProject(self, pubsub_evt): |
| 280 | - filename = os.path.abspath(pubsub_evt.data) | ||
| 281 | - session.Session().project_status = const.OPEN_PROJECT | 309 | + path = os.path.abspath(pubsub_evt.data) |
| 310 | + | ||
| 282 | proj = prj.Project() | 311 | proj = prj.Project() |
| 283 | - proj.OpenPlistProject(filename) | 312 | + proj.OpenPlistProject(path) |
| 284 | proj.SetAcquisitionModality(proj.modality) | 313 | proj.SetAcquisitionModality(proj.modality) |
| 285 | - proj.save_as = False | ||
| 286 | - proj.path = filename | ||
| 287 | - const.THRESHOLD_OUTVALUE = proj.threshold_range[0] | ||
| 288 | - const.THRESHOLD_INVALUE = proj.threshold_range[1] | ||
| 289 | - const.WINDOW_LEVEL['Default'] = (proj.window, proj.level) | ||
| 290 | - const.WINDOW_LEVEL['Manual'] = (proj.window, proj.level) | 314 | + ###proj.path = filename |
| 315 | + ###proj.save_as = False | ||
| 316 | + | ||
| 317 | + session = ses.Session() | ||
| 318 | + session.OpenProject(path) | ||
| 319 | + | ||
| 291 | self.LoadProject() | 320 | self.LoadProject() |
| 321 | + | ||
| 322 | + def OnCloseProject(self, pubsub_evt): | ||
| 323 | + print "OnCloseProject" | ||
| 324 | + session = ses.Session() | ||
| 325 | + st = session.project_status | ||
| 326 | + filename = session.project_path[1] | ||
| 327 | + if (st == const.PROJ_NEW) or (st == const.PROJ_CHANGE): | ||
| 328 | + answer = dialog.SaveChangesDialog(filename) | ||
| 329 | + if not answer: | ||
| 330 | + print "Delete all" | ||
| 331 | + elif answer > 1: | ||
| 332 | + print "Save" | ||
| 333 | + |
invesalius/data/slice_.py
| @@ -25,7 +25,7 @@ import constants as const | @@ -25,7 +25,7 @@ import constants as const | ||
| 25 | import imagedata_utils as iu | 25 | import imagedata_utils as iu |
| 26 | from mask import Mask | 26 | from mask import Mask |
| 27 | from project import Project | 27 | from project import Project |
| 28 | -import session | 28 | +import session as ses |
| 29 | from utils import Singleton | 29 | from utils import Singleton |
| 30 | 30 | ||
| 31 | 31 | ||
| @@ -115,9 +115,10 @@ class Slice(object): | @@ -115,9 +115,10 @@ class Slice(object): | ||
| 115 | self.SetMaskEditionThreshold(index, threshold_range) | 115 | self.SetMaskEditionThreshold(index, threshold_range) |
| 116 | 116 | ||
| 117 | def __set_current_mask_threshold(self, evt_pubsub): | 117 | def __set_current_mask_threshold(self, evt_pubsub): |
| 118 | + session = ses.Session() | ||
| 118 | #FIXME: find a better way to implement this | 119 | #FIXME: find a better way to implement this |
| 119 | if (self.num_gradient >= 2) or \ | 120 | if (self.num_gradient >= 2) or \ |
| 120 | - (session.Session().project_status != const.OPEN_PROJECT): | 121 | + (session.project_status != const.PROJ_OPEN): |
| 121 | threshold_range = evt_pubsub.data | 122 | threshold_range = evt_pubsub.data |
| 122 | index = self.current_mask.index | 123 | index = self.current_mask.index |
| 123 | self.SetMaskThreshold(index, threshold_range) | 124 | self.SetMaskThreshold(index, threshold_range) |
| @@ -180,11 +181,19 @@ class Slice(object): | @@ -180,11 +181,19 @@ class Slice(object): | ||
| 180 | if update: | 181 | if update: |
| 181 | ps.Publisher().sendMessage('Update slice viewer') | 182 | ps.Publisher().sendMessage('Update slice viewer') |
| 182 | 183 | ||
| 184 | + session = ses.Session() | ||
| 185 | + session.ChangeProject() | ||
| 186 | + | ||
| 187 | + | ||
| 183 | def SetMaskName(self, index, name): | 188 | def SetMaskName(self, index, name): |
| 184 | "Rename a mask given its index and the new name" | 189 | "Rename a mask given its index and the new name" |
| 185 | proj = Project() | 190 | proj = Project() |
| 186 | proj.mask_dict[index].name = name | 191 | proj.mask_dict[index].name = name |
| 187 | 192 | ||
| 193 | + session = ses.Session() | ||
| 194 | + session.ChangeProject() | ||
| 195 | + | ||
| 196 | + | ||
| 188 | def SetMaskEditionThreshold(self, index, threshold_range): | 197 | def SetMaskEditionThreshold(self, index, threshold_range): |
| 189 | "Set threshold bounds to be used while editing slice" | 198 | "Set threshold bounds to be used while editing slice" |
| 190 | proj = Project() | 199 | proj = Project() |
| @@ -224,8 +233,13 @@ class Slice(object): | @@ -224,8 +233,13 @@ class Slice(object): | ||
| 224 | proj.mask_dict[index].threshold_range = threshold_range | 233 | proj.mask_dict[index].threshold_range = threshold_range |
| 225 | 234 | ||
| 226 | proj = Project() | 235 | proj = Project() |
| 227 | - proj.mask_dict[self.current_mask.index ].threshold_range = threshold_range | ||
| 228 | - | 236 | + proj.mask_dict[self.current_mask.index].threshold_range = threshold_range |
| 237 | + | ||
| 238 | + session = ses.Session() | ||
| 239 | + session.ChangeProject() | ||
| 240 | + | ||
| 241 | + | ||
| 242 | + | ||
| 229 | 243 | ||
| 230 | def ShowMask(self, index, value): | 244 | def ShowMask(self, index, value): |
| 231 | "Show a mask given its index and 'show' value (0: hide, other: show)" | 245 | "Show a mask given its index and 'show' value (0: hide, other: show)" |
| @@ -246,6 +260,10 @@ class Slice(object): | @@ -246,6 +260,10 @@ class Slice(object): | ||
| 246 | imagedata = self.current_mask.imagedata | 260 | imagedata = self.current_mask.imagedata |
| 247 | imagedata.SetScalarComponentFromDouble(x, y, z, 0, colour) | 261 | imagedata.SetScalarComponentFromDouble(x, y, z, 0, colour) |
| 248 | self.current_mask.edited_points[(x, y, z)] = colour | 262 | self.current_mask.edited_points[(x, y, z)] = colour |
| 263 | + | ||
| 264 | + session = ses.Session() | ||
| 265 | + session.ChangeProject() | ||
| 266 | + | ||
| 249 | 267 | ||
| 250 | def DrawPixel(self, position, colour=None): | 268 | def DrawPixel(self, position, colour=None): |
| 251 | "Draw pixel, based on x, y and z position coordinates." | 269 | "Draw pixel, based on x, y and z position coordinates." |
| @@ -255,6 +273,10 @@ class Slice(object): | @@ -255,6 +273,10 @@ class Slice(object): | ||
| 255 | imagedata.SetScalarComponentFromDouble(x, y, z, 0, colour) | 273 | imagedata.SetScalarComponentFromDouble(x, y, z, 0, colour) |
| 256 | self.current_mask.edited_points[(x, y, z)] = colour | 274 | self.current_mask.edited_points[(x, y, z)] = colour |
| 257 | 275 | ||
| 276 | + session = ses.Session() | ||
| 277 | + session.ChangeProject() | ||
| 278 | + | ||
| 279 | + | ||
| 258 | def EditPixelBasedOnThreshold(self, position): | 280 | def EditPixelBasedOnThreshold(self, position): |
| 259 | "Erase or draw pixel based on edition threshold range." | 281 | "Erase or draw pixel based on edition threshold range." |
| 260 | x, y, z = position | 282 | x, y, z = position |
| @@ -264,6 +286,11 @@ class Slice(object): | @@ -264,6 +286,11 @@ class Slice(object): | ||
| 264 | self.DrawPixel(position, colour) | 286 | self.DrawPixel(position, colour) |
| 265 | else: | 287 | else: |
| 266 | self.ErasePixel(position) | 288 | self.ErasePixel(position) |
| 289 | + | ||
| 290 | + session = ses.Session() | ||
| 291 | + session.ChangeProject() | ||
| 292 | + | ||
| 293 | + | ||
| 267 | #--------------------------------------------------------------------------- | 294 | #--------------------------------------------------------------------------- |
| 268 | def SelectCurrentMask(self, index): | 295 | def SelectCurrentMask(self, index): |
| 269 | "Insert mask data, based on given index, into pipeline." | 296 | "Insert mask data, based on given index, into pipeline." |
invesalius/data/surface.py
| @@ -25,9 +25,10 @@ import wx.lib.pubsub as ps | @@ -25,9 +25,10 @@ import wx.lib.pubsub as ps | ||
| 25 | 25 | ||
| 26 | import constants as const | 26 | import constants as const |
| 27 | import imagedata_utils as iu | 27 | import imagedata_utils as iu |
| 28 | +import polydata_utils as pu | ||
| 28 | import project as prj | 29 | import project as prj |
| 30 | +import session as ses | ||
| 29 | import vtk_utils as vu | 31 | import vtk_utils as vu |
| 30 | -import polydata_utils as pu | ||
| 31 | from imagedata_utils import BuildEditedImage | 32 | from imagedata_utils import BuildEditedImage |
| 32 | 33 | ||
| 33 | class Surface(): | 34 | class Surface(): |
| @@ -292,6 +293,11 @@ class SurfaceManager(): | @@ -292,6 +293,11 @@ class SurfaceManager(): | ||
| 292 | proj = prj.Project() | 293 | proj = prj.Project() |
| 293 | proj.surface_dict[surface.index] = surface | 294 | proj.surface_dict[surface.index] = surface |
| 294 | 295 | ||
| 296 | + | ||
| 297 | + session = ses.Session() | ||
| 298 | + session.ChangeProject() | ||
| 299 | + | ||
| 300 | + | ||
| 295 | # Save actor for future management tasks | 301 | # Save actor for future management tasks |
| 296 | self.actors_dict[surface.index] = actor | 302 | self.actors_dict[surface.index] = actor |
| 297 | 303 |
invesalius/gui/dialogs.py
| @@ -190,4 +190,18 @@ def ShowSaveAsProjectDialog(default_filename=None): | @@ -190,4 +190,18 @@ def ShowSaveAsProjectDialog(default_filename=None): | ||
| 190 | if sys.platform != 'win32': | 190 | if sys.platform != 'win32': |
| 191 | if filename.split(".")[-1] != extension: | 191 | if filename.split(".")[-1] != extension: |
| 192 | filename = filename + "." + extension | 192 | filename = filename + "." + extension |
| 193 | - return filename | 193 | + return filename |
| 194 | + | ||
| 195 | +def SaveChangesDialog(filename): | ||
| 196 | + dlg = wx.MessageDialog(None, | ||
| 197 | + "InVesalius 3", | ||
| 198 | + "Save changes to "+filename+"?", | ||
| 199 | + wx.YES | wx.NO | wx.CANCEL | wx.ICON_INFORMATION) | ||
| 200 | + | ||
| 201 | + if dlg.ShowModal() == wx.ID_YES: | ||
| 202 | + return 1 | ||
| 203 | + elif dlg.ShowModal() == wx.ID_NO: | ||
| 204 | + return 0 | ||
| 205 | + else: | ||
| 206 | + return -1 | ||
| 207 | + |
invesalius/gui/frame.py
| @@ -30,7 +30,8 @@ import default_tasks as tasks | @@ -30,7 +30,8 @@ import default_tasks as tasks | ||
| 30 | import default_viewers as viewers | 30 | import default_viewers as viewers |
| 31 | import gui.dialogs as dlg | 31 | import gui.dialogs as dlg |
| 32 | import import_panel as imp | 32 | import import_panel as imp |
| 33 | -from project import Project | 33 | +import project as prj |
| 34 | +import session as ses | ||
| 34 | 35 | ||
| 35 | # Object toolbar | 36 | # Object toolbar |
| 36 | OBJ_TOOLS = [ID_ZOOM, ID_ZOOM_SELECT, ID_ROTATE, ID_MOVE, | 37 | OBJ_TOOLS = [ID_ZOOM, ID_ZOOM_SELECT, ID_ROTATE, ID_MOVE, |
| @@ -216,12 +217,15 @@ class Frame(wx.Frame): | @@ -216,12 +217,15 @@ class Frame(wx.Frame): | ||
| 216 | #ps.Publisher().sendMessage(("Event from GUI", | 217 | #ps.Publisher().sendMessage(("Event from GUI", |
| 217 | # evt.GetId())) | 218 | # evt.GetId())) |
| 218 | id = evt.GetId() | 219 | id = evt.GetId() |
| 220 | + #proj = prj.Project() | ||
| 221 | + session = ses.Session() | ||
| 219 | if id == const.ID_DICOM_IMPORT: | 222 | if id == const.ID_DICOM_IMPORT: |
| 220 | self.ImportDicom() | 223 | self.ImportDicom() |
| 221 | elif id == const.ID_PROJECT_OPEN: | 224 | elif id == const.ID_PROJECT_OPEN: |
| 222 | self.OpenProject() | 225 | self.OpenProject() |
| 223 | elif id == const.ID_PROJECT_SAVE: | 226 | elif id == const.ID_PROJECT_SAVE: |
| 224 | - if Project().save_as: | 227 | + #if proj.save_as: |
| 228 | + if session.temp_item: | ||
| 225 | self.SaveAsProject() | 229 | self.SaveAsProject() |
| 226 | else: | 230 | else: |
| 227 | self.SaveProject() | 231 | self.SaveProject() |
| @@ -246,14 +250,20 @@ class Frame(wx.Frame): | @@ -246,14 +250,20 @@ class Frame(wx.Frame): | ||
| 246 | self.SaveProject(True) | 250 | self.SaveProject(True) |
| 247 | 251 | ||
| 248 | def SaveProject(self, saveas=False): | 252 | def SaveProject(self, saveas=False): |
| 249 | - filename = (Project().name).replace(' ','_') | ||
| 250 | - if Project().save_as or saveas: | ||
| 251 | - filename = dlg.ShowSaveAsProjectDialog(filename) | ||
| 252 | - if filename: | ||
| 253 | - Project().save_as = False | 253 | + |
| 254 | + session = ses.Session() | ||
| 255 | + if saveas: | ||
| 256 | + proj = prj.Project() | ||
| 257 | + filepath = dlg.ShowSaveAsProjectDialog(proj.name) | ||
| 258 | + if filepath: | ||
| 259 | + session.RemoveTemp() | ||
| 260 | + session.OpenProject(filepath) | ||
| 254 | else: | 261 | else: |
| 255 | return | 262 | return |
| 256 | - ps.Publisher().sendMessage('Save Project',filename) | 263 | + else: |
| 264 | + dirpath, filename = session.project_path | ||
| 265 | + filepath = os.path.join(dirpath, filename) | ||
| 266 | + ps.Publisher().sendMessage('Save Project',filepath) | ||
| 257 | 267 | ||
| 258 | 268 | ||
| 259 | def SaveAsOld(self): | 269 | def SaveAsOld(self): |
| @@ -272,7 +282,7 @@ class Frame(wx.Frame): | @@ -272,7 +282,7 @@ class Frame(wx.Frame): | ||
| 272 | ps.Publisher().sendMessage('Save Project',filename) | 282 | ps.Publisher().sendMessage('Save Project',filename) |
| 273 | 283 | ||
| 274 | def CloseProject(self): | 284 | def CloseProject(self): |
| 275 | - print "TODO: CloseProject" | 285 | + ps.Publisher().sendMessage('Close Project') |
| 276 | 286 | ||
| 277 | def Exit(self): | 287 | def Exit(self): |
| 278 | print "TODO: Exit" | 288 | print "TODO: Exit" |
| @@ -544,10 +554,10 @@ class ProjectToolBar(wx.ToolBar): | @@ -544,10 +554,10 @@ class ProjectToolBar(wx.ToolBar): | ||
| 544 | self.Realize() | 554 | self.Realize() |
| 545 | 555 | ||
| 546 | def __bind_events(self): | 556 | def __bind_events(self): |
| 547 | - | ||
| 548 | - self.Bind(wx.EVT_TOOL, self.OnToolSave, id=const.ID_PROJECT_SAVE) | ||
| 549 | - self.Bind(wx.EVT_TOOL, self.OnToolOpen, id=const.ID_PROJECT_OPEN) | ||
| 550 | - self.Bind(wx.EVT_TOOL, self.OnToolImport, id=const.ID_DICOM_IMPORT) | 557 | + pass |
| 558 | + #self.Bind(wx.EVT_TOOL, self.OnToolSave, id=const.ID_PROJECT_SAVE) | ||
| 559 | + #self.Bind(wx.EVT_TOOL, self.OnToolOpen, id=const.ID_PROJECT_OPEN) | ||
| 560 | + #self.Bind(wx.EVT_TOOL, self.OnToolImport, id=const.ID_DICOM_IMPORT) | ||
| 551 | 561 | ||
| 552 | def OnToolImport(self, event): | 562 | def OnToolImport(self, event): |
| 553 | dirpath = dlg.ShowImportDirDialog() | 563 | dirpath = dlg.ShowImportDirDialog() |
| @@ -562,11 +572,12 @@ class ProjectToolBar(wx.ToolBar): | @@ -562,11 +572,12 @@ class ProjectToolBar(wx.ToolBar): | ||
| 562 | event.Skip() | 572 | event.Skip() |
| 563 | 573 | ||
| 564 | def OnToolSave(self, event): | 574 | def OnToolSave(self, event): |
| 565 | - filename = (Project().name).replace(' ','_') | ||
| 566 | - if Project().save_as: | 575 | + proj = prj.Project() |
| 576 | + filename = (prj.name).replace(' ','_') | ||
| 577 | + if prj.save_as: | ||
| 567 | filename = dlg.ShowSaveAsProjectDialog(filename) | 578 | filename = dlg.ShowSaveAsProjectDialog(filename) |
| 568 | if filename: | 579 | if filename: |
| 569 | - Project().save_as = False | 580 | + prj.save_as = False |
| 570 | else: | 581 | else: |
| 571 | return | 582 | return |
| 572 | ps.Publisher().sendMessage('Save Project',filename) | 583 | ps.Publisher().sendMessage('Save Project',filename) |
invesalius/project.py
| @@ -109,9 +109,9 @@ class Project(object): | @@ -109,9 +109,9 @@ class Project(object): | ||
| 109 | self.invesalius_version = version.get_svn_revision() | 109 | self.invesalius_version = version.get_svn_revision() |
| 110 | print self.invesalius_version | 110 | print self.invesalius_version |
| 111 | 111 | ||
| 112 | - self.save_as = True | 112 | + #self.save_as = True |
| 113 | 113 | ||
| 114 | - self.path = "" | 114 | + #self.path = "" |
| 115 | self.debug = 0 | 115 | self.debug = 0 |
| 116 | 116 | ||
| 117 | ####### MASK OPERATIONS | 117 | ####### MASK OPERATIONS |
invesalius/reader/dicom.py
| @@ -1129,7 +1129,7 @@ class Parser(): | @@ -1129,7 +1129,7 @@ class Parser(): | ||
| 1129 | data = self.vtkgdcm_reader.GetMedicalImageProperties()\ | 1129 | data = self.vtkgdcm_reader.GetMedicalImageProperties()\ |
| 1130 | .GetPatientName() | 1130 | .GetPatientName() |
| 1131 | if (data): | 1131 | if (data): |
| 1132 | - return data | 1132 | + return data.strip() |
| 1133 | return "" | 1133 | return "" |
| 1134 | 1134 | ||
| 1135 | def GetPatientID(self): | 1135 | def GetPatientID(self): |
invesalius/session.py
| 1 | +import os | ||
| 2 | + | ||
| 1 | import constants as const | 3 | import constants as const |
| 2 | from utils import Singleton | 4 | from utils import Singleton |
| 3 | 5 | ||
| @@ -7,4 +9,77 @@ class Session(object): | @@ -7,4 +9,77 @@ class Session(object): | ||
| 7 | __metaclass__= Singleton | 9 | __metaclass__= Singleton |
| 8 | 10 | ||
| 9 | def __init__(self): | 11 | def __init__(self): |
| 10 | - self.project_status = const.NEW_PROJECT | ||
| 11 | \ No newline at end of file | 12 | \ No newline at end of file |
| 13 | + self.project_path = () | ||
| 14 | + | ||
| 15 | + self.project_status = const.PROJ_NEW | ||
| 16 | + # const.PROJ_NEW*, const.PROJ_OPEN, const.PROJ_CHANGE* | ||
| 17 | + | ||
| 18 | + self.mode = "" | ||
| 19 | + # const.MODE_RP, const.MODE_NAVIGATOR, const.MODE_RADIOLOGY, | ||
| 20 | + # const.MODE_ODONTOLOGY | ||
| 21 | + | ||
| 22 | + # InVesalius default projects' directory | ||
| 23 | + homedir = os.path.expanduser('~') | ||
| 24 | + invdir = os.path.join(homedir, ".invesalius", "temp") | ||
| 25 | + if not os.path.isdir(invdir): | ||
| 26 | + os.makedirs(invdir) | ||
| 27 | + self.invdir = invdir | ||
| 28 | + | ||
| 29 | + self.temp_item = False | ||
| 30 | + | ||
| 31 | + # Recent projects list | ||
| 32 | + self.recent_projects = [] | ||
| 33 | + | ||
| 34 | + | ||
| 35 | + def SaveProject(self, path=()): | ||
| 36 | + self.project_status = const.PROJ_OPEN | ||
| 37 | + if path: | ||
| 38 | + self.project_path = path | ||
| 39 | + self.__add_to_list(path) | ||
| 40 | + if self.temp_item: | ||
| 41 | + self.temp_item = False | ||
| 42 | + | ||
| 43 | + def ChangeProject(self): | ||
| 44 | + self.project_status = const.PROJ_CHANGE | ||
| 45 | + | ||
| 46 | + def CreateProject(self, filename): | ||
| 47 | + # Set session info | ||
| 48 | + self.project_path = (self.invdir, filename) | ||
| 49 | + self.project_status = const.PROJ_NEW | ||
| 50 | + self.temp_item = True | ||
| 51 | + return self.invdir | ||
| 52 | + | ||
| 53 | + | ||
| 54 | + def OpenProject(self, filepath): | ||
| 55 | + # Add item to recent projects list | ||
| 56 | + item = (path, file) = os.path.split(filepath) | ||
| 57 | + self.__add_to_list(item) | ||
| 58 | + | ||
| 59 | + # Set session info | ||
| 60 | + self.project_path = item | ||
| 61 | + self.project_status = const.PROJ_OPEN | ||
| 62 | + | ||
| 63 | + def RemoveTemp(self): | ||
| 64 | + if self.temp_item: | ||
| 65 | + (dirpath, file) = self.project_path | ||
| 66 | + path = os.path.join(dirpath, file) | ||
| 67 | + os.remove(path) | ||
| 68 | + self.temp_item = False | ||
| 69 | + | ||
| 70 | + | ||
| 71 | + def __add_to_list(self, item): | ||
| 72 | + # Last projects list | ||
| 73 | + l = self.recent_projects | ||
| 74 | + | ||
| 75 | + # If item exists, remove it from list | ||
| 76 | + if l.count(item): | ||
| 77 | + l.remove(item) | ||
| 78 | + | ||
| 79 | + # Add new item | ||
| 80 | + l.insert(0, item) | ||
| 81 | + | ||
| 82 | + # Remove oldest projects from list | ||
| 83 | + if len(l)>const.PROJ_MAX: | ||
| 84 | + for i in xrange(len(l)-const.PROJ_MAX): | ||
| 85 | + l.pop() | ||
| 86 | + |