From 088d7b8b7090e0e55678f33f32c1d6085ee1b2e6 Mon Sep 17 00:00:00 2001 From: tatiana Date: Mon, 23 Nov 2009 18:46:32 +0000 Subject: [PATCH] FIX: Save existing project under OSX --- invesalius/constants.py | 15 +++++++++++---- invesalius/control.py | 110 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------------------------------- invesalius/data/slice_.py | 35 +++++++++++++++++++++++++++++++---- invesalius/data/surface.py | 8 +++++++- invesalius/gui/dialogs.py | 16 +++++++++++++++- invesalius/gui/frame.py | 43 +++++++++++++++++++++++++++---------------- invesalius/project.py | 4 ++-- invesalius/reader/dicom.py | 2 +- invesalius/session.py | 77 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 9 files changed, 246 insertions(+), 64 deletions(-) diff --git a/invesalius/constants.py b/invesalius/constants.py index 47c81df..34008b6 100644 --- a/invesalius/constants.py +++ b/invesalius/constants.py @@ -78,10 +78,17 @@ SLICE_POSITION = {AXIAL:[AXIAL_SLICE_CAM_VIEW_UP, AXIAL_SLICE_CAM_POSITION], SAGITAL:[SAGITAL_SLICE_CAM_VIEW_UP, SAGITAL_SLICE_CAM_POSITION], CORONAL:[CORONAL_SLICE_CAM_VIEW_UP, CORONAL_SLICE_CAM_POSITION]} #Project Status -NEW_PROJECT = 0 -OPEN_PROJECT = 1 -CHANGE_PROJECT = 2 -SAVE_PROJECT = 3 +#NEW_PROJECT = 0 +#OPEN_PROJECT = 1 +#CHANGE_PROJECT = 2 +#SAVE_PROJECT = 3 +PROJ_NEW = 0 +PROJ_OPEN = 1 +PROJ_CHANGE = 2 + +PROJ_MAX = 4 + + #Color Table from Slice #NumberOfColors, SaturationRange, HueRange, ValueRange diff --git a/invesalius/control.py b/invesalius/control.py index d044b9a..2ce7658 100755 --- a/invesalius/control.py +++ b/invesalius/control.py @@ -33,7 +33,7 @@ import reader.dicom_grouper as dg import gui.dialogs as dialog import reader.dicom_reader as dcm import reader.analyze_reader as analyze -import session +import session as ses DEFAULT_THRESH_MODE = 0 @@ -47,7 +47,7 @@ class Controller(): self.progress_dialog = None self.cancel_import = False #Init session - session.Session() + session = ses.Session() def __bind_events(self): ps.Publisher().subscribe(self.OnImportMedicalImages, 'Import directory') @@ -63,6 +63,7 @@ class Controller(): ps.Publisher().subscribe(self.OnCancelImport, 'Cancel DICOM load') ps.Publisher().subscribe(self.OnSaveProject, 'Save Project') ps.Publisher().subscribe(self.OnOpenProject, 'Open Project') + ps.Publisher().subscribe(self.OnCloseProject, 'Close Project') def OnCancelImport(self, pubsub_evt): @@ -136,6 +137,13 @@ class Controller(): def LoadProject(self): proj = prj.Project() + + const.THRESHOLD_OUTVALUE = proj.threshold_range[0] + const.THRESHOLD_INVALUE = proj.threshold_range[1] + const.WINDOW_LEVEL['Default'] = (proj.window, proj.level) + const.WINDOW_LEVEL['Manual'] = (proj.window, proj.level) + + ps.Publisher().sendMessage('Set project name', proj.name) ps.Publisher().sendMessage('Load slice to viewer', (proj.imagedata, @@ -162,11 +170,6 @@ class Controller(): proj.window = proj.threshold_range[1] - proj.threshold_range[0] proj.level = (0.5 * (proj.threshold_range[1] + proj.threshold_range[0])) - const.THRESHOLD_OUTVALUE = proj.threshold_range[0] - const.THRESHOLD_INVALUE = proj.threshold_range[1] - const.WINDOW_LEVEL['Default'] = (proj.window, proj.level) - const.WINDOW_LEVEL['Manual'] = (proj.window, proj.level) - def CreateDicomProject(self, imagedata, dicom): name_to_const = {"AXIAL":const.AXIAL, @@ -185,10 +188,14 @@ class Controller(): proj.level = float(dicom.image.level) proj.threshold_range = imagedata.GetScalarRange() - const.THRESHOLD_OUTVALUE = proj.threshold_range[0] - const.THRESHOLD_INVALUE = proj.threshold_range[1] - const.WINDOW_LEVEL['Default'] = (proj.window, proj.level) - const.WINDOW_LEVEL['Manual'] = (proj.window, proj.level) + + ###### + session = ses.Session() + filename = proj.name+".inv3" + dirpath = session.CreateProject(filename) + proj.SavePlistProject(dirpath, filename) + + def OnOpenDicomGroup(self, pubsub_evt): group = pubsub_evt.data @@ -259,33 +266,68 @@ class Controller(): plistlib.writePlist(preset, preset_dir) def OnSaveProject(self, pubsub_evt): + session = ses.Session() - if not(pubsub_evt.data): - filename = prj.Project().path - else: - filename = pubsub_evt.data - dir_,filename = os.path.split(filename) - - if not (filename): - filename = prj.Project().name + path = pubsub_evt.data + if path: + print "----- FILENAME" + dirpath, filename = os.path.split(path) + session.SaveProject((dirpath, filename)) else: - filename = filename.replace(' ','_') - prj.Project().name = filename - prj.Project().path = filename - print prj.Project().path - prj.Project().SavePlistProject(dir_, filename) - session.Session().project_status = const.SAVE_PROJECT + dirpath, filename = session.project_path + + print "$$$$$$$$$$$$$$$$$$$$$$$$$$" + print "filename: ", filename + print "dirpath: ", dirpath + + proj = prj.Project() + prj.Project().SavePlistProject(dirpath, filename) + + + + + #if not(pubsub_evt.data): + # filename = prj.Project().path + #else: + # filename = pubsub_evt.data + #dir_,filename = os.path.split(filename) + + #if not (filename): + # filename = prj.Project().name + #else: + # filename = filename.replace(' ','_') + # prj.Project().name = filename + #prj.Project().path = filename + #print prj.Project().path + + #prj.Project().SavePlistProject(dirpath, filename) + + #session.project_status = const.PROJ_OPEN + #session.project_path = (dirpath, filename) def OnOpenProject(self, pubsub_evt): - filename = os.path.abspath(pubsub_evt.data) - session.Session().project_status = const.OPEN_PROJECT + path = os.path.abspath(pubsub_evt.data) + proj = prj.Project() - proj.OpenPlistProject(filename) + proj.OpenPlistProject(path) proj.SetAcquisitionModality(proj.modality) - proj.save_as = False - proj.path = filename - const.THRESHOLD_OUTVALUE = proj.threshold_range[0] - const.THRESHOLD_INVALUE = proj.threshold_range[1] - const.WINDOW_LEVEL['Default'] = (proj.window, proj.level) - const.WINDOW_LEVEL['Manual'] = (proj.window, proj.level) + ###proj.path = filename + ###proj.save_as = False + + session = ses.Session() + session.OpenProject(path) + self.LoadProject() + + def OnCloseProject(self, pubsub_evt): + print "OnCloseProject" + session = ses.Session() + st = session.project_status + filename = session.project_path[1] + if (st == const.PROJ_NEW) or (st == const.PROJ_CHANGE): + answer = dialog.SaveChangesDialog(filename) + if not answer: + print "Delete all" + elif answer > 1: + print "Save" + diff --git a/invesalius/data/slice_.py b/invesalius/data/slice_.py index d369010..ca43e59 100644 --- a/invesalius/data/slice_.py +++ b/invesalius/data/slice_.py @@ -25,7 +25,7 @@ import constants as const import imagedata_utils as iu from mask import Mask from project import Project -import session +import session as ses from utils import Singleton @@ -115,9 +115,10 @@ class Slice(object): self.SetMaskEditionThreshold(index, threshold_range) def __set_current_mask_threshold(self, evt_pubsub): + session = ses.Session() #FIXME: find a better way to implement this if (self.num_gradient >= 2) or \ - (session.Session().project_status != const.OPEN_PROJECT): + (session.project_status != const.PROJ_OPEN): threshold_range = evt_pubsub.data index = self.current_mask.index self.SetMaskThreshold(index, threshold_range) @@ -180,11 +181,19 @@ class Slice(object): if update: ps.Publisher().sendMessage('Update slice viewer') + session = ses.Session() + session.ChangeProject() + + def SetMaskName(self, index, name): "Rename a mask given its index and the new name" proj = Project() proj.mask_dict[index].name = name + session = ses.Session() + session.ChangeProject() + + def SetMaskEditionThreshold(self, index, threshold_range): "Set threshold bounds to be used while editing slice" proj = Project() @@ -224,8 +233,13 @@ class Slice(object): proj.mask_dict[index].threshold_range = threshold_range proj = Project() - proj.mask_dict[self.current_mask.index ].threshold_range = threshold_range - + proj.mask_dict[self.current_mask.index].threshold_range = threshold_range + + session = ses.Session() + session.ChangeProject() + + + def ShowMask(self, index, value): "Show a mask given its index and 'show' value (0: hide, other: show)" @@ -246,6 +260,10 @@ class Slice(object): imagedata = self.current_mask.imagedata imagedata.SetScalarComponentFromDouble(x, y, z, 0, colour) self.current_mask.edited_points[(x, y, z)] = colour + + session = ses.Session() + session.ChangeProject() + def DrawPixel(self, position, colour=None): "Draw pixel, based on x, y and z position coordinates." @@ -255,6 +273,10 @@ class Slice(object): imagedata.SetScalarComponentFromDouble(x, y, z, 0, colour) self.current_mask.edited_points[(x, y, z)] = colour + session = ses.Session() + session.ChangeProject() + + def EditPixelBasedOnThreshold(self, position): "Erase or draw pixel based on edition threshold range." x, y, z = position @@ -264,6 +286,11 @@ class Slice(object): self.DrawPixel(position, colour) else: self.ErasePixel(position) + + session = ses.Session() + session.ChangeProject() + + #--------------------------------------------------------------------------- def SelectCurrentMask(self, index): "Insert mask data, based on given index, into pipeline." diff --git a/invesalius/data/surface.py b/invesalius/data/surface.py index 4970718..de5b68c 100644 --- a/invesalius/data/surface.py +++ b/invesalius/data/surface.py @@ -25,9 +25,10 @@ import wx.lib.pubsub as ps import constants as const import imagedata_utils as iu +import polydata_utils as pu import project as prj +import session as ses import vtk_utils as vu -import polydata_utils as pu from imagedata_utils import BuildEditedImage class Surface(): @@ -292,6 +293,11 @@ class SurfaceManager(): proj = prj.Project() proj.surface_dict[surface.index] = surface + + session = ses.Session() + session.ChangeProject() + + # Save actor for future management tasks self.actors_dict[surface.index] = actor diff --git a/invesalius/gui/dialogs.py b/invesalius/gui/dialogs.py index 0c4bcf2..76839ee 100644 --- a/invesalius/gui/dialogs.py +++ b/invesalius/gui/dialogs.py @@ -190,4 +190,18 @@ def ShowSaveAsProjectDialog(default_filename=None): if sys.platform != 'win32': if filename.split(".")[-1] != extension: filename = filename + "." + extension - return filename + return filename + +def SaveChangesDialog(filename): + dlg = wx.MessageDialog(None, + "InVesalius 3", + "Save changes to "+filename+"?", + wx.YES | wx.NO | wx.CANCEL | wx.ICON_INFORMATION) + + if dlg.ShowModal() == wx.ID_YES: + return 1 + elif dlg.ShowModal() == wx.ID_NO: + return 0 + else: + return -1 + diff --git a/invesalius/gui/frame.py b/invesalius/gui/frame.py index bf686ab..06db2c8 100755 --- a/invesalius/gui/frame.py +++ b/invesalius/gui/frame.py @@ -30,7 +30,8 @@ import default_tasks as tasks import default_viewers as viewers import gui.dialogs as dlg import import_panel as imp -from project import Project +import project as prj +import session as ses # Object toolbar OBJ_TOOLS = [ID_ZOOM, ID_ZOOM_SELECT, ID_ROTATE, ID_MOVE, @@ -216,12 +217,15 @@ class Frame(wx.Frame): #ps.Publisher().sendMessage(("Event from GUI", # evt.GetId())) id = evt.GetId() + #proj = prj.Project() + session = ses.Session() if id == const.ID_DICOM_IMPORT: self.ImportDicom() elif id == const.ID_PROJECT_OPEN: self.OpenProject() elif id == const.ID_PROJECT_SAVE: - if Project().save_as: + #if proj.save_as: + if session.temp_item: self.SaveAsProject() else: self.SaveProject() @@ -246,14 +250,20 @@ class Frame(wx.Frame): self.SaveProject(True) def SaveProject(self, saveas=False): - filename = (Project().name).replace(' ','_') - if Project().save_as or saveas: - filename = dlg.ShowSaveAsProjectDialog(filename) - if filename: - Project().save_as = False + + session = ses.Session() + if saveas: + proj = prj.Project() + filepath = dlg.ShowSaveAsProjectDialog(proj.name) + if filepath: + session.RemoveTemp() + session.OpenProject(filepath) else: return - ps.Publisher().sendMessage('Save Project',filename) + else: + dirpath, filename = session.project_path + filepath = os.path.join(dirpath, filename) + ps.Publisher().sendMessage('Save Project',filepath) def SaveAsOld(self): @@ -272,7 +282,7 @@ class Frame(wx.Frame): ps.Publisher().sendMessage('Save Project',filename) def CloseProject(self): - print "TODO: CloseProject" + ps.Publisher().sendMessage('Close Project') def Exit(self): print "TODO: Exit" @@ -544,10 +554,10 @@ class ProjectToolBar(wx.ToolBar): self.Realize() def __bind_events(self): - - self.Bind(wx.EVT_TOOL, self.OnToolSave, id=const.ID_PROJECT_SAVE) - self.Bind(wx.EVT_TOOL, self.OnToolOpen, id=const.ID_PROJECT_OPEN) - self.Bind(wx.EVT_TOOL, self.OnToolImport, id=const.ID_DICOM_IMPORT) + pass + #self.Bind(wx.EVT_TOOL, self.OnToolSave, id=const.ID_PROJECT_SAVE) + #self.Bind(wx.EVT_TOOL, self.OnToolOpen, id=const.ID_PROJECT_OPEN) + #self.Bind(wx.EVT_TOOL, self.OnToolImport, id=const.ID_DICOM_IMPORT) def OnToolImport(self, event): dirpath = dlg.ShowImportDirDialog() @@ -562,11 +572,12 @@ class ProjectToolBar(wx.ToolBar): event.Skip() def OnToolSave(self, event): - filename = (Project().name).replace(' ','_') - if Project().save_as: + proj = prj.Project() + filename = (prj.name).replace(' ','_') + if prj.save_as: filename = dlg.ShowSaveAsProjectDialog(filename) if filename: - Project().save_as = False + prj.save_as = False else: return ps.Publisher().sendMessage('Save Project',filename) diff --git a/invesalius/project.py b/invesalius/project.py index 57b9533..1eae61f 100755 --- a/invesalius/project.py +++ b/invesalius/project.py @@ -109,9 +109,9 @@ class Project(object): self.invesalius_version = version.get_svn_revision() print self.invesalius_version - self.save_as = True + #self.save_as = True - self.path = "" + #self.path = "" self.debug = 0 ####### MASK OPERATIONS diff --git a/invesalius/reader/dicom.py b/invesalius/reader/dicom.py index 743aa16..860fa22 100644 --- a/invesalius/reader/dicom.py +++ b/invesalius/reader/dicom.py @@ -1129,7 +1129,7 @@ class Parser(): data = self.vtkgdcm_reader.GetMedicalImageProperties()\ .GetPatientName() if (data): - return data + return data.strip() return "" def GetPatientID(self): diff --git a/invesalius/session.py b/invesalius/session.py index c83850f..5036ba4 100644 --- a/invesalius/session.py +++ b/invesalius/session.py @@ -1,3 +1,5 @@ +import os + import constants as const from utils import Singleton @@ -7,4 +9,77 @@ class Session(object): __metaclass__= Singleton def __init__(self): - self.project_status = const.NEW_PROJECT \ No newline at end of file + self.project_path = () + + self.project_status = const.PROJ_NEW + # const.PROJ_NEW*, const.PROJ_OPEN, const.PROJ_CHANGE* + + self.mode = "" + # const.MODE_RP, const.MODE_NAVIGATOR, const.MODE_RADIOLOGY, + # const.MODE_ODONTOLOGY + + # InVesalius default projects' directory + homedir = os.path.expanduser('~') + invdir = os.path.join(homedir, ".invesalius", "temp") + if not os.path.isdir(invdir): + os.makedirs(invdir) + self.invdir = invdir + + self.temp_item = False + + # Recent projects list + self.recent_projects = [] + + + def SaveProject(self, path=()): + self.project_status = const.PROJ_OPEN + if path: + self.project_path = path + self.__add_to_list(path) + if self.temp_item: + self.temp_item = False + + def ChangeProject(self): + self.project_status = const.PROJ_CHANGE + + def CreateProject(self, filename): + # Set session info + self.project_path = (self.invdir, filename) + self.project_status = const.PROJ_NEW + self.temp_item = True + return self.invdir + + + def OpenProject(self, filepath): + # Add item to recent projects list + item = (path, file) = os.path.split(filepath) + self.__add_to_list(item) + + # Set session info + self.project_path = item + self.project_status = const.PROJ_OPEN + + def RemoveTemp(self): + if self.temp_item: + (dirpath, file) = self.project_path + path = os.path.join(dirpath, file) + os.remove(path) + self.temp_item = False + + + def __add_to_list(self, item): + # Last projects list + l = self.recent_projects + + # If item exists, remove it from list + if l.count(item): + l.remove(item) + + # Add new item + l.insert(0, item) + + # Remove oldest projects from list + if len(l)>const.PROJ_MAX: + for i in xrange(len(l)-const.PROJ_MAX): + l.pop() + -- libgit2 0.21.2