diff --git a/.gitattributes b/.gitattributes index de78ff5..940a331 100644 --- a/.gitattributes +++ b/.gitattributes @@ -151,65 +151,6 @@ icons/volume_raycasting.png -text icons/volume_raycasting_original.png -text icons/zh_TW.bmp -text invesalius/.svnignore -text -invesalius/constants.py -text -invesalius/control.py -text -invesalius/data/__init__.py -text -invesalius/data/cursor_actors.py -text -invesalius/data/editor.py -text -invesalius/data/imagedata_utils.py -text -invesalius/data/mask.py -text -invesalius/data/measures.py -text -invesalius/data/orientation.py -text -invesalius/data/polydata_utils.py -text -invesalius/data/slice_.py -text -invesalius/data/slice_data.py -text -invesalius/data/styles.py -text -invesalius/data/surface.py -text -invesalius/data/surface_process.py -text -invesalius/data/viewer.py -text -invesalius/data/viewer_slice.py -text -invesalius/data/viewer_volume.py -text -invesalius/data/volume.py -text -invesalius/data/volume_widgets.py -text -invesalius/data/vtk_utils.py -text -invesalius/gui/__init__.py -text -invesalius/gui/data_notebook.py -text -invesalius/gui/default_tasks.py -text -invesalius/gui/default_viewers.py -text -invesalius/gui/dialogs.py -text -invesalius/gui/dicom_preview_panel.py -text -invesalius/gui/frame.py -text -invesalius/gui/import_panel.py -text -invesalius/gui/language_dialog.py -text -invesalius/gui/task_exporter.py -text -invesalius/gui/task_generic.py -text -invesalius/gui/task_importer.py -text -invesalius/gui/task_navigator.py -text -invesalius/gui/task_slice.py -text -invesalius/gui/task_surface.py -text -invesalius/gui/task_tools.py -text -invesalius/gui/widgets/__init__.py -text -invesalius/gui/widgets/clut_raycasting.py -text -invesalius/gui/widgets/colourselect.py -text -invesalius/gui/widgets/foldpanelbar.py -text -invesalius/gui/widgets/gradient.py -text -invesalius/gui/widgets/listctrl.py -text -invesalius/gui/widgets/platebtn.py -text -invesalius/gui/widgets/slice_menu.py -text -invesalius/i18n.py -text -invesalius/invesalius.py -text -invesalius/math_utils.py -text -invesalius/presets.py -text -invesalius/project.py -text -invesalius/reader/__init__.py -text -invesalius/reader/analyze_reader.py -text -invesalius/reader/dicom.py -text -invesalius/reader/dicom_grouper.py -text -invesalius/reader/dicom_reader.py -text -invesalius/session.py -text -invesalius/style.py -text -invesalius/utils.py -text -invesalius/version.py -text locale/de/LC_MESSAGES/invesalius.mo -text locale/el/LC_MESSAGES/invesalius.mo -text locale/en/LC_MESSAGES/invesalius.mo -text diff --git a/invesalius/data/__init__.py b/invesalius/data/__init__.py index 0b41624..0b52a02 100644 --- a/invesalius/data/__init__.py +++ b/invesalius/data/__init__.py @@ -1,18 +1,18 @@ -#-------------------------------------------------------------------------- -# Software: InVesalius - Software de Reconstrucao 3D de Imagens Medicas -# Copyright: (C) 2001 Centro de Pesquisas Renato Archer -# Homepage: http://www.softwarepublico.gov.br -# Contact: invesalius@cti.gov.br -# License: GNU - GPL 2 (LICENSE.txt/LICENCA.txt) -#-------------------------------------------------------------------------- -# Este programa e software livre; voce pode redistribui-lo e/ou -# modifica-lo sob os termos da Licenca Publica Geral GNU, conforme -# publicada pela Free Software Foundation; de acordo com a versao 2 -# da Licenca. -# -# Este programa eh distribuido na expectativa de ser util, mas SEM -# QUALQUER GARANTIA; sem mesmo a garantia implicita de -# COMERCIALIZACAO ou de ADEQUACAO A QUALQUER PROPOSITO EM -# PARTICULAR. Consulte a Licenca Publica Geral GNU para obter mais -# detalhes. -#-------------------------------------------------------------------------- +#-------------------------------------------------------------------------- +# Software: InVesalius - Software de Reconstrucao 3D de Imagens Medicas +# Copyright: (C) 2001 Centro de Pesquisas Renato Archer +# Homepage: http://www.softwarepublico.gov.br +# Contact: invesalius@cti.gov.br +# License: GNU - GPL 2 (LICENSE.txt/LICENCA.txt) +#-------------------------------------------------------------------------- +# Este programa e software livre; voce pode redistribui-lo e/ou +# modifica-lo sob os termos da Licenca Publica Geral GNU, conforme +# publicada pela Free Software Foundation; de acordo com a versao 2 +# da Licenca. +# +# Este programa eh distribuido na expectativa de ser util, mas SEM +# QUALQUER GARANTIA; sem mesmo a garantia implicita de +# COMERCIALIZACAO ou de ADEQUACAO A QUALQUER PROPOSITO EM +# PARTICULAR. Consulte a Licenca Publica Geral GNU para obter mais +# detalhes. +#-------------------------------------------------------------------------- diff --git a/invesalius/data/surface.py b/invesalius/data/surface.py index 51fdc4c..cba320d 100644 --- a/invesalius/data/surface.py +++ b/invesalius/data/surface.py @@ -235,6 +235,7 @@ class SurfaceManager(): mapper = vtk.vtkPolyDataMapper() mapper.SetInput(normals.GetOutput()) mapper.ScalarVisibilityOff() + mapper.ImmediateModeRenderingOn() actor = vtk.vtkActor() actor.SetMapper(mapper) @@ -339,6 +340,7 @@ class SurfaceManager(): mapper = vtk.vtkPolyDataMapper() mapper.SetInput(stripper.GetOutput()) mapper.ScalarVisibilityOff() + mapper.ImmediateModeRenderingOn() # Represent an object (geometry & properties) in the rendered scene actor = vtk.vtkActor() @@ -470,6 +472,7 @@ class SurfaceManager(): mapper = vtk.vtkPolyDataMapper() mapper.SetInput(stripper.GetOutput()) mapper.ScalarVisibilityOff() + mapper.ImmediateModeRendering() # Represent an object (geometry & properties) in the rendered scene actor = vtk.vtkActor() diff --git a/invesalius/data/surface_process.py b/invesalius/data/surface_process.py index 2dbd6fc..bb5c8c4 100644 --- a/invesalius/data/surface_process.py +++ b/invesalius/data/surface_process.py @@ -1,121 +1,121 @@ -import vtk -import multiprocessing -import tempfile - -import i18n - -class SurfaceProcess(multiprocessing.Process): - - def __init__(self, pipe, filename, mode, min_value, max_value, - decimate_reduction, smooth_relaxation_factor, - smooth_iterations, language, fill_holes, keep_largest): - - multiprocessing.Process.__init__(self) - self.pipe = pipe - self.filename = filename - self.mode = mode - self.min_value = min_value - self.max_value = max_value - self.decimate_reduction = decimate_reduction - self.smooth_relaxation_factor = smooth_relaxation_factor - self.smooth_iterations = smooth_iterations - self.language = language - self.fill_holes = fill_holes - self.keep_largest = keep_largest - - - def run(self): - self.CreateSurface() - - def SendProgress(self, obj, msg): - prog = obj.GetProgress() - self.pipe.send([prog, msg]) - - def CreateSurface(self): - _ = i18n.InstallLanguage(self.language) - - reader = vtk.vtkXMLImageDataReader() - reader.SetFileName(self.filename) - reader.Update() - - # Flip original vtkImageData - flip = vtk.vtkImageFlip() - flip.SetInput(reader.GetOutput()) - flip.SetFilteredAxis(1) - flip.FlipAboutOriginOn() - - # Create vtkPolyData from vtkImageData - if self.mode == "CONTOUR": - contour = vtk.vtkContourFilter() - contour.SetInput(flip.GetOutput()) - contour.SetValue(0, self.min_value) # initial threshold - contour.SetValue(1, self.max_value) # final threshold - contour.GetOutput().ReleaseDataFlagOn() - contour.AddObserver("ProgressEvent", lambda obj,evt: - self.SendProgress(obj, _("Generating 3D surface..."))) - polydata = contour.GetOutput() - else: #mode == "GRAYSCALE": - mcubes = vtk.vtkMarchingCubes() - mcubes.SetInput(flip.GetOutput()) - mcubes.SetValue(0, 255) - mcubes.ComputeScalarsOn() - mcubes.ComputeGradientsOn() - mcubes.ComputeNormalsOn() - mcubes.ThresholdBetween(self.min_value, self.max_value) - mcubes.GetOutput().ReleaseDataFlagOn() - mcubes.AddObserver("ProgressEvent", lambda obj,evt: - self.SendProgress(obj, _("Generating 3D surface..."))) - polydata = mcubes.GetOutput() - - if self.decimate_reduction: - decimation = vtk.vtkQuadricDecimation() - decimation.SetInput(polydata) - decimation.SetTargetReduction(self.decimate_reduction) - decimation.GetOutput().ReleaseDataFlagOn() - decimation.AddObserver("ProgressEvent", lambda obj,evt: - self.SendProgress(obj, _("Generating 3D surface..."))) - polydata = decimation.GetOutput() - - if self.smooth_iterations and self.smooth_relaxation_factor: - smoother = vtk.vtkSmoothPolyDataFilter() - smoother.SetInput(polydata) - smoother.SetNumberOfIterations(self.smooth_iterations) - smoother.SetFeatureAngle(80) - smoother.SetRelaxationFactor(self.smooth_relaxation_factor) - smoother.FeatureEdgeSmoothingOn() - smoother.BoundarySmoothingOn() - smoother.GetOutput().ReleaseDataFlagOn() - smoother.AddObserver("ProgressEvent", lambda obj,evt: - self.SendProgress(obj, _("Generating 3D surface..."))) - polydata = smoother.GetOutput() - - - if self.keep_largest: - conn = vtk.vtkPolyDataConnectivityFilter() - conn.SetInput(polydata) - conn.SetExtractionModeToLargestRegion() - conn.AddObserver("ProgressEvent", lambda obj,evt: - self.SendProgress(obj, _("Generating 3D surface..."))) - polydata = conn.GetOutput() - - # Filter used to detect and fill holes. Only fill boundary edges holes. - #TODO: Hey! This piece of code is the same from - # polydata_utils.FillSurfaceHole, we need to review this. - if self.fill_holes: - filled_polydata = vtk.vtkFillHolesFilter() - filled_polydata.SetInput(polydata) - filled_polydata.SetHoleSize(300) - filled_polydata.AddObserver("ProgressEvent", lambda obj,evt: - self.SendProgress(obj, _("Generating 3D surface..."))) - polydata = filled_polydata.GetOutput() - - - - filename = tempfile.mktemp() - writer = vtk.vtkXMLPolyDataWriter() - writer.SetInput(polydata) - writer.SetFileName(filename) - writer.Write() - - self.pipe.send(None) - self.pipe.send(filename) +import vtk +import multiprocessing +import tempfile + +import i18n + +class SurfaceProcess(multiprocessing.Process): + + def __init__(self, pipe, filename, mode, min_value, max_value, + decimate_reduction, smooth_relaxation_factor, + smooth_iterations, language, fill_holes, keep_largest): + + multiprocessing.Process.__init__(self) + self.pipe = pipe + self.filename = filename + self.mode = mode + self.min_value = min_value + self.max_value = max_value + self.decimate_reduction = decimate_reduction + self.smooth_relaxation_factor = smooth_relaxation_factor + self.smooth_iterations = smooth_iterations + self.language = language + self.fill_holes = fill_holes + self.keep_largest = keep_largest + + + def run(self): + self.CreateSurface() + + def SendProgress(self, obj, msg): + prog = obj.GetProgress() + self.pipe.send([prog, msg]) + + def CreateSurface(self): + _ = i18n.InstallLanguage(self.language) + + reader = vtk.vtkXMLImageDataReader() + reader.SetFileName(self.filename) + reader.Update() + + # Flip original vtkImageData + flip = vtk.vtkImageFlip() + flip.SetInput(reader.GetOutput()) + flip.SetFilteredAxis(1) + flip.FlipAboutOriginOn() + + # Create vtkPolyData from vtkImageData + if self.mode == "CONTOUR": + contour = vtk.vtkContourFilter() + contour.SetInput(flip.GetOutput()) + contour.SetValue(0, self.min_value) # initial threshold + contour.SetValue(1, self.max_value) # final threshold + contour.GetOutput().ReleaseDataFlagOn() + contour.AddObserver("ProgressEvent", lambda obj,evt: + self.SendProgress(obj, _("Generating 3D surface..."))) + polydata = contour.GetOutput() + else: #mode == "GRAYSCALE": + mcubes = vtk.vtkMarchingCubes() + mcubes.SetInput(flip.GetOutput()) + mcubes.SetValue(0, 255) + mcubes.ComputeScalarsOn() + mcubes.ComputeGradientsOn() + mcubes.ComputeNormalsOn() + mcubes.ThresholdBetween(self.min_value, self.max_value) + mcubes.GetOutput().ReleaseDataFlagOn() + mcubes.AddObserver("ProgressEvent", lambda obj,evt: + self.SendProgress(obj, _("Generating 3D surface..."))) + polydata = mcubes.GetOutput() + + if self.decimate_reduction: + decimation = vtk.vtkQuadricDecimation() + decimation.SetInput(polydata) + decimation.SetTargetReduction(self.decimate_reduction) + decimation.GetOutput().ReleaseDataFlagOn() + decimation.AddObserver("ProgressEvent", lambda obj,evt: + self.SendProgress(obj, _("Generating 3D surface..."))) + polydata = decimation.GetOutput() + + if self.smooth_iterations and self.smooth_relaxation_factor: + smoother = vtk.vtkSmoothPolyDataFilter() + smoother.SetInput(polydata) + smoother.SetNumberOfIterations(self.smooth_iterations) + smoother.SetFeatureAngle(80) + smoother.SetRelaxationFactor(self.smooth_relaxation_factor) + smoother.FeatureEdgeSmoothingOn() + smoother.BoundarySmoothingOn() + smoother.GetOutput().ReleaseDataFlagOn() + smoother.AddObserver("ProgressEvent", lambda obj,evt: + self.SendProgress(obj, _("Generating 3D surface..."))) + polydata = smoother.GetOutput() + + + if self.keep_largest: + conn = vtk.vtkPolyDataConnectivityFilter() + conn.SetInput(polydata) + conn.SetExtractionModeToLargestRegion() + conn.AddObserver("ProgressEvent", lambda obj,evt: + self.SendProgress(obj, _("Generating 3D surface..."))) + polydata = conn.GetOutput() + + # Filter used to detect and fill holes. Only fill boundary edges holes. + #TODO: Hey! This piece of code is the same from + # polydata_utils.FillSurfaceHole, we need to review this. + if self.fill_holes: + filled_polydata = vtk.vtkFillHolesFilter() + filled_polydata.SetInput(polydata) + filled_polydata.SetHoleSize(300) + filled_polydata.AddObserver("ProgressEvent", lambda obj,evt: + self.SendProgress(obj, _("Generating 3D surface..."))) + polydata = filled_polydata.GetOutput() + + + + filename = tempfile.mktemp() + writer = vtk.vtkXMLPolyDataWriter() + writer.SetInput(polydata) + writer.SetFileName(filename) + writer.Write() + + self.pipe.send(None) + self.pipe.send(filename) diff --git a/invesalius/data/viewer.py b/invesalius/data/viewer.py index 0b41624..0b52a02 100644 --- a/invesalius/data/viewer.py +++ b/invesalius/data/viewer.py @@ -1,18 +1,18 @@ -#-------------------------------------------------------------------------- -# Software: InVesalius - Software de Reconstrucao 3D de Imagens Medicas -# Copyright: (C) 2001 Centro de Pesquisas Renato Archer -# Homepage: http://www.softwarepublico.gov.br -# Contact: invesalius@cti.gov.br -# License: GNU - GPL 2 (LICENSE.txt/LICENCA.txt) -#-------------------------------------------------------------------------- -# Este programa e software livre; voce pode redistribui-lo e/ou -# modifica-lo sob os termos da Licenca Publica Geral GNU, conforme -# publicada pela Free Software Foundation; de acordo com a versao 2 -# da Licenca. -# -# Este programa eh distribuido na expectativa de ser util, mas SEM -# QUALQUER GARANTIA; sem mesmo a garantia implicita de -# COMERCIALIZACAO ou de ADEQUACAO A QUALQUER PROPOSITO EM -# PARTICULAR. Consulte a Licenca Publica Geral GNU para obter mais -# detalhes. -#-------------------------------------------------------------------------- +#-------------------------------------------------------------------------- +# Software: InVesalius - Software de Reconstrucao 3D de Imagens Medicas +# Copyright: (C) 2001 Centro de Pesquisas Renato Archer +# Homepage: http://www.softwarepublico.gov.br +# Contact: invesalius@cti.gov.br +# License: GNU - GPL 2 (LICENSE.txt/LICENCA.txt) +#-------------------------------------------------------------------------- +# Este programa e software livre; voce pode redistribui-lo e/ou +# modifica-lo sob os termos da Licenca Publica Geral GNU, conforme +# publicada pela Free Software Foundation; de acordo com a versao 2 +# da Licenca. +# +# Este programa eh distribuido na expectativa de ser util, mas SEM +# QUALQUER GARANTIA; sem mesmo a garantia implicita de +# COMERCIALIZACAO ou de ADEQUACAO A QUALQUER PROPOSITO EM +# PARTICULAR. Consulte a Licenca Publica Geral GNU para obter mais +# detalhes. +#-------------------------------------------------------------------------- diff --git a/invesalius/gui/__init__.py b/invesalius/gui/__init__.py index 0b41624..0b52a02 100644 --- a/invesalius/gui/__init__.py +++ b/invesalius/gui/__init__.py @@ -1,18 +1,18 @@ -#-------------------------------------------------------------------------- -# Software: InVesalius - Software de Reconstrucao 3D de Imagens Medicas -# Copyright: (C) 2001 Centro de Pesquisas Renato Archer -# Homepage: http://www.softwarepublico.gov.br -# Contact: invesalius@cti.gov.br -# License: GNU - GPL 2 (LICENSE.txt/LICENCA.txt) -#-------------------------------------------------------------------------- -# Este programa e software livre; voce pode redistribui-lo e/ou -# modifica-lo sob os termos da Licenca Publica Geral GNU, conforme -# publicada pela Free Software Foundation; de acordo com a versao 2 -# da Licenca. -# -# Este programa eh distribuido na expectativa de ser util, mas SEM -# QUALQUER GARANTIA; sem mesmo a garantia implicita de -# COMERCIALIZACAO ou de ADEQUACAO A QUALQUER PROPOSITO EM -# PARTICULAR. Consulte a Licenca Publica Geral GNU para obter mais -# detalhes. -#-------------------------------------------------------------------------- +#-------------------------------------------------------------------------- +# Software: InVesalius - Software de Reconstrucao 3D de Imagens Medicas +# Copyright: (C) 2001 Centro de Pesquisas Renato Archer +# Homepage: http://www.softwarepublico.gov.br +# Contact: invesalius@cti.gov.br +# License: GNU - GPL 2 (LICENSE.txt/LICENCA.txt) +#-------------------------------------------------------------------------- +# Este programa e software livre; voce pode redistribui-lo e/ou +# modifica-lo sob os termos da Licenca Publica Geral GNU, conforme +# publicada pela Free Software Foundation; de acordo com a versao 2 +# da Licenca. +# +# Este programa eh distribuido na expectativa de ser util, mas SEM +# QUALQUER GARANTIA; sem mesmo a garantia implicita de +# COMERCIALIZACAO ou de ADEQUACAO A QUALQUER PROPOSITO EM +# PARTICULAR. Consulte a Licenca Publica Geral GNU para obter mais +# detalhes. +#-------------------------------------------------------------------------- diff --git a/invesalius/gui/language_dialog.py b/invesalius/gui/language_dialog.py index 3f80d68..22b3202 100644 --- a/invesalius/gui/language_dialog.py +++ b/invesalius/gui/language_dialog.py @@ -1,122 +1,122 @@ -#-------------------------------------------------------------------------- -# Software: InVesalius - Software de Reconstrucao 3D de Imagens Medicas -# Copyright: (C) 2001 Centro de Pesquisas Renato Archer -# Homepage: http://www.softwarepublico.gov.br -# Contact: invesalius@cti.gov.br -# License: GNU - GPL 2 (LICENSE.txt/LICENCA.txt) -#-------------------------------------------------------------------------- -# Este programa e software livre; voce pode redistribui-lo e/ou -# modifica-lo sob os termos da Licenca Publica Geral GNU, conforme -# publicada pela Free Software Foundation; de acordo com a versao 2 -# da Licenca. -# -# Este programa eh distribuido na expectativa de ser util, mas SEM -# QUALQUER GARANTIA; sem mesmo a garantia implicita de -# COMERCIALIZACAO ou de ADEQUACAO A QUALQUER PROPOSITO EM -# PARTICULAR. Consulte a Licenca Publica Geral GNU para obter mais -# detalhes. -#-------------------------------------------------------------------------- - -import os -import wx -import wx.combo - -import i18n - -ICON_DIR = os.path.abspath(os.path.join('..', 'icons')) - -class LanguageDialog(wx.Dialog): - """Class define the language to be used in the InVesalius, - exist chcLanguage that list language EN and PT. The language - selected is writing in the config.ini""" - - def __init__(self, parent=None, startApp=None): - super(LanguageDialog, self).__init__(parent, title="") - self.__TranslateMessage__() - self.SetTitle(_('Language selection')) - self.__init_gui() - self.Centre() - - def __init_combobox_bitmap__(self): - """Initialize combobox bitmap""" - - # Retrieve locales dictionary - dict_locales = i18n.GetLocales() - - # Retrieve locales names and sort them - self.locales = dict_locales.values() - self.locales.sort() - - # Retrieve locales keys (eg: pt_BR for Portuguese(Brazilian)) - self.locales_key = [dict_locales.get_key(value)[0] for value in self.locales] - - # Find out OS locale - self.os_locale = i18n.GetLocaleOS() - - # FIXME: In future we shall be using all locales using 5 - # characters... until then, we use only 2: - os_lang = self.os_locale[0:2] - - # Default selection will be English - selection = self.locales_key.index('en') - - # Create bitmap combo - self.bitmapCmb = bitmapCmb = wx.combo.BitmapComboBox(self, style=wx.CB_READONLY) - for key in self.locales_key: - # Based on composed flag filename, get bitmap - filepath = os.path.join(ICON_DIR, "%s.bmp"%(key)) - bmp = wx.Bitmap(filepath, wx.BITMAP_TYPE_BMP) - # Add bitmap and info to Combo - bitmapCmb.Append(dict_locales[key], bmp, key) - # Set default combo item if available on the list - if key.startswith(os_lang): - selection = self.locales_key.index(key) - bitmapCmb.SetSelection(selection) - - - def __init_gui(self): - self.txtMsg = wx.StaticText(self, -1, - label=_('Choose user interface language')) - - btnsizer = wx.StdDialogButtonSizer() - - btn = wx.Button(self, wx.ID_OK) - btn.SetDefault() - btnsizer.AddButton(btn) - - btn = wx.Button(self, wx.ID_CANCEL) - btnsizer.AddButton(btn) - btnsizer.Realize() - - self.__init_combobox_bitmap__() - - sizer = wx.BoxSizer(wx.VERTICAL) - sizer.Add(self.txtMsg, 0, wx.EXPAND | wx.ALL, 5) - sizer.Add(self.bitmapCmb, 0, wx.EXPAND | wx.ALL, 5) - sizer.Add(btnsizer, 0, wx.EXPAND | wx.ALL, 5) - - sizer.Fit(self) - self.SetSizer(sizer) - self.Layout() - self.Update() - self.SetAutoLayout(1) - - def GetSelectedLanguage(self): - """Return String with Selected Language""" - return self.locales_key[self.bitmapCmb.GetSelection()] - - def __TranslateMessage__(self): - """Translate Messages of the Window""" - os_language = i18n.GetLocaleOS() - - if(os_language[0:2] == 'pt'): - _ = i18n.InstallLanguage('pt_BR') - elif(os_language[0:2] == 'es'): - _ = i18n.InstallLanguage('es') - else: - _ = i18n.InstallLanguage('en') - - def Cancel(self, event): - """Close Frm_Language""" - self.Close() - event.Skip() +#-------------------------------------------------------------------------- +# Software: InVesalius - Software de Reconstrucao 3D de Imagens Medicas +# Copyright: (C) 2001 Centro de Pesquisas Renato Archer +# Homepage: http://www.softwarepublico.gov.br +# Contact: invesalius@cti.gov.br +# License: GNU - GPL 2 (LICENSE.txt/LICENCA.txt) +#-------------------------------------------------------------------------- +# Este programa e software livre; voce pode redistribui-lo e/ou +# modifica-lo sob os termos da Licenca Publica Geral GNU, conforme +# publicada pela Free Software Foundation; de acordo com a versao 2 +# da Licenca. +# +# Este programa eh distribuido na expectativa de ser util, mas SEM +# QUALQUER GARANTIA; sem mesmo a garantia implicita de +# COMERCIALIZACAO ou de ADEQUACAO A QUALQUER PROPOSITO EM +# PARTICULAR. Consulte a Licenca Publica Geral GNU para obter mais +# detalhes. +#-------------------------------------------------------------------------- + +import os +import wx +import wx.combo + +import i18n + +ICON_DIR = os.path.abspath(os.path.join('..', 'icons')) + +class LanguageDialog(wx.Dialog): + """Class define the language to be used in the InVesalius, + exist chcLanguage that list language EN and PT. The language + selected is writing in the config.ini""" + + def __init__(self, parent=None, startApp=None): + super(LanguageDialog, self).__init__(parent, title="") + self.__TranslateMessage__() + self.SetTitle(_('Language selection')) + self.__init_gui() + self.Centre() + + def __init_combobox_bitmap__(self): + """Initialize combobox bitmap""" + + # Retrieve locales dictionary + dict_locales = i18n.GetLocales() + + # Retrieve locales names and sort them + self.locales = dict_locales.values() + self.locales.sort() + + # Retrieve locales keys (eg: pt_BR for Portuguese(Brazilian)) + self.locales_key = [dict_locales.get_key(value)[0] for value in self.locales] + + # Find out OS locale + self.os_locale = i18n.GetLocaleOS() + + # FIXME: In future we shall be using all locales using 5 + # characters... until then, we use only 2: + os_lang = self.os_locale[0:2] + + # Default selection will be English + selection = self.locales_key.index('en') + + # Create bitmap combo + self.bitmapCmb = bitmapCmb = wx.combo.BitmapComboBox(self, style=wx.CB_READONLY) + for key in self.locales_key: + # Based on composed flag filename, get bitmap + filepath = os.path.join(ICON_DIR, "%s.bmp"%(key)) + bmp = wx.Bitmap(filepath, wx.BITMAP_TYPE_BMP) + # Add bitmap and info to Combo + bitmapCmb.Append(dict_locales[key], bmp, key) + # Set default combo item if available on the list + if key.startswith(os_lang): + selection = self.locales_key.index(key) + bitmapCmb.SetSelection(selection) + + + def __init_gui(self): + self.txtMsg = wx.StaticText(self, -1, + label=_('Choose user interface language')) + + btnsizer = wx.StdDialogButtonSizer() + + btn = wx.Button(self, wx.ID_OK) + btn.SetDefault() + btnsizer.AddButton(btn) + + btn = wx.Button(self, wx.ID_CANCEL) + btnsizer.AddButton(btn) + btnsizer.Realize() + + self.__init_combobox_bitmap__() + + sizer = wx.BoxSizer(wx.VERTICAL) + sizer.Add(self.txtMsg, 0, wx.EXPAND | wx.ALL, 5) + sizer.Add(self.bitmapCmb, 0, wx.EXPAND | wx.ALL, 5) + sizer.Add(btnsizer, 0, wx.EXPAND | wx.ALL, 5) + + sizer.Fit(self) + self.SetSizer(sizer) + self.Layout() + self.Update() + self.SetAutoLayout(1) + + def GetSelectedLanguage(self): + """Return String with Selected Language""" + return self.locales_key[self.bitmapCmb.GetSelection()] + + def __TranslateMessage__(self): + """Translate Messages of the Window""" + os_language = i18n.GetLocaleOS() + + if(os_language[0:2] == 'pt'): + _ = i18n.InstallLanguage('pt_BR') + elif(os_language[0:2] == 'es'): + _ = i18n.InstallLanguage('es') + else: + _ = i18n.InstallLanguage('en') + + def Cancel(self, event): + """Close Frm_Language""" + self.Close() + event.Skip() diff --git a/invesalius/gui/widgets/__init__.py b/invesalius/gui/widgets/__init__.py index 0b41624..0b52a02 100644 --- a/invesalius/gui/widgets/__init__.py +++ b/invesalius/gui/widgets/__init__.py @@ -1,18 +1,18 @@ -#-------------------------------------------------------------------------- -# Software: InVesalius - Software de Reconstrucao 3D de Imagens Medicas -# Copyright: (C) 2001 Centro de Pesquisas Renato Archer -# Homepage: http://www.softwarepublico.gov.br -# Contact: invesalius@cti.gov.br -# License: GNU - GPL 2 (LICENSE.txt/LICENCA.txt) -#-------------------------------------------------------------------------- -# Este programa e software livre; voce pode redistribui-lo e/ou -# modifica-lo sob os termos da Licenca Publica Geral GNU, conforme -# publicada pela Free Software Foundation; de acordo com a versao 2 -# da Licenca. -# -# Este programa eh distribuido na expectativa de ser util, mas SEM -# QUALQUER GARANTIA; sem mesmo a garantia implicita de -# COMERCIALIZACAO ou de ADEQUACAO A QUALQUER PROPOSITO EM -# PARTICULAR. Consulte a Licenca Publica Geral GNU para obter mais -# detalhes. -#-------------------------------------------------------------------------- +#-------------------------------------------------------------------------- +# Software: InVesalius - Software de Reconstrucao 3D de Imagens Medicas +# Copyright: (C) 2001 Centro de Pesquisas Renato Archer +# Homepage: http://www.softwarepublico.gov.br +# Contact: invesalius@cti.gov.br +# License: GNU - GPL 2 (LICENSE.txt/LICENCA.txt) +#-------------------------------------------------------------------------- +# Este programa e software livre; voce pode redistribui-lo e/ou +# modifica-lo sob os termos da Licenca Publica Geral GNU, conforme +# publicada pela Free Software Foundation; de acordo com a versao 2 +# da Licenca. +# +# Este programa eh distribuido na expectativa de ser util, mas SEM +# QUALQUER GARANTIA; sem mesmo a garantia implicita de +# COMERCIALIZACAO ou de ADEQUACAO A QUALQUER PROPOSITO EM +# PARTICULAR. Consulte a Licenca Publica Geral GNU para obter mais +# detalhes. +#-------------------------------------------------------------------------- diff --git a/invesalius/gui/widgets/colourselect.py b/invesalius/gui/widgets/colourselect.py index a9d8c19..8b5eff5 100644 --- a/invesalius/gui/widgets/colourselect.py +++ b/invesalius/gui/widgets/colourselect.py @@ -1,176 +1,176 @@ -#---------------------------------------------------------------------------- -# Name: ColourSelect.py -# Purpose: Colour Box Selection Control -# -# Author: Lorne White, Lorne.White@telusplanet.net -# -# Created: Feb 25, 2001 -# Licence: wxWindows license -#---------------------------------------------------------------------------- - -# creates a colour wxButton with selectable color -# button click provides a colour selection box -# button colour will change to new colour -# GetColour method to get the selected colour - -# Updates: -# call back to function if changes made - -# Cliff Wells, logiplexsoftware@earthlink.net: -# - Made ColourSelect into "is a button" rather than "has a button" -# - Added label parameter and logic to adjust the label colour according to the background -# colour -# - Added id argument -# - Rearranged arguments to more closely follow wx conventions -# - Simplified some of the code - -# Cliff Wells, 2002/02/07 -# - Added ColourSelect Event - -# 12/01/2003 - Jeff Grimmett (grimmtooth@softhome.net) -# -# o Updated for 2.5 compatability. -# - -""" -Provides a `ColourSelect` button that, when clicked, will display a -colour selection dialog. The selected colour is displayed on the -button itself. -""" - -#---------------------------------------------------------------------------- - -import wx - -#---------------------------------------------------------------------------- - -wxEVT_COMMAND_COLOURSELECT = wx.NewEventType() - -class ColourSelectEvent(wx.PyCommandEvent): - def __init__(self, id, value): - wx.PyCommandEvent.__init__(self, id = id) - self.SetEventType(wxEVT_COMMAND_COLOURSELECT) - self.value = value - - def GetValue(self): - return self.value - -EVT_COLOURSELECT = wx.PyEventBinder(wxEVT_COMMAND_COLOURSELECT, 1) - -#---------------------------------------------------------------------------- - -class ColourSelect(wx.BitmapButton): - def __init__(self, parent, id=wx.ID_ANY, label="", colour=wx.BLACK, - pos=wx.DefaultPosition, size=wx.DefaultSize, - callback=None, style=0): - if label: - w, h = parent.GetTextExtent(label) - w += 6 - h += 6 - else: - w, h = 20, 20 - wx.BitmapButton.__init__(self, parent, id, wx.EmptyBitmap(w,h), - pos=pos, size=size, style=style|wx.BU_AUTODRAW) - - if type(colour) == type( () ): - colour = wx.Colour(*colour) - self.colour = colour - self.SetLabel(label) - self.callback = callback - bmp = self.MakeBitmap() - self.SetBitmap(bmp) - parent.Bind(wx.EVT_BUTTON, self.OnClick, self) - - - def GetColour(self): - return self.colour - - def GetValue(self): - return self.colour - - def SetValue(self, colour): - self.SetColour(colour) - - def SetColour(self, colour): - if type(colour) == tuple: - colour = wx.Colour(*colour) - if type(colour) == str: - colour = wx.NamedColour(colour) - - self.colour = colour - bmp = self.MakeBitmap() - self.SetBitmap(bmp) - - - def SetLabel(self, label): - self.label = label - - def GetLabel(self): - return self.label - - - def MakeBitmap(self): - bdr = 8 - width, height = self.GetSize() - - # yes, this is weird, but it appears to work around a bug in wxMac - if "wxMac" in wx.PlatformInfo and width == height: - height -= 1 - - bmp = wx.EmptyBitmap(width-bdr, height-bdr) - dc = wx.MemoryDC() - dc.SelectObject(bmp) - dc.SetFont(self.GetFont()) - label = self.GetLabel() - # Just make a little colored bitmap - dc.SetBackground(wx.Brush(self.colour)) - dc.Clear() - - if label: - # Add a label to it - avg = reduce(lambda a, b: a + b, self.colour.Get()) / 3 - fcolour = avg > 128 and wx.BLACK or wx.WHITE - dc.SetTextForeground(fcolour) - dc.DrawLabel(label, (0,0, width-bdr, height-bdr), - wx.ALIGN_CENTER) - - dc.SelectObject(wx.NullBitmap) - return bmp - - - def SetBitmap(self, bmp): - self.SetBitmapLabel(bmp) - #self.SetBitmapSelected(bmp) - #self.SetBitmapDisabled(bmp) - #self.SetBitmapFocus(bmp) - #self.SetBitmapSelected(bmp) - self.Refresh() - - - def OnChange(self): - evt = ColourSelectEvent(self.GetId(), self.GetValue()) - evt.SetEventObject(self) - wx.PostEvent(self, evt) - if self.callback is not None: - self.callback() - - def OnClick(self, event): - data = wx.ColourData() - data.SetChooseFull(True) - data.SetColour(self.colour) - dlg = wx.ColourDialog(wx.GetTopLevelParent(self), data) - - try: - changed = dlg.ShowModal() == wx.ID_OK - except(wx._core.PyAssertionError): - changed = True - - if changed: - data = dlg.GetColourData() - self.SetColour(data.GetColour()) - dlg.Destroy() - - # moved after dlg.Destroy, since who knows what the callback will do... - if changed: - self.OnChange() - +#---------------------------------------------------------------------------- +# Name: ColourSelect.py +# Purpose: Colour Box Selection Control +# +# Author: Lorne White, Lorne.White@telusplanet.net +# +# Created: Feb 25, 2001 +# Licence: wxWindows license +#---------------------------------------------------------------------------- + +# creates a colour wxButton with selectable color +# button click provides a colour selection box +# button colour will change to new colour +# GetColour method to get the selected colour + +# Updates: +# call back to function if changes made + +# Cliff Wells, logiplexsoftware@earthlink.net: +# - Made ColourSelect into "is a button" rather than "has a button" +# - Added label parameter and logic to adjust the label colour according to the background +# colour +# - Added id argument +# - Rearranged arguments to more closely follow wx conventions +# - Simplified some of the code + +# Cliff Wells, 2002/02/07 +# - Added ColourSelect Event + +# 12/01/2003 - Jeff Grimmett (grimmtooth@softhome.net) +# +# o Updated for 2.5 compatability. +# + +""" +Provides a `ColourSelect` button that, when clicked, will display a +colour selection dialog. The selected colour is displayed on the +button itself. +""" + +#---------------------------------------------------------------------------- + +import wx + +#---------------------------------------------------------------------------- + +wxEVT_COMMAND_COLOURSELECT = wx.NewEventType() + +class ColourSelectEvent(wx.PyCommandEvent): + def __init__(self, id, value): + wx.PyCommandEvent.__init__(self, id = id) + self.SetEventType(wxEVT_COMMAND_COLOURSELECT) + self.value = value + + def GetValue(self): + return self.value + +EVT_COLOURSELECT = wx.PyEventBinder(wxEVT_COMMAND_COLOURSELECT, 1) + +#---------------------------------------------------------------------------- + +class ColourSelect(wx.BitmapButton): + def __init__(self, parent, id=wx.ID_ANY, label="", colour=wx.BLACK, + pos=wx.DefaultPosition, size=wx.DefaultSize, + callback=None, style=0): + if label: + w, h = parent.GetTextExtent(label) + w += 6 + h += 6 + else: + w, h = 20, 20 + wx.BitmapButton.__init__(self, parent, id, wx.EmptyBitmap(w,h), + pos=pos, size=size, style=style|wx.BU_AUTODRAW) + + if type(colour) == type( () ): + colour = wx.Colour(*colour) + self.colour = colour + self.SetLabel(label) + self.callback = callback + bmp = self.MakeBitmap() + self.SetBitmap(bmp) + parent.Bind(wx.EVT_BUTTON, self.OnClick, self) + + + def GetColour(self): + return self.colour + + def GetValue(self): + return self.colour + + def SetValue(self, colour): + self.SetColour(colour) + + def SetColour(self, colour): + if type(colour) == tuple: + colour = wx.Colour(*colour) + if type(colour) == str: + colour = wx.NamedColour(colour) + + self.colour = colour + bmp = self.MakeBitmap() + self.SetBitmap(bmp) + + + def SetLabel(self, label): + self.label = label + + def GetLabel(self): + return self.label + + + def MakeBitmap(self): + bdr = 8 + width, height = self.GetSize() + + # yes, this is weird, but it appears to work around a bug in wxMac + if "wxMac" in wx.PlatformInfo and width == height: + height -= 1 + + bmp = wx.EmptyBitmap(width-bdr, height-bdr) + dc = wx.MemoryDC() + dc.SelectObject(bmp) + dc.SetFont(self.GetFont()) + label = self.GetLabel() + # Just make a little colored bitmap + dc.SetBackground(wx.Brush(self.colour)) + dc.Clear() + + if label: + # Add a label to it + avg = reduce(lambda a, b: a + b, self.colour.Get()) / 3 + fcolour = avg > 128 and wx.BLACK or wx.WHITE + dc.SetTextForeground(fcolour) + dc.DrawLabel(label, (0,0, width-bdr, height-bdr), + wx.ALIGN_CENTER) + + dc.SelectObject(wx.NullBitmap) + return bmp + + + def SetBitmap(self, bmp): + self.SetBitmapLabel(bmp) + #self.SetBitmapSelected(bmp) + #self.SetBitmapDisabled(bmp) + #self.SetBitmapFocus(bmp) + #self.SetBitmapSelected(bmp) + self.Refresh() + + + def OnChange(self): + evt = ColourSelectEvent(self.GetId(), self.GetValue()) + evt.SetEventObject(self) + wx.PostEvent(self, evt) + if self.callback is not None: + self.callback() + + def OnClick(self, event): + data = wx.ColourData() + data.SetChooseFull(True) + data.SetColour(self.colour) + dlg = wx.ColourDialog(wx.GetTopLevelParent(self), data) + + try: + changed = dlg.ShowModal() == wx.ID_OK + except(wx._core.PyAssertionError): + changed = True + + if changed: + data = dlg.GetColourData() + self.SetColour(data.GetColour()) + dlg.Destroy() + + # moved after dlg.Destroy, since who knows what the callback will do... + if changed: + self.OnChange() + diff --git a/invesalius/reader/__init__.py b/invesalius/reader/__init__.py index 0b41624..0b52a02 100644 --- a/invesalius/reader/__init__.py +++ b/invesalius/reader/__init__.py @@ -1,18 +1,18 @@ -#-------------------------------------------------------------------------- -# Software: InVesalius - Software de Reconstrucao 3D de Imagens Medicas -# Copyright: (C) 2001 Centro de Pesquisas Renato Archer -# Homepage: http://www.softwarepublico.gov.br -# Contact: invesalius@cti.gov.br -# License: GNU - GPL 2 (LICENSE.txt/LICENCA.txt) -#-------------------------------------------------------------------------- -# Este programa e software livre; voce pode redistribui-lo e/ou -# modifica-lo sob os termos da Licenca Publica Geral GNU, conforme -# publicada pela Free Software Foundation; de acordo com a versao 2 -# da Licenca. -# -# Este programa eh distribuido na expectativa de ser util, mas SEM -# QUALQUER GARANTIA; sem mesmo a garantia implicita de -# COMERCIALIZACAO ou de ADEQUACAO A QUALQUER PROPOSITO EM -# PARTICULAR. Consulte a Licenca Publica Geral GNU para obter mais -# detalhes. -#-------------------------------------------------------------------------- +#-------------------------------------------------------------------------- +# Software: InVesalius - Software de Reconstrucao 3D de Imagens Medicas +# Copyright: (C) 2001 Centro de Pesquisas Renato Archer +# Homepage: http://www.softwarepublico.gov.br +# Contact: invesalius@cti.gov.br +# License: GNU - GPL 2 (LICENSE.txt/LICENCA.txt) +#-------------------------------------------------------------------------- +# Este programa e software livre; voce pode redistribui-lo e/ou +# modifica-lo sob os termos da Licenca Publica Geral GNU, conforme +# publicada pela Free Software Foundation; de acordo com a versao 2 +# da Licenca. +# +# Este programa eh distribuido na expectativa de ser util, mas SEM +# QUALQUER GARANTIA; sem mesmo a garantia implicita de +# COMERCIALIZACAO ou de ADEQUACAO A QUALQUER PROPOSITO EM +# PARTICULAR. Consulte a Licenca Publica Geral GNU para obter mais +# detalhes. +#-------------------------------------------------------------------------- diff --git a/invesalius/session.py b/invesalius/session.py index 2900a57..062d703 100644 --- a/invesalius/session.py +++ b/invesalius/session.py @@ -1,276 +1,276 @@ -import ConfigParser -import os -import shutil -import sys -from threading import Thread -import time - -import wx.lib.pubsub as ps - -from utils import Singleton, debug - -class Session(object): - # Only one session will be initialized per time. Therefore, we use - # Singleton design pattern for implementing it - __metaclass__= Singleton - - def __init__(self): - self.temp_item = False - - ws = self.ws = WriteSession(self) - ws.start() - ps.Publisher().subscribe(self.StopRecording, "Stop Config Recording") - - def CreateItens(self): - import constants as const - self.project_path = () - self.debug = False - - self.project_status = const.PROJ_CLOSE - # const.PROJ_NEW*, const.PROJ_OPEN, const.PROJ_CHANGE*, - # const.PROJ_CLOSE - - self.mode = const.MODE_RP - # const.MODE_RP, const.MODE_NAVIGATOR, const.MODE_RADIOLOGY, - # const.MODE_ODONTOLOGY - - # InVesalius default projects' directory - homedir = self.homedir = os.path.expanduser('~') - tempdir = os.path.join(homedir, ".invesalius", "temp") - if not os.path.isdir(tempdir): - os.makedirs(tempdir) - self.tempdir = tempdir - - # GUI language - self.language = "" # "pt_BR", "es" - - # Recent projects list - self.recent_projects = [(const.SAMPLE_DIR, "Cranium.inv3")] - self.last_dicom_folder = '' - - self.CreateSessionFile() - - def StopRecording(self, pubsub_evt): - self.ws.Stop() - - def SaveConfigFileBackup(self): - path = os.path.join(self.homedir , - '.invesalius', 'config.cfg') - path_dst = os.path.join(self.homedir , - '.invesalius', 'config.backup') - shutil.copy(path, path_dst) - - def RecoveryConfigFile(self): - homedir = self.homedir = os.path.expanduser('~') - try: - path = os.path.join(self.homedir , - '.invesalius', 'config.backup') - path_dst = os.path.join(self.homedir , - '.invesalius', 'config.cfg') - shutil.copy(path, path_dst) - return True - except(IOError): - return False - - - def CloseProject(self): - import constants as const - debug("Session.CloseProject") - self.project_path = () - self.project_status = const.PROJ_CLOSE - #self.mode = const.MODE_RP - self.temp_item = False - - def SaveProject(self, path=()): - import constants as const - debug("Session.SaveProject") - 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): - import constants as const - debug("Session.ChangeProject") - self.project_status = const.PROJ_CHANGE - - def CreateProject(self, filename): - import constants as const - debug("Session.CreateProject") - ps.Publisher().sendMessage('Begin busy cursor') - # Set session info - self.project_path = (self.tempdir, filename) - self.project_status = const.PROJ_NEW - self.temp_item = True - return self.tempdir - - def OpenProject(self, filepath): - import constants as const - debug("Session.OpenProject") - # 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 CreateSessionFile(self): - config = ConfigParser.RawConfigParser() - - config.add_section('session') - config.set('session', 'mode', self.mode) - config.set('session', 'status', self.project_status) - config.set('session','debug', self.debug) - config.set('session', 'language', self.language) - - config.add_section('project') - config.set('project', 'recent_projects', self.recent_projects) - - config.add_section('paths') - config.set('paths','homedir',self.homedir) - config.set('paths','tempdir',self.tempdir) - try: - config.set('paths','last_dicom_folder',self.last_dicom_folder.encode('utf-8')) - except (UnicodeEncodeError, UnicodeDecodeError): - config.set('paths','last_dicom_folder',self.last_dicom_folder) - path = os.path.join(self.homedir , - '.invesalius', 'config.cfg') - - configfile = open(path, 'wb') - config.write(configfile) - configfile.close() - - - def __add_to_list(self, item): - import constants as const - # 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() - - def GetLanguage(self): - return self.language - - def SetLanguage(self, language): - self.language = language - - def GetLastDicomFolder(self): - return self.last_dicom_folder - - def SetLastDicomFolder(self, folder): - self.last_dicom_folder = folder - self.CreateSessionFile() - - def ReadLanguage(self): - config = ConfigParser.ConfigParser() - home_path = os.path.expanduser('~') - path = os.path.join(home_path ,'.invesalius', 'config.cfg') - try: - config.read(path) - self.language = config.get('session','language') - return self.language - except (ConfigParser.NoSectionError, - ConfigParser.NoOptionError, - ConfigParser.MissingSectionHeaderError): - return False - - def ReadSession(self): - config = ConfigParser.ConfigParser() - home_path = os.path.expanduser('~') - path = os.path.join(home_path ,'.invesalius', 'config.cfg') - try: - config.read(path) - self.mode = config.get('session', 'mode') - self.project_status = config.get('session', 'status') - self.debug = config.get('session','debug') - self.language = config.get('session','language') - self.recent_projects = eval(config.get('project','recent_projects')) - self.homedir = config.get('paths','homedir') - self.tempdir = config.get('paths','tempdir') - self.last_dicom_folder = config.get('paths','last_dicom_folder') - self.last_dicom_folder = self.last_dicom_folder.decode('utf-8') - return True - - except(ConfigParser.NoSectionError, ConfigParser.NoOptionError, - ConfigParser.MissingSectionHeaderError, ConfigParser.ParsingError): - - if (self.RecoveryConfigFile()): - self.ReadSession() - return True - else: - return False - - -class WriteSession(Thread): - - def __init__ (self, session): - Thread.__init__(self) - self.session = session - self.runing = 1 - - def run(self): - while self.runing: - time.sleep(10) - try: - self.Write() - except AttributeError: - debug("Session: trying to write into inexistent file") - - def Stop(self): - self.runing = 0 - - def Write(self): - import utils as utl - - config = ConfigParser.RawConfigParser() - - config.add_section('session') - config.set('session', 'mode', self.session.mode) - config.set('session', 'status', self.session.project_status) - config.set('session','debug', self.session.debug) - config.set('session', 'language', self.session.language) - - config.add_section('project') - config.set('project', 'recent_projects', self.session.recent_projects) - - config.add_section('paths') - config.set('paths','homedir',self.session.homedir) - config.set('paths','tempdir',self.session.tempdir) - config.set('paths','last_dicom_folder', self.session.last_dicom_folder) - - path = os.path.join(self.session.homedir , - '.invesalius', 'config.cfg') - - try: - configfile = open(path, 'wb') - except IOError: - return - utl.debug("Session - IOError") - finally: - self.session.CreateSessionFile() - - configfile.close() - - - - +import ConfigParser +import os +import shutil +import sys +from threading import Thread +import time + +import wx.lib.pubsub as ps + +from utils import Singleton, debug + +class Session(object): + # Only one session will be initialized per time. Therefore, we use + # Singleton design pattern for implementing it + __metaclass__= Singleton + + def __init__(self): + self.temp_item = False + + ws = self.ws = WriteSession(self) + ws.start() + ps.Publisher().subscribe(self.StopRecording, "Stop Config Recording") + + def CreateItens(self): + import constants as const + self.project_path = () + self.debug = False + + self.project_status = const.PROJ_CLOSE + # const.PROJ_NEW*, const.PROJ_OPEN, const.PROJ_CHANGE*, + # const.PROJ_CLOSE + + self.mode = const.MODE_RP + # const.MODE_RP, const.MODE_NAVIGATOR, const.MODE_RADIOLOGY, + # const.MODE_ODONTOLOGY + + # InVesalius default projects' directory + homedir = self.homedir = os.path.expanduser('~') + tempdir = os.path.join(homedir, ".invesalius", "temp") + if not os.path.isdir(tempdir): + os.makedirs(tempdir) + self.tempdir = tempdir + + # GUI language + self.language = "" # "pt_BR", "es" + + # Recent projects list + self.recent_projects = [(const.SAMPLE_DIR, "Cranium.inv3")] + self.last_dicom_folder = '' + + self.CreateSessionFile() + + def StopRecording(self, pubsub_evt): + self.ws.Stop() + + def SaveConfigFileBackup(self): + path = os.path.join(self.homedir , + '.invesalius', 'config.cfg') + path_dst = os.path.join(self.homedir , + '.invesalius', 'config.backup') + shutil.copy(path, path_dst) + + def RecoveryConfigFile(self): + homedir = self.homedir = os.path.expanduser('~') + try: + path = os.path.join(self.homedir , + '.invesalius', 'config.backup') + path_dst = os.path.join(self.homedir , + '.invesalius', 'config.cfg') + shutil.copy(path, path_dst) + return True + except(IOError): + return False + + + def CloseProject(self): + import constants as const + debug("Session.CloseProject") + self.project_path = () + self.project_status = const.PROJ_CLOSE + #self.mode = const.MODE_RP + self.temp_item = False + + def SaveProject(self, path=()): + import constants as const + debug("Session.SaveProject") + 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): + import constants as const + debug("Session.ChangeProject") + self.project_status = const.PROJ_CHANGE + + def CreateProject(self, filename): + import constants as const + debug("Session.CreateProject") + ps.Publisher().sendMessage('Begin busy cursor') + # Set session info + self.project_path = (self.tempdir, filename) + self.project_status = const.PROJ_NEW + self.temp_item = True + return self.tempdir + + def OpenProject(self, filepath): + import constants as const + debug("Session.OpenProject") + # 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 CreateSessionFile(self): + config = ConfigParser.RawConfigParser() + + config.add_section('session') + config.set('session', 'mode', self.mode) + config.set('session', 'status', self.project_status) + config.set('session','debug', self.debug) + config.set('session', 'language', self.language) + + config.add_section('project') + config.set('project', 'recent_projects', self.recent_projects) + + config.add_section('paths') + config.set('paths','homedir',self.homedir) + config.set('paths','tempdir',self.tempdir) + try: + config.set('paths','last_dicom_folder',self.last_dicom_folder.encode('utf-8')) + except (UnicodeEncodeError, UnicodeDecodeError): + config.set('paths','last_dicom_folder',self.last_dicom_folder) + path = os.path.join(self.homedir , + '.invesalius', 'config.cfg') + + configfile = open(path, 'wb') + config.write(configfile) + configfile.close() + + + def __add_to_list(self, item): + import constants as const + # 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() + + def GetLanguage(self): + return self.language + + def SetLanguage(self, language): + self.language = language + + def GetLastDicomFolder(self): + return self.last_dicom_folder + + def SetLastDicomFolder(self, folder): + self.last_dicom_folder = folder + self.CreateSessionFile() + + def ReadLanguage(self): + config = ConfigParser.ConfigParser() + home_path = os.path.expanduser('~') + path = os.path.join(home_path ,'.invesalius', 'config.cfg') + try: + config.read(path) + self.language = config.get('session','language') + return self.language + except (ConfigParser.NoSectionError, + ConfigParser.NoOptionError, + ConfigParser.MissingSectionHeaderError): + return False + + def ReadSession(self): + config = ConfigParser.ConfigParser() + home_path = os.path.expanduser('~') + path = os.path.join(home_path ,'.invesalius', 'config.cfg') + try: + config.read(path) + self.mode = config.get('session', 'mode') + self.project_status = config.get('session', 'status') + self.debug = config.get('session','debug') + self.language = config.get('session','language') + self.recent_projects = eval(config.get('project','recent_projects')) + self.homedir = config.get('paths','homedir') + self.tempdir = config.get('paths','tempdir') + self.last_dicom_folder = config.get('paths','last_dicom_folder') + self.last_dicom_folder = self.last_dicom_folder.decode('utf-8') + return True + + except(ConfigParser.NoSectionError, ConfigParser.NoOptionError, + ConfigParser.MissingSectionHeaderError, ConfigParser.ParsingError): + + if (self.RecoveryConfigFile()): + self.ReadSession() + return True + else: + return False + + +class WriteSession(Thread): + + def __init__ (self, session): + Thread.__init__(self) + self.session = session + self.runing = 1 + + def run(self): + while self.runing: + time.sleep(10) + try: + self.Write() + except AttributeError: + debug("Session: trying to write into inexistent file") + + def Stop(self): + self.runing = 0 + + def Write(self): + import utils as utl + + config = ConfigParser.RawConfigParser() + + config.add_section('session') + config.set('session', 'mode', self.session.mode) + config.set('session', 'status', self.session.project_status) + config.set('session','debug', self.session.debug) + config.set('session', 'language', self.session.language) + + config.add_section('project') + config.set('project', 'recent_projects', self.session.recent_projects) + + config.add_section('paths') + config.set('paths','homedir',self.session.homedir) + config.set('paths','tempdir',self.session.tempdir) + config.set('paths','last_dicom_folder', self.session.last_dicom_folder) + + path = os.path.join(self.session.homedir , + '.invesalius', 'config.cfg') + + try: + configfile = open(path, 'wb') + except IOError: + return + utl.debug("Session - IOError") + finally: + self.session.CreateSessionFile() + + configfile.close() + + + + -- libgit2 0.21.2