Commit a3104e149d61fe6171e4f1a146804d7c9e41d243
1 parent
57107bf8
Exists in
master
and in
68 other branches
ENH: Setting svn eol-style=native for all py files
Showing
11 changed files
with
788 additions
and
844 deletions
Show diff stats
.gitattributes
| ... | ... | @@ -151,65 +151,6 @@ icons/volume_raycasting.png -text |
| 151 | 151 | icons/volume_raycasting_original.png -text |
| 152 | 152 | icons/zh_TW.bmp -text |
| 153 | 153 | invesalius/.svnignore -text |
| 154 | -invesalius/constants.py -text | |
| 155 | -invesalius/control.py -text | |
| 156 | -invesalius/data/__init__.py -text | |
| 157 | -invesalius/data/cursor_actors.py -text | |
| 158 | -invesalius/data/editor.py -text | |
| 159 | -invesalius/data/imagedata_utils.py -text | |
| 160 | -invesalius/data/mask.py -text | |
| 161 | -invesalius/data/measures.py -text | |
| 162 | -invesalius/data/orientation.py -text | |
| 163 | -invesalius/data/polydata_utils.py -text | |
| 164 | -invesalius/data/slice_.py -text | |
| 165 | -invesalius/data/slice_data.py -text | |
| 166 | -invesalius/data/styles.py -text | |
| 167 | -invesalius/data/surface.py -text | |
| 168 | -invesalius/data/surface_process.py -text | |
| 169 | -invesalius/data/viewer.py -text | |
| 170 | -invesalius/data/viewer_slice.py -text | |
| 171 | -invesalius/data/viewer_volume.py -text | |
| 172 | -invesalius/data/volume.py -text | |
| 173 | -invesalius/data/volume_widgets.py -text | |
| 174 | -invesalius/data/vtk_utils.py -text | |
| 175 | -invesalius/gui/__init__.py -text | |
| 176 | -invesalius/gui/data_notebook.py -text | |
| 177 | -invesalius/gui/default_tasks.py -text | |
| 178 | -invesalius/gui/default_viewers.py -text | |
| 179 | -invesalius/gui/dialogs.py -text | |
| 180 | -invesalius/gui/dicom_preview_panel.py -text | |
| 181 | -invesalius/gui/frame.py -text | |
| 182 | -invesalius/gui/import_panel.py -text | |
| 183 | -invesalius/gui/language_dialog.py -text | |
| 184 | -invesalius/gui/task_exporter.py -text | |
| 185 | -invesalius/gui/task_generic.py -text | |
| 186 | -invesalius/gui/task_importer.py -text | |
| 187 | -invesalius/gui/task_navigator.py -text | |
| 188 | -invesalius/gui/task_slice.py -text | |
| 189 | -invesalius/gui/task_surface.py -text | |
| 190 | -invesalius/gui/task_tools.py -text | |
| 191 | -invesalius/gui/widgets/__init__.py -text | |
| 192 | -invesalius/gui/widgets/clut_raycasting.py -text | |
| 193 | -invesalius/gui/widgets/colourselect.py -text | |
| 194 | -invesalius/gui/widgets/foldpanelbar.py -text | |
| 195 | -invesalius/gui/widgets/gradient.py -text | |
| 196 | -invesalius/gui/widgets/listctrl.py -text | |
| 197 | -invesalius/gui/widgets/platebtn.py -text | |
| 198 | -invesalius/gui/widgets/slice_menu.py -text | |
| 199 | -invesalius/i18n.py -text | |
| 200 | -invesalius/invesalius.py -text | |
| 201 | -invesalius/math_utils.py -text | |
| 202 | -invesalius/presets.py -text | |
| 203 | -invesalius/project.py -text | |
| 204 | -invesalius/reader/__init__.py -text | |
| 205 | -invesalius/reader/analyze_reader.py -text | |
| 206 | -invesalius/reader/dicom.py -text | |
| 207 | -invesalius/reader/dicom_grouper.py -text | |
| 208 | -invesalius/reader/dicom_reader.py -text | |
| 209 | -invesalius/session.py -text | |
| 210 | -invesalius/style.py -text | |
| 211 | -invesalius/utils.py -text | |
| 212 | -invesalius/version.py -text | |
| 213 | 154 | locale/de/LC_MESSAGES/invesalius.mo -text |
| 214 | 155 | locale/el/LC_MESSAGES/invesalius.mo -text |
| 215 | 156 | locale/en/LC_MESSAGES/invesalius.mo -text | ... | ... |
invesalius/data/__init__.py
| 1 | -#-------------------------------------------------------------------------- | |
| 2 | -# Software: InVesalius - Software de Reconstrucao 3D de Imagens Medicas | |
| 3 | -# Copyright: (C) 2001 Centro de Pesquisas Renato Archer | |
| 4 | -# Homepage: http://www.softwarepublico.gov.br | |
| 5 | -# Contact: invesalius@cti.gov.br | |
| 6 | -# License: GNU - GPL 2 (LICENSE.txt/LICENCA.txt) | |
| 7 | -#-------------------------------------------------------------------------- | |
| 8 | -# Este programa e software livre; voce pode redistribui-lo e/ou | |
| 9 | -# modifica-lo sob os termos da Licenca Publica Geral GNU, conforme | |
| 10 | -# publicada pela Free Software Foundation; de acordo com a versao 2 | |
| 11 | -# da Licenca. | |
| 12 | -# | |
| 13 | -# Este programa eh distribuido na expectativa de ser util, mas SEM | |
| 14 | -# QUALQUER GARANTIA; sem mesmo a garantia implicita de | |
| 15 | -# COMERCIALIZACAO ou de ADEQUACAO A QUALQUER PROPOSITO EM | |
| 16 | -# PARTICULAR. Consulte a Licenca Publica Geral GNU para obter mais | |
| 17 | -# detalhes. | |
| 18 | -#-------------------------------------------------------------------------- | |
| 1 | +#-------------------------------------------------------------------------- | |
| 2 | +# Software: InVesalius - Software de Reconstrucao 3D de Imagens Medicas | |
| 3 | +# Copyright: (C) 2001 Centro de Pesquisas Renato Archer | |
| 4 | +# Homepage: http://www.softwarepublico.gov.br | |
| 5 | +# Contact: invesalius@cti.gov.br | |
| 6 | +# License: GNU - GPL 2 (LICENSE.txt/LICENCA.txt) | |
| 7 | +#-------------------------------------------------------------------------- | |
| 8 | +# Este programa e software livre; voce pode redistribui-lo e/ou | |
| 9 | +# modifica-lo sob os termos da Licenca Publica Geral GNU, conforme | |
| 10 | +# publicada pela Free Software Foundation; de acordo com a versao 2 | |
| 11 | +# da Licenca. | |
| 12 | +# | |
| 13 | +# Este programa eh distribuido na expectativa de ser util, mas SEM | |
| 14 | +# QUALQUER GARANTIA; sem mesmo a garantia implicita de | |
| 15 | +# COMERCIALIZACAO ou de ADEQUACAO A QUALQUER PROPOSITO EM | |
| 16 | +# PARTICULAR. Consulte a Licenca Publica Geral GNU para obter mais | |
| 17 | +# detalhes. | |
| 18 | +#-------------------------------------------------------------------------- | ... | ... |
invesalius/data/surface.py
| ... | ... | @@ -235,6 +235,7 @@ class SurfaceManager(): |
| 235 | 235 | mapper = vtk.vtkPolyDataMapper() |
| 236 | 236 | mapper.SetInput(normals.GetOutput()) |
| 237 | 237 | mapper.ScalarVisibilityOff() |
| 238 | + mapper.ImmediateModeRenderingOn() | |
| 238 | 239 | |
| 239 | 240 | actor = vtk.vtkActor() |
| 240 | 241 | actor.SetMapper(mapper) |
| ... | ... | @@ -339,6 +340,7 @@ class SurfaceManager(): |
| 339 | 340 | mapper = vtk.vtkPolyDataMapper() |
| 340 | 341 | mapper.SetInput(stripper.GetOutput()) |
| 341 | 342 | mapper.ScalarVisibilityOff() |
| 343 | + mapper.ImmediateModeRenderingOn() | |
| 342 | 344 | |
| 343 | 345 | # Represent an object (geometry & properties) in the rendered scene |
| 344 | 346 | actor = vtk.vtkActor() |
| ... | ... | @@ -470,6 +472,7 @@ class SurfaceManager(): |
| 470 | 472 | mapper = vtk.vtkPolyDataMapper() |
| 471 | 473 | mapper.SetInput(stripper.GetOutput()) |
| 472 | 474 | mapper.ScalarVisibilityOff() |
| 475 | + mapper.ImmediateModeRendering() | |
| 473 | 476 | |
| 474 | 477 | # Represent an object (geometry & properties) in the rendered scene |
| 475 | 478 | actor = vtk.vtkActor() | ... | ... |
invesalius/data/surface_process.py
| 1 | -import vtk | |
| 2 | -import multiprocessing | |
| 3 | -import tempfile | |
| 4 | - | |
| 5 | -import i18n | |
| 6 | - | |
| 7 | -class SurfaceProcess(multiprocessing.Process): | |
| 8 | - | |
| 9 | - def __init__(self, pipe, filename, mode, min_value, max_value, | |
| 10 | - decimate_reduction, smooth_relaxation_factor, | |
| 11 | - smooth_iterations, language, fill_holes, keep_largest): | |
| 12 | - | |
| 13 | - multiprocessing.Process.__init__(self) | |
| 14 | - self.pipe = pipe | |
| 15 | - self.filename = filename | |
| 16 | - self.mode = mode | |
| 17 | - self.min_value = min_value | |
| 18 | - self.max_value = max_value | |
| 19 | - self.decimate_reduction = decimate_reduction | |
| 20 | - self.smooth_relaxation_factor = smooth_relaxation_factor | |
| 21 | - self.smooth_iterations = smooth_iterations | |
| 22 | - self.language = language | |
| 23 | - self.fill_holes = fill_holes | |
| 24 | - self.keep_largest = keep_largest | |
| 25 | - | |
| 26 | - | |
| 27 | - def run(self): | |
| 28 | - self.CreateSurface() | |
| 29 | - | |
| 30 | - def SendProgress(self, obj, msg): | |
| 31 | - prog = obj.GetProgress() | |
| 32 | - self.pipe.send([prog, msg]) | |
| 33 | - | |
| 34 | - def CreateSurface(self): | |
| 35 | - _ = i18n.InstallLanguage(self.language) | |
| 36 | - | |
| 37 | - reader = vtk.vtkXMLImageDataReader() | |
| 38 | - reader.SetFileName(self.filename) | |
| 39 | - reader.Update() | |
| 40 | - | |
| 41 | - # Flip original vtkImageData | |
| 42 | - flip = vtk.vtkImageFlip() | |
| 43 | - flip.SetInput(reader.GetOutput()) | |
| 44 | - flip.SetFilteredAxis(1) | |
| 45 | - flip.FlipAboutOriginOn() | |
| 46 | - | |
| 47 | - # Create vtkPolyData from vtkImageData | |
| 48 | - if self.mode == "CONTOUR": | |
| 49 | - contour = vtk.vtkContourFilter() | |
| 50 | - contour.SetInput(flip.GetOutput()) | |
| 51 | - contour.SetValue(0, self.min_value) # initial threshold | |
| 52 | - contour.SetValue(1, self.max_value) # final threshold | |
| 53 | - contour.GetOutput().ReleaseDataFlagOn() | |
| 54 | - contour.AddObserver("ProgressEvent", lambda obj,evt: | |
| 55 | - self.SendProgress(obj, _("Generating 3D surface..."))) | |
| 56 | - polydata = contour.GetOutput() | |
| 57 | - else: #mode == "GRAYSCALE": | |
| 58 | - mcubes = vtk.vtkMarchingCubes() | |
| 59 | - mcubes.SetInput(flip.GetOutput()) | |
| 60 | - mcubes.SetValue(0, 255) | |
| 61 | - mcubes.ComputeScalarsOn() | |
| 62 | - mcubes.ComputeGradientsOn() | |
| 63 | - mcubes.ComputeNormalsOn() | |
| 64 | - mcubes.ThresholdBetween(self.min_value, self.max_value) | |
| 65 | - mcubes.GetOutput().ReleaseDataFlagOn() | |
| 66 | - mcubes.AddObserver("ProgressEvent", lambda obj,evt: | |
| 67 | - self.SendProgress(obj, _("Generating 3D surface..."))) | |
| 68 | - polydata = mcubes.GetOutput() | |
| 69 | - | |
| 70 | - if self.decimate_reduction: | |
| 71 | - decimation = vtk.vtkQuadricDecimation() | |
| 72 | - decimation.SetInput(polydata) | |
| 73 | - decimation.SetTargetReduction(self.decimate_reduction) | |
| 74 | - decimation.GetOutput().ReleaseDataFlagOn() | |
| 75 | - decimation.AddObserver("ProgressEvent", lambda obj,evt: | |
| 76 | - self.SendProgress(obj, _("Generating 3D surface..."))) | |
| 77 | - polydata = decimation.GetOutput() | |
| 78 | - | |
| 79 | - if self.smooth_iterations and self.smooth_relaxation_factor: | |
| 80 | - smoother = vtk.vtkSmoothPolyDataFilter() | |
| 81 | - smoother.SetInput(polydata) | |
| 82 | - smoother.SetNumberOfIterations(self.smooth_iterations) | |
| 83 | - smoother.SetFeatureAngle(80) | |
| 84 | - smoother.SetRelaxationFactor(self.smooth_relaxation_factor) | |
| 85 | - smoother.FeatureEdgeSmoothingOn() | |
| 86 | - smoother.BoundarySmoothingOn() | |
| 87 | - smoother.GetOutput().ReleaseDataFlagOn() | |
| 88 | - smoother.AddObserver("ProgressEvent", lambda obj,evt: | |
| 89 | - self.SendProgress(obj, _("Generating 3D surface..."))) | |
| 90 | - polydata = smoother.GetOutput() | |
| 91 | - | |
| 92 | - | |
| 93 | - if self.keep_largest: | |
| 94 | - conn = vtk.vtkPolyDataConnectivityFilter() | |
| 95 | - conn.SetInput(polydata) | |
| 96 | - conn.SetExtractionModeToLargestRegion() | |
| 97 | - conn.AddObserver("ProgressEvent", lambda obj,evt: | |
| 98 | - self.SendProgress(obj, _("Generating 3D surface..."))) | |
| 99 | - polydata = conn.GetOutput() | |
| 100 | - | |
| 101 | - # Filter used to detect and fill holes. Only fill boundary edges holes. | |
| 102 | - #TODO: Hey! This piece of code is the same from | |
| 103 | - # polydata_utils.FillSurfaceHole, we need to review this. | |
| 104 | - if self.fill_holes: | |
| 105 | - filled_polydata = vtk.vtkFillHolesFilter() | |
| 106 | - filled_polydata.SetInput(polydata) | |
| 107 | - filled_polydata.SetHoleSize(300) | |
| 108 | - filled_polydata.AddObserver("ProgressEvent", lambda obj,evt: | |
| 109 | - self.SendProgress(obj, _("Generating 3D surface..."))) | |
| 110 | - polydata = filled_polydata.GetOutput() | |
| 111 | - | |
| 112 | - | |
| 113 | - | |
| 114 | - filename = tempfile.mktemp() | |
| 115 | - writer = vtk.vtkXMLPolyDataWriter() | |
| 116 | - writer.SetInput(polydata) | |
| 117 | - writer.SetFileName(filename) | |
| 118 | - writer.Write() | |
| 119 | - | |
| 120 | - self.pipe.send(None) | |
| 121 | - self.pipe.send(filename) | |
| 1 | +import vtk | |
| 2 | +import multiprocessing | |
| 3 | +import tempfile | |
| 4 | + | |
| 5 | +import i18n | |
| 6 | + | |
| 7 | +class SurfaceProcess(multiprocessing.Process): | |
| 8 | + | |
| 9 | + def __init__(self, pipe, filename, mode, min_value, max_value, | |
| 10 | + decimate_reduction, smooth_relaxation_factor, | |
| 11 | + smooth_iterations, language, fill_holes, keep_largest): | |
| 12 | + | |
| 13 | + multiprocessing.Process.__init__(self) | |
| 14 | + self.pipe = pipe | |
| 15 | + self.filename = filename | |
| 16 | + self.mode = mode | |
| 17 | + self.min_value = min_value | |
| 18 | + self.max_value = max_value | |
| 19 | + self.decimate_reduction = decimate_reduction | |
| 20 | + self.smooth_relaxation_factor = smooth_relaxation_factor | |
| 21 | + self.smooth_iterations = smooth_iterations | |
| 22 | + self.language = language | |
| 23 | + self.fill_holes = fill_holes | |
| 24 | + self.keep_largest = keep_largest | |
| 25 | + | |
| 26 | + | |
| 27 | + def run(self): | |
| 28 | + self.CreateSurface() | |
| 29 | + | |
| 30 | + def SendProgress(self, obj, msg): | |
| 31 | + prog = obj.GetProgress() | |
| 32 | + self.pipe.send([prog, msg]) | |
| 33 | + | |
| 34 | + def CreateSurface(self): | |
| 35 | + _ = i18n.InstallLanguage(self.language) | |
| 36 | + | |
| 37 | + reader = vtk.vtkXMLImageDataReader() | |
| 38 | + reader.SetFileName(self.filename) | |
| 39 | + reader.Update() | |
| 40 | + | |
| 41 | + # Flip original vtkImageData | |
| 42 | + flip = vtk.vtkImageFlip() | |
| 43 | + flip.SetInput(reader.GetOutput()) | |
| 44 | + flip.SetFilteredAxis(1) | |
| 45 | + flip.FlipAboutOriginOn() | |
| 46 | + | |
| 47 | + # Create vtkPolyData from vtkImageData | |
| 48 | + if self.mode == "CONTOUR": | |
| 49 | + contour = vtk.vtkContourFilter() | |
| 50 | + contour.SetInput(flip.GetOutput()) | |
| 51 | + contour.SetValue(0, self.min_value) # initial threshold | |
| 52 | + contour.SetValue(1, self.max_value) # final threshold | |
| 53 | + contour.GetOutput().ReleaseDataFlagOn() | |
| 54 | + contour.AddObserver("ProgressEvent", lambda obj,evt: | |
| 55 | + self.SendProgress(obj, _("Generating 3D surface..."))) | |
| 56 | + polydata = contour.GetOutput() | |
| 57 | + else: #mode == "GRAYSCALE": | |
| 58 | + mcubes = vtk.vtkMarchingCubes() | |
| 59 | + mcubes.SetInput(flip.GetOutput()) | |
| 60 | + mcubes.SetValue(0, 255) | |
| 61 | + mcubes.ComputeScalarsOn() | |
| 62 | + mcubes.ComputeGradientsOn() | |
| 63 | + mcubes.ComputeNormalsOn() | |
| 64 | + mcubes.ThresholdBetween(self.min_value, self.max_value) | |
| 65 | + mcubes.GetOutput().ReleaseDataFlagOn() | |
| 66 | + mcubes.AddObserver("ProgressEvent", lambda obj,evt: | |
| 67 | + self.SendProgress(obj, _("Generating 3D surface..."))) | |
| 68 | + polydata = mcubes.GetOutput() | |
| 69 | + | |
| 70 | + if self.decimate_reduction: | |
| 71 | + decimation = vtk.vtkQuadricDecimation() | |
| 72 | + decimation.SetInput(polydata) | |
| 73 | + decimation.SetTargetReduction(self.decimate_reduction) | |
| 74 | + decimation.GetOutput().ReleaseDataFlagOn() | |
| 75 | + decimation.AddObserver("ProgressEvent", lambda obj,evt: | |
| 76 | + self.SendProgress(obj, _("Generating 3D surface..."))) | |
| 77 | + polydata = decimation.GetOutput() | |
| 78 | + | |
| 79 | + if self.smooth_iterations and self.smooth_relaxation_factor: | |
| 80 | + smoother = vtk.vtkSmoothPolyDataFilter() | |
| 81 | + smoother.SetInput(polydata) | |
| 82 | + smoother.SetNumberOfIterations(self.smooth_iterations) | |
| 83 | + smoother.SetFeatureAngle(80) | |
| 84 | + smoother.SetRelaxationFactor(self.smooth_relaxation_factor) | |
| 85 | + smoother.FeatureEdgeSmoothingOn() | |
| 86 | + smoother.BoundarySmoothingOn() | |
| 87 | + smoother.GetOutput().ReleaseDataFlagOn() | |
| 88 | + smoother.AddObserver("ProgressEvent", lambda obj,evt: | |
| 89 | + self.SendProgress(obj, _("Generating 3D surface..."))) | |
| 90 | + polydata = smoother.GetOutput() | |
| 91 | + | |
| 92 | + | |
| 93 | + if self.keep_largest: | |
| 94 | + conn = vtk.vtkPolyDataConnectivityFilter() | |
| 95 | + conn.SetInput(polydata) | |
| 96 | + conn.SetExtractionModeToLargestRegion() | |
| 97 | + conn.AddObserver("ProgressEvent", lambda obj,evt: | |
| 98 | + self.SendProgress(obj, _("Generating 3D surface..."))) | |
| 99 | + polydata = conn.GetOutput() | |
| 100 | + | |
| 101 | + # Filter used to detect and fill holes. Only fill boundary edges holes. | |
| 102 | + #TODO: Hey! This piece of code is the same from | |
| 103 | + # polydata_utils.FillSurfaceHole, we need to review this. | |
| 104 | + if self.fill_holes: | |
| 105 | + filled_polydata = vtk.vtkFillHolesFilter() | |
| 106 | + filled_polydata.SetInput(polydata) | |
| 107 | + filled_polydata.SetHoleSize(300) | |
| 108 | + filled_polydata.AddObserver("ProgressEvent", lambda obj,evt: | |
| 109 | + self.SendProgress(obj, _("Generating 3D surface..."))) | |
| 110 | + polydata = filled_polydata.GetOutput() | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + filename = tempfile.mktemp() | |
| 115 | + writer = vtk.vtkXMLPolyDataWriter() | |
| 116 | + writer.SetInput(polydata) | |
| 117 | + writer.SetFileName(filename) | |
| 118 | + writer.Write() | |
| 119 | + | |
| 120 | + self.pipe.send(None) | |
| 121 | + self.pipe.send(filename) | ... | ... |
invesalius/data/viewer.py
| 1 | -#-------------------------------------------------------------------------- | |
| 2 | -# Software: InVesalius - Software de Reconstrucao 3D de Imagens Medicas | |
| 3 | -# Copyright: (C) 2001 Centro de Pesquisas Renato Archer | |
| 4 | -# Homepage: http://www.softwarepublico.gov.br | |
| 5 | -# Contact: invesalius@cti.gov.br | |
| 6 | -# License: GNU - GPL 2 (LICENSE.txt/LICENCA.txt) | |
| 7 | -#-------------------------------------------------------------------------- | |
| 8 | -# Este programa e software livre; voce pode redistribui-lo e/ou | |
| 9 | -# modifica-lo sob os termos da Licenca Publica Geral GNU, conforme | |
| 10 | -# publicada pela Free Software Foundation; de acordo com a versao 2 | |
| 11 | -# da Licenca. | |
| 12 | -# | |
| 13 | -# Este programa eh distribuido na expectativa de ser util, mas SEM | |
| 14 | -# QUALQUER GARANTIA; sem mesmo a garantia implicita de | |
| 15 | -# COMERCIALIZACAO ou de ADEQUACAO A QUALQUER PROPOSITO EM | |
| 16 | -# PARTICULAR. Consulte a Licenca Publica Geral GNU para obter mais | |
| 17 | -# detalhes. | |
| 18 | -#-------------------------------------------------------------------------- | |
| 1 | +#-------------------------------------------------------------------------- | |
| 2 | +# Software: InVesalius - Software de Reconstrucao 3D de Imagens Medicas | |
| 3 | +# Copyright: (C) 2001 Centro de Pesquisas Renato Archer | |
| 4 | +# Homepage: http://www.softwarepublico.gov.br | |
| 5 | +# Contact: invesalius@cti.gov.br | |
| 6 | +# License: GNU - GPL 2 (LICENSE.txt/LICENCA.txt) | |
| 7 | +#-------------------------------------------------------------------------- | |
| 8 | +# Este programa e software livre; voce pode redistribui-lo e/ou | |
| 9 | +# modifica-lo sob os termos da Licenca Publica Geral GNU, conforme | |
| 10 | +# publicada pela Free Software Foundation; de acordo com a versao 2 | |
| 11 | +# da Licenca. | |
| 12 | +# | |
| 13 | +# Este programa eh distribuido na expectativa de ser util, mas SEM | |
| 14 | +# QUALQUER GARANTIA; sem mesmo a garantia implicita de | |
| 15 | +# COMERCIALIZACAO ou de ADEQUACAO A QUALQUER PROPOSITO EM | |
| 16 | +# PARTICULAR. Consulte a Licenca Publica Geral GNU para obter mais | |
| 17 | +# detalhes. | |
| 18 | +#-------------------------------------------------------------------------- | ... | ... |
invesalius/gui/__init__.py
| 1 | -#-------------------------------------------------------------------------- | |
| 2 | -# Software: InVesalius - Software de Reconstrucao 3D de Imagens Medicas | |
| 3 | -# Copyright: (C) 2001 Centro de Pesquisas Renato Archer | |
| 4 | -# Homepage: http://www.softwarepublico.gov.br | |
| 5 | -# Contact: invesalius@cti.gov.br | |
| 6 | -# License: GNU - GPL 2 (LICENSE.txt/LICENCA.txt) | |
| 7 | -#-------------------------------------------------------------------------- | |
| 8 | -# Este programa e software livre; voce pode redistribui-lo e/ou | |
| 9 | -# modifica-lo sob os termos da Licenca Publica Geral GNU, conforme | |
| 10 | -# publicada pela Free Software Foundation; de acordo com a versao 2 | |
| 11 | -# da Licenca. | |
| 12 | -# | |
| 13 | -# Este programa eh distribuido na expectativa de ser util, mas SEM | |
| 14 | -# QUALQUER GARANTIA; sem mesmo a garantia implicita de | |
| 15 | -# COMERCIALIZACAO ou de ADEQUACAO A QUALQUER PROPOSITO EM | |
| 16 | -# PARTICULAR. Consulte a Licenca Publica Geral GNU para obter mais | |
| 17 | -# detalhes. | |
| 18 | -#-------------------------------------------------------------------------- | |
| 1 | +#-------------------------------------------------------------------------- | |
| 2 | +# Software: InVesalius - Software de Reconstrucao 3D de Imagens Medicas | |
| 3 | +# Copyright: (C) 2001 Centro de Pesquisas Renato Archer | |
| 4 | +# Homepage: http://www.softwarepublico.gov.br | |
| 5 | +# Contact: invesalius@cti.gov.br | |
| 6 | +# License: GNU - GPL 2 (LICENSE.txt/LICENCA.txt) | |
| 7 | +#-------------------------------------------------------------------------- | |
| 8 | +# Este programa e software livre; voce pode redistribui-lo e/ou | |
| 9 | +# modifica-lo sob os termos da Licenca Publica Geral GNU, conforme | |
| 10 | +# publicada pela Free Software Foundation; de acordo com a versao 2 | |
| 11 | +# da Licenca. | |
| 12 | +# | |
| 13 | +# Este programa eh distribuido na expectativa de ser util, mas SEM | |
| 14 | +# QUALQUER GARANTIA; sem mesmo a garantia implicita de | |
| 15 | +# COMERCIALIZACAO ou de ADEQUACAO A QUALQUER PROPOSITO EM | |
| 16 | +# PARTICULAR. Consulte a Licenca Publica Geral GNU para obter mais | |
| 17 | +# detalhes. | |
| 18 | +#-------------------------------------------------------------------------- | ... | ... |
invesalius/gui/language_dialog.py
| 1 | -#-------------------------------------------------------------------------- | |
| 2 | -# Software: InVesalius - Software de Reconstrucao 3D de Imagens Medicas | |
| 3 | -# Copyright: (C) 2001 Centro de Pesquisas Renato Archer | |
| 4 | -# Homepage: http://www.softwarepublico.gov.br | |
| 5 | -# Contact: invesalius@cti.gov.br | |
| 6 | -# License: GNU - GPL 2 (LICENSE.txt/LICENCA.txt) | |
| 7 | -#-------------------------------------------------------------------------- | |
| 8 | -# Este programa e software livre; voce pode redistribui-lo e/ou | |
| 9 | -# modifica-lo sob os termos da Licenca Publica Geral GNU, conforme | |
| 10 | -# publicada pela Free Software Foundation; de acordo com a versao 2 | |
| 11 | -# da Licenca. | |
| 12 | -# | |
| 13 | -# Este programa eh distribuido na expectativa de ser util, mas SEM | |
| 14 | -# QUALQUER GARANTIA; sem mesmo a garantia implicita de | |
| 15 | -# COMERCIALIZACAO ou de ADEQUACAO A QUALQUER PROPOSITO EM | |
| 16 | -# PARTICULAR. Consulte a Licenca Publica Geral GNU para obter mais | |
| 17 | -# detalhes. | |
| 18 | -#-------------------------------------------------------------------------- | |
| 19 | - | |
| 20 | -import os | |
| 21 | -import wx | |
| 22 | -import wx.combo | |
| 23 | - | |
| 24 | -import i18n | |
| 25 | - | |
| 26 | -ICON_DIR = os.path.abspath(os.path.join('..', 'icons')) | |
| 27 | - | |
| 28 | -class LanguageDialog(wx.Dialog): | |
| 29 | - """Class define the language to be used in the InVesalius, | |
| 30 | - exist chcLanguage that list language EN and PT. The language | |
| 31 | - selected is writing in the config.ini""" | |
| 32 | - | |
| 33 | - def __init__(self, parent=None, startApp=None): | |
| 34 | - super(LanguageDialog, self).__init__(parent, title="") | |
| 35 | - self.__TranslateMessage__() | |
| 36 | - self.SetTitle(_('Language selection')) | |
| 37 | - self.__init_gui() | |
| 38 | - self.Centre() | |
| 39 | - | |
| 40 | - def __init_combobox_bitmap__(self): | |
| 41 | - """Initialize combobox bitmap""" | |
| 42 | - | |
| 43 | - # Retrieve locales dictionary | |
| 44 | - dict_locales = i18n.GetLocales() | |
| 45 | - | |
| 46 | - # Retrieve locales names and sort them | |
| 47 | - self.locales = dict_locales.values() | |
| 48 | - self.locales.sort() | |
| 49 | - | |
| 50 | - # Retrieve locales keys (eg: pt_BR for Portuguese(Brazilian)) | |
| 51 | - self.locales_key = [dict_locales.get_key(value)[0] for value in self.locales] | |
| 52 | - | |
| 53 | - # Find out OS locale | |
| 54 | - self.os_locale = i18n.GetLocaleOS() | |
| 55 | - | |
| 56 | - # FIXME: In future we shall be using all locales using 5 | |
| 57 | - # characters... until then, we use only 2: | |
| 58 | - os_lang = self.os_locale[0:2] | |
| 59 | - | |
| 60 | - # Default selection will be English | |
| 61 | - selection = self.locales_key.index('en') | |
| 62 | - | |
| 63 | - # Create bitmap combo | |
| 64 | - self.bitmapCmb = bitmapCmb = wx.combo.BitmapComboBox(self, style=wx.CB_READONLY) | |
| 65 | - for key in self.locales_key: | |
| 66 | - # Based on composed flag filename, get bitmap | |
| 67 | - filepath = os.path.join(ICON_DIR, "%s.bmp"%(key)) | |
| 68 | - bmp = wx.Bitmap(filepath, wx.BITMAP_TYPE_BMP) | |
| 69 | - # Add bitmap and info to Combo | |
| 70 | - bitmapCmb.Append(dict_locales[key], bmp, key) | |
| 71 | - # Set default combo item if available on the list | |
| 72 | - if key.startswith(os_lang): | |
| 73 | - selection = self.locales_key.index(key) | |
| 74 | - bitmapCmb.SetSelection(selection) | |
| 75 | - | |
| 76 | - | |
| 77 | - def __init_gui(self): | |
| 78 | - self.txtMsg = wx.StaticText(self, -1, | |
| 79 | - label=_('Choose user interface language')) | |
| 80 | - | |
| 81 | - btnsizer = wx.StdDialogButtonSizer() | |
| 82 | - | |
| 83 | - btn = wx.Button(self, wx.ID_OK) | |
| 84 | - btn.SetDefault() | |
| 85 | - btnsizer.AddButton(btn) | |
| 86 | - | |
| 87 | - btn = wx.Button(self, wx.ID_CANCEL) | |
| 88 | - btnsizer.AddButton(btn) | |
| 89 | - btnsizer.Realize() | |
| 90 | - | |
| 91 | - self.__init_combobox_bitmap__() | |
| 92 | - | |
| 93 | - sizer = wx.BoxSizer(wx.VERTICAL) | |
| 94 | - sizer.Add(self.txtMsg, 0, wx.EXPAND | wx.ALL, 5) | |
| 95 | - sizer.Add(self.bitmapCmb, 0, wx.EXPAND | wx.ALL, 5) | |
| 96 | - sizer.Add(btnsizer, 0, wx.EXPAND | wx.ALL, 5) | |
| 97 | - | |
| 98 | - sizer.Fit(self) | |
| 99 | - self.SetSizer(sizer) | |
| 100 | - self.Layout() | |
| 101 | - self.Update() | |
| 102 | - self.SetAutoLayout(1) | |
| 103 | - | |
| 104 | - def GetSelectedLanguage(self): | |
| 105 | - """Return String with Selected Language""" | |
| 106 | - return self.locales_key[self.bitmapCmb.GetSelection()] | |
| 107 | - | |
| 108 | - def __TranslateMessage__(self): | |
| 109 | - """Translate Messages of the Window""" | |
| 110 | - os_language = i18n.GetLocaleOS() | |
| 111 | - | |
| 112 | - if(os_language[0:2] == 'pt'): | |
| 113 | - _ = i18n.InstallLanguage('pt_BR') | |
| 114 | - elif(os_language[0:2] == 'es'): | |
| 115 | - _ = i18n.InstallLanguage('es') | |
| 116 | - else: | |
| 117 | - _ = i18n.InstallLanguage('en') | |
| 118 | - | |
| 119 | - def Cancel(self, event): | |
| 120 | - """Close Frm_Language""" | |
| 121 | - self.Close() | |
| 122 | - event.Skip() | |
| 1 | +#-------------------------------------------------------------------------- | |
| 2 | +# Software: InVesalius - Software de Reconstrucao 3D de Imagens Medicas | |
| 3 | +# Copyright: (C) 2001 Centro de Pesquisas Renato Archer | |
| 4 | +# Homepage: http://www.softwarepublico.gov.br | |
| 5 | +# Contact: invesalius@cti.gov.br | |
| 6 | +# License: GNU - GPL 2 (LICENSE.txt/LICENCA.txt) | |
| 7 | +#-------------------------------------------------------------------------- | |
| 8 | +# Este programa e software livre; voce pode redistribui-lo e/ou | |
| 9 | +# modifica-lo sob os termos da Licenca Publica Geral GNU, conforme | |
| 10 | +# publicada pela Free Software Foundation; de acordo com a versao 2 | |
| 11 | +# da Licenca. | |
| 12 | +# | |
| 13 | +# Este programa eh distribuido na expectativa de ser util, mas SEM | |
| 14 | +# QUALQUER GARANTIA; sem mesmo a garantia implicita de | |
| 15 | +# COMERCIALIZACAO ou de ADEQUACAO A QUALQUER PROPOSITO EM | |
| 16 | +# PARTICULAR. Consulte a Licenca Publica Geral GNU para obter mais | |
| 17 | +# detalhes. | |
| 18 | +#-------------------------------------------------------------------------- | |
| 19 | + | |
| 20 | +import os | |
| 21 | +import wx | |
| 22 | +import wx.combo | |
| 23 | + | |
| 24 | +import i18n | |
| 25 | + | |
| 26 | +ICON_DIR = os.path.abspath(os.path.join('..', 'icons')) | |
| 27 | + | |
| 28 | +class LanguageDialog(wx.Dialog): | |
| 29 | + """Class define the language to be used in the InVesalius, | |
| 30 | + exist chcLanguage that list language EN and PT. The language | |
| 31 | + selected is writing in the config.ini""" | |
| 32 | + | |
| 33 | + def __init__(self, parent=None, startApp=None): | |
| 34 | + super(LanguageDialog, self).__init__(parent, title="") | |
| 35 | + self.__TranslateMessage__() | |
| 36 | + self.SetTitle(_('Language selection')) | |
| 37 | + self.__init_gui() | |
| 38 | + self.Centre() | |
| 39 | + | |
| 40 | + def __init_combobox_bitmap__(self): | |
| 41 | + """Initialize combobox bitmap""" | |
| 42 | + | |
| 43 | + # Retrieve locales dictionary | |
| 44 | + dict_locales = i18n.GetLocales() | |
| 45 | + | |
| 46 | + # Retrieve locales names and sort them | |
| 47 | + self.locales = dict_locales.values() | |
| 48 | + self.locales.sort() | |
| 49 | + | |
| 50 | + # Retrieve locales keys (eg: pt_BR for Portuguese(Brazilian)) | |
| 51 | + self.locales_key = [dict_locales.get_key(value)[0] for value in self.locales] | |
| 52 | + | |
| 53 | + # Find out OS locale | |
| 54 | + self.os_locale = i18n.GetLocaleOS() | |
| 55 | + | |
| 56 | + # FIXME: In future we shall be using all locales using 5 | |
| 57 | + # characters... until then, we use only 2: | |
| 58 | + os_lang = self.os_locale[0:2] | |
| 59 | + | |
| 60 | + # Default selection will be English | |
| 61 | + selection = self.locales_key.index('en') | |
| 62 | + | |
| 63 | + # Create bitmap combo | |
| 64 | + self.bitmapCmb = bitmapCmb = wx.combo.BitmapComboBox(self, style=wx.CB_READONLY) | |
| 65 | + for key in self.locales_key: | |
| 66 | + # Based on composed flag filename, get bitmap | |
| 67 | + filepath = os.path.join(ICON_DIR, "%s.bmp"%(key)) | |
| 68 | + bmp = wx.Bitmap(filepath, wx.BITMAP_TYPE_BMP) | |
| 69 | + # Add bitmap and info to Combo | |
| 70 | + bitmapCmb.Append(dict_locales[key], bmp, key) | |
| 71 | + # Set default combo item if available on the list | |
| 72 | + if key.startswith(os_lang): | |
| 73 | + selection = self.locales_key.index(key) | |
| 74 | + bitmapCmb.SetSelection(selection) | |
| 75 | + | |
| 76 | + | |
| 77 | + def __init_gui(self): | |
| 78 | + self.txtMsg = wx.StaticText(self, -1, | |
| 79 | + label=_('Choose user interface language')) | |
| 80 | + | |
| 81 | + btnsizer = wx.StdDialogButtonSizer() | |
| 82 | + | |
| 83 | + btn = wx.Button(self, wx.ID_OK) | |
| 84 | + btn.SetDefault() | |
| 85 | + btnsizer.AddButton(btn) | |
| 86 | + | |
| 87 | + btn = wx.Button(self, wx.ID_CANCEL) | |
| 88 | + btnsizer.AddButton(btn) | |
| 89 | + btnsizer.Realize() | |
| 90 | + | |
| 91 | + self.__init_combobox_bitmap__() | |
| 92 | + | |
| 93 | + sizer = wx.BoxSizer(wx.VERTICAL) | |
| 94 | + sizer.Add(self.txtMsg, 0, wx.EXPAND | wx.ALL, 5) | |
| 95 | + sizer.Add(self.bitmapCmb, 0, wx.EXPAND | wx.ALL, 5) | |
| 96 | + sizer.Add(btnsizer, 0, wx.EXPAND | wx.ALL, 5) | |
| 97 | + | |
| 98 | + sizer.Fit(self) | |
| 99 | + self.SetSizer(sizer) | |
| 100 | + self.Layout() | |
| 101 | + self.Update() | |
| 102 | + self.SetAutoLayout(1) | |
| 103 | + | |
| 104 | + def GetSelectedLanguage(self): | |
| 105 | + """Return String with Selected Language""" | |
| 106 | + return self.locales_key[self.bitmapCmb.GetSelection()] | |
| 107 | + | |
| 108 | + def __TranslateMessage__(self): | |
| 109 | + """Translate Messages of the Window""" | |
| 110 | + os_language = i18n.GetLocaleOS() | |
| 111 | + | |
| 112 | + if(os_language[0:2] == 'pt'): | |
| 113 | + _ = i18n.InstallLanguage('pt_BR') | |
| 114 | + elif(os_language[0:2] == 'es'): | |
| 115 | + _ = i18n.InstallLanguage('es') | |
| 116 | + else: | |
| 117 | + _ = i18n.InstallLanguage('en') | |
| 118 | + | |
| 119 | + def Cancel(self, event): | |
| 120 | + """Close Frm_Language""" | |
| 121 | + self.Close() | |
| 122 | + event.Skip() | ... | ... |
invesalius/gui/widgets/__init__.py
| 1 | -#-------------------------------------------------------------------------- | |
| 2 | -# Software: InVesalius - Software de Reconstrucao 3D de Imagens Medicas | |
| 3 | -# Copyright: (C) 2001 Centro de Pesquisas Renato Archer | |
| 4 | -# Homepage: http://www.softwarepublico.gov.br | |
| 5 | -# Contact: invesalius@cti.gov.br | |
| 6 | -# License: GNU - GPL 2 (LICENSE.txt/LICENCA.txt) | |
| 7 | -#-------------------------------------------------------------------------- | |
| 8 | -# Este programa e software livre; voce pode redistribui-lo e/ou | |
| 9 | -# modifica-lo sob os termos da Licenca Publica Geral GNU, conforme | |
| 10 | -# publicada pela Free Software Foundation; de acordo com a versao 2 | |
| 11 | -# da Licenca. | |
| 12 | -# | |
| 13 | -# Este programa eh distribuido na expectativa de ser util, mas SEM | |
| 14 | -# QUALQUER GARANTIA; sem mesmo a garantia implicita de | |
| 15 | -# COMERCIALIZACAO ou de ADEQUACAO A QUALQUER PROPOSITO EM | |
| 16 | -# PARTICULAR. Consulte a Licenca Publica Geral GNU para obter mais | |
| 17 | -# detalhes. | |
| 18 | -#-------------------------------------------------------------------------- | |
| 1 | +#-------------------------------------------------------------------------- | |
| 2 | +# Software: InVesalius - Software de Reconstrucao 3D de Imagens Medicas | |
| 3 | +# Copyright: (C) 2001 Centro de Pesquisas Renato Archer | |
| 4 | +# Homepage: http://www.softwarepublico.gov.br | |
| 5 | +# Contact: invesalius@cti.gov.br | |
| 6 | +# License: GNU - GPL 2 (LICENSE.txt/LICENCA.txt) | |
| 7 | +#-------------------------------------------------------------------------- | |
| 8 | +# Este programa e software livre; voce pode redistribui-lo e/ou | |
| 9 | +# modifica-lo sob os termos da Licenca Publica Geral GNU, conforme | |
| 10 | +# publicada pela Free Software Foundation; de acordo com a versao 2 | |
| 11 | +# da Licenca. | |
| 12 | +# | |
| 13 | +# Este programa eh distribuido na expectativa de ser util, mas SEM | |
| 14 | +# QUALQUER GARANTIA; sem mesmo a garantia implicita de | |
| 15 | +# COMERCIALIZACAO ou de ADEQUACAO A QUALQUER PROPOSITO EM | |
| 16 | +# PARTICULAR. Consulte a Licenca Publica Geral GNU para obter mais | |
| 17 | +# detalhes. | |
| 18 | +#-------------------------------------------------------------------------- | ... | ... |
invesalius/gui/widgets/colourselect.py
| 1 | -#---------------------------------------------------------------------------- | |
| 2 | -# Name: ColourSelect.py | |
| 3 | -# Purpose: Colour Box Selection Control | |
| 4 | -# | |
| 5 | -# Author: Lorne White, Lorne.White@telusplanet.net | |
| 6 | -# | |
| 7 | -# Created: Feb 25, 2001 | |
| 8 | -# Licence: wxWindows license | |
| 9 | -#---------------------------------------------------------------------------- | |
| 10 | - | |
| 11 | -# creates a colour wxButton with selectable color | |
| 12 | -# button click provides a colour selection box | |
| 13 | -# button colour will change to new colour | |
| 14 | -# GetColour method to get the selected colour | |
| 15 | - | |
| 16 | -# Updates: | |
| 17 | -# call back to function if changes made | |
| 18 | - | |
| 19 | -# Cliff Wells, logiplexsoftware@earthlink.net: | |
| 20 | -# - Made ColourSelect into "is a button" rather than "has a button" | |
| 21 | -# - Added label parameter and logic to adjust the label colour according to the background | |
| 22 | -# colour | |
| 23 | -# - Added id argument | |
| 24 | -# - Rearranged arguments to more closely follow wx conventions | |
| 25 | -# - Simplified some of the code | |
| 26 | - | |
| 27 | -# Cliff Wells, 2002/02/07 | |
| 28 | -# - Added ColourSelect Event | |
| 29 | - | |
| 30 | -# 12/01/2003 - Jeff Grimmett (grimmtooth@softhome.net) | |
| 31 | -# | |
| 32 | -# o Updated for 2.5 compatability. | |
| 33 | -# | |
| 34 | - | |
| 35 | -""" | |
| 36 | -Provides a `ColourSelect` button that, when clicked, will display a | |
| 37 | -colour selection dialog. The selected colour is displayed on the | |
| 38 | -button itself. | |
| 39 | -""" | |
| 40 | - | |
| 41 | -#---------------------------------------------------------------------------- | |
| 42 | - | |
| 43 | -import wx | |
| 44 | - | |
| 45 | -#---------------------------------------------------------------------------- | |
| 46 | - | |
| 47 | -wxEVT_COMMAND_COLOURSELECT = wx.NewEventType() | |
| 48 | - | |
| 49 | -class ColourSelectEvent(wx.PyCommandEvent): | |
| 50 | - def __init__(self, id, value): | |
| 51 | - wx.PyCommandEvent.__init__(self, id = id) | |
| 52 | - self.SetEventType(wxEVT_COMMAND_COLOURSELECT) | |
| 53 | - self.value = value | |
| 54 | - | |
| 55 | - def GetValue(self): | |
| 56 | - return self.value | |
| 57 | - | |
| 58 | -EVT_COLOURSELECT = wx.PyEventBinder(wxEVT_COMMAND_COLOURSELECT, 1) | |
| 59 | - | |
| 60 | -#---------------------------------------------------------------------------- | |
| 61 | - | |
| 62 | -class ColourSelect(wx.BitmapButton): | |
| 63 | - def __init__(self, parent, id=wx.ID_ANY, label="", colour=wx.BLACK, | |
| 64 | - pos=wx.DefaultPosition, size=wx.DefaultSize, | |
| 65 | - callback=None, style=0): | |
| 66 | - if label: | |
| 67 | - w, h = parent.GetTextExtent(label) | |
| 68 | - w += 6 | |
| 69 | - h += 6 | |
| 70 | - else: | |
| 71 | - w, h = 20, 20 | |
| 72 | - wx.BitmapButton.__init__(self, parent, id, wx.EmptyBitmap(w,h), | |
| 73 | - pos=pos, size=size, style=style|wx.BU_AUTODRAW) | |
| 74 | - | |
| 75 | - if type(colour) == type( () ): | |
| 76 | - colour = wx.Colour(*colour) | |
| 77 | - self.colour = colour | |
| 78 | - self.SetLabel(label) | |
| 79 | - self.callback = callback | |
| 80 | - bmp = self.MakeBitmap() | |
| 81 | - self.SetBitmap(bmp) | |
| 82 | - parent.Bind(wx.EVT_BUTTON, self.OnClick, self) | |
| 83 | - | |
| 84 | - | |
| 85 | - def GetColour(self): | |
| 86 | - return self.colour | |
| 87 | - | |
| 88 | - def GetValue(self): | |
| 89 | - return self.colour | |
| 90 | - | |
| 91 | - def SetValue(self, colour): | |
| 92 | - self.SetColour(colour) | |
| 93 | - | |
| 94 | - def SetColour(self, colour): | |
| 95 | - if type(colour) == tuple: | |
| 96 | - colour = wx.Colour(*colour) | |
| 97 | - if type(colour) == str: | |
| 98 | - colour = wx.NamedColour(colour) | |
| 99 | - | |
| 100 | - self.colour = colour | |
| 101 | - bmp = self.MakeBitmap() | |
| 102 | - self.SetBitmap(bmp) | |
| 103 | - | |
| 104 | - | |
| 105 | - def SetLabel(self, label): | |
| 106 | - self.label = label | |
| 107 | - | |
| 108 | - def GetLabel(self): | |
| 109 | - return self.label | |
| 110 | - | |
| 111 | - | |
| 112 | - def MakeBitmap(self): | |
| 113 | - bdr = 8 | |
| 114 | - width, height = self.GetSize() | |
| 115 | - | |
| 116 | - # yes, this is weird, but it appears to work around a bug in wxMac | |
| 117 | - if "wxMac" in wx.PlatformInfo and width == height: | |
| 118 | - height -= 1 | |
| 119 | - | |
| 120 | - bmp = wx.EmptyBitmap(width-bdr, height-bdr) | |
| 121 | - dc = wx.MemoryDC() | |
| 122 | - dc.SelectObject(bmp) | |
| 123 | - dc.SetFont(self.GetFont()) | |
| 124 | - label = self.GetLabel() | |
| 125 | - # Just make a little colored bitmap | |
| 126 | - dc.SetBackground(wx.Brush(self.colour)) | |
| 127 | - dc.Clear() | |
| 128 | - | |
| 129 | - if label: | |
| 130 | - # Add a label to it | |
| 131 | - avg = reduce(lambda a, b: a + b, self.colour.Get()) / 3 | |
| 132 | - fcolour = avg > 128 and wx.BLACK or wx.WHITE | |
| 133 | - dc.SetTextForeground(fcolour) | |
| 134 | - dc.DrawLabel(label, (0,0, width-bdr, height-bdr), | |
| 135 | - wx.ALIGN_CENTER) | |
| 136 | - | |
| 137 | - dc.SelectObject(wx.NullBitmap) | |
| 138 | - return bmp | |
| 139 | - | |
| 140 | - | |
| 141 | - def SetBitmap(self, bmp): | |
| 142 | - self.SetBitmapLabel(bmp) | |
| 143 | - #self.SetBitmapSelected(bmp) | |
| 144 | - #self.SetBitmapDisabled(bmp) | |
| 145 | - #self.SetBitmapFocus(bmp) | |
| 146 | - #self.SetBitmapSelected(bmp) | |
| 147 | - self.Refresh() | |
| 148 | - | |
| 149 | - | |
| 150 | - def OnChange(self): | |
| 151 | - evt = ColourSelectEvent(self.GetId(), self.GetValue()) | |
| 152 | - evt.SetEventObject(self) | |
| 153 | - wx.PostEvent(self, evt) | |
| 154 | - if self.callback is not None: | |
| 155 | - self.callback() | |
| 156 | - | |
| 157 | - def OnClick(self, event): | |
| 158 | - data = wx.ColourData() | |
| 159 | - data.SetChooseFull(True) | |
| 160 | - data.SetColour(self.colour) | |
| 161 | - dlg = wx.ColourDialog(wx.GetTopLevelParent(self), data) | |
| 162 | - | |
| 163 | - try: | |
| 164 | - changed = dlg.ShowModal() == wx.ID_OK | |
| 165 | - except(wx._core.PyAssertionError): | |
| 166 | - changed = True | |
| 167 | - | |
| 168 | - if changed: | |
| 169 | - data = dlg.GetColourData() | |
| 170 | - self.SetColour(data.GetColour()) | |
| 171 | - dlg.Destroy() | |
| 172 | - | |
| 173 | - # moved after dlg.Destroy, since who knows what the callback will do... | |
| 174 | - if changed: | |
| 175 | - self.OnChange() | |
| 176 | - | |
| 1 | +#---------------------------------------------------------------------------- | |
| 2 | +# Name: ColourSelect.py | |
| 3 | +# Purpose: Colour Box Selection Control | |
| 4 | +# | |
| 5 | +# Author: Lorne White, Lorne.White@telusplanet.net | |
| 6 | +# | |
| 7 | +# Created: Feb 25, 2001 | |
| 8 | +# Licence: wxWindows license | |
| 9 | +#---------------------------------------------------------------------------- | |
| 10 | + | |
| 11 | +# creates a colour wxButton with selectable color | |
| 12 | +# button click provides a colour selection box | |
| 13 | +# button colour will change to new colour | |
| 14 | +# GetColour method to get the selected colour | |
| 15 | + | |
| 16 | +# Updates: | |
| 17 | +# call back to function if changes made | |
| 18 | + | |
| 19 | +# Cliff Wells, logiplexsoftware@earthlink.net: | |
| 20 | +# - Made ColourSelect into "is a button" rather than "has a button" | |
| 21 | +# - Added label parameter and logic to adjust the label colour according to the background | |
| 22 | +# colour | |
| 23 | +# - Added id argument | |
| 24 | +# - Rearranged arguments to more closely follow wx conventions | |
| 25 | +# - Simplified some of the code | |
| 26 | + | |
| 27 | +# Cliff Wells, 2002/02/07 | |
| 28 | +# - Added ColourSelect Event | |
| 29 | + | |
| 30 | +# 12/01/2003 - Jeff Grimmett (grimmtooth@softhome.net) | |
| 31 | +# | |
| 32 | +# o Updated for 2.5 compatability. | |
| 33 | +# | |
| 34 | + | |
| 35 | +""" | |
| 36 | +Provides a `ColourSelect` button that, when clicked, will display a | |
| 37 | +colour selection dialog. The selected colour is displayed on the | |
| 38 | +button itself. | |
| 39 | +""" | |
| 40 | + | |
| 41 | +#---------------------------------------------------------------------------- | |
| 42 | + | |
| 43 | +import wx | |
| 44 | + | |
| 45 | +#---------------------------------------------------------------------------- | |
| 46 | + | |
| 47 | +wxEVT_COMMAND_COLOURSELECT = wx.NewEventType() | |
| 48 | + | |
| 49 | +class ColourSelectEvent(wx.PyCommandEvent): | |
| 50 | + def __init__(self, id, value): | |
| 51 | + wx.PyCommandEvent.__init__(self, id = id) | |
| 52 | + self.SetEventType(wxEVT_COMMAND_COLOURSELECT) | |
| 53 | + self.value = value | |
| 54 | + | |
| 55 | + def GetValue(self): | |
| 56 | + return self.value | |
| 57 | + | |
| 58 | +EVT_COLOURSELECT = wx.PyEventBinder(wxEVT_COMMAND_COLOURSELECT, 1) | |
| 59 | + | |
| 60 | +#---------------------------------------------------------------------------- | |
| 61 | + | |
| 62 | +class ColourSelect(wx.BitmapButton): | |
| 63 | + def __init__(self, parent, id=wx.ID_ANY, label="", colour=wx.BLACK, | |
| 64 | + pos=wx.DefaultPosition, size=wx.DefaultSize, | |
| 65 | + callback=None, style=0): | |
| 66 | + if label: | |
| 67 | + w, h = parent.GetTextExtent(label) | |
| 68 | + w += 6 | |
| 69 | + h += 6 | |
| 70 | + else: | |
| 71 | + w, h = 20, 20 | |
| 72 | + wx.BitmapButton.__init__(self, parent, id, wx.EmptyBitmap(w,h), | |
| 73 | + pos=pos, size=size, style=style|wx.BU_AUTODRAW) | |
| 74 | + | |
| 75 | + if type(colour) == type( () ): | |
| 76 | + colour = wx.Colour(*colour) | |
| 77 | + self.colour = colour | |
| 78 | + self.SetLabel(label) | |
| 79 | + self.callback = callback | |
| 80 | + bmp = self.MakeBitmap() | |
| 81 | + self.SetBitmap(bmp) | |
| 82 | + parent.Bind(wx.EVT_BUTTON, self.OnClick, self) | |
| 83 | + | |
| 84 | + | |
| 85 | + def GetColour(self): | |
| 86 | + return self.colour | |
| 87 | + | |
| 88 | + def GetValue(self): | |
| 89 | + return self.colour | |
| 90 | + | |
| 91 | + def SetValue(self, colour): | |
| 92 | + self.SetColour(colour) | |
| 93 | + | |
| 94 | + def SetColour(self, colour): | |
| 95 | + if type(colour) == tuple: | |
| 96 | + colour = wx.Colour(*colour) | |
| 97 | + if type(colour) == str: | |
| 98 | + colour = wx.NamedColour(colour) | |
| 99 | + | |
| 100 | + self.colour = colour | |
| 101 | + bmp = self.MakeBitmap() | |
| 102 | + self.SetBitmap(bmp) | |
| 103 | + | |
| 104 | + | |
| 105 | + def SetLabel(self, label): | |
| 106 | + self.label = label | |
| 107 | + | |
| 108 | + def GetLabel(self): | |
| 109 | + return self.label | |
| 110 | + | |
| 111 | + | |
| 112 | + def MakeBitmap(self): | |
| 113 | + bdr = 8 | |
| 114 | + width, height = self.GetSize() | |
| 115 | + | |
| 116 | + # yes, this is weird, but it appears to work around a bug in wxMac | |
| 117 | + if "wxMac" in wx.PlatformInfo and width == height: | |
| 118 | + height -= 1 | |
| 119 | + | |
| 120 | + bmp = wx.EmptyBitmap(width-bdr, height-bdr) | |
| 121 | + dc = wx.MemoryDC() | |
| 122 | + dc.SelectObject(bmp) | |
| 123 | + dc.SetFont(self.GetFont()) | |
| 124 | + label = self.GetLabel() | |
| 125 | + # Just make a little colored bitmap | |
| 126 | + dc.SetBackground(wx.Brush(self.colour)) | |
| 127 | + dc.Clear() | |
| 128 | + | |
| 129 | + if label: | |
| 130 | + # Add a label to it | |
| 131 | + avg = reduce(lambda a, b: a + b, self.colour.Get()) / 3 | |
| 132 | + fcolour = avg > 128 and wx.BLACK or wx.WHITE | |
| 133 | + dc.SetTextForeground(fcolour) | |
| 134 | + dc.DrawLabel(label, (0,0, width-bdr, height-bdr), | |
| 135 | + wx.ALIGN_CENTER) | |
| 136 | + | |
| 137 | + dc.SelectObject(wx.NullBitmap) | |
| 138 | + return bmp | |
| 139 | + | |
| 140 | + | |
| 141 | + def SetBitmap(self, bmp): | |
| 142 | + self.SetBitmapLabel(bmp) | |
| 143 | + #self.SetBitmapSelected(bmp) | |
| 144 | + #self.SetBitmapDisabled(bmp) | |
| 145 | + #self.SetBitmapFocus(bmp) | |
| 146 | + #self.SetBitmapSelected(bmp) | |
| 147 | + self.Refresh() | |
| 148 | + | |
| 149 | + | |
| 150 | + def OnChange(self): | |
| 151 | + evt = ColourSelectEvent(self.GetId(), self.GetValue()) | |
| 152 | + evt.SetEventObject(self) | |
| 153 | + wx.PostEvent(self, evt) | |
| 154 | + if self.callback is not None: | |
| 155 | + self.callback() | |
| 156 | + | |
| 157 | + def OnClick(self, event): | |
| 158 | + data = wx.ColourData() | |
| 159 | + data.SetChooseFull(True) | |
| 160 | + data.SetColour(self.colour) | |
| 161 | + dlg = wx.ColourDialog(wx.GetTopLevelParent(self), data) | |
| 162 | + | |
| 163 | + try: | |
| 164 | + changed = dlg.ShowModal() == wx.ID_OK | |
| 165 | + except(wx._core.PyAssertionError): | |
| 166 | + changed = True | |
| 167 | + | |
| 168 | + if changed: | |
| 169 | + data = dlg.GetColourData() | |
| 170 | + self.SetColour(data.GetColour()) | |
| 171 | + dlg.Destroy() | |
| 172 | + | |
| 173 | + # moved after dlg.Destroy, since who knows what the callback will do... | |
| 174 | + if changed: | |
| 175 | + self.OnChange() | |
| 176 | + | ... | ... |
invesalius/reader/__init__.py
| 1 | -#-------------------------------------------------------------------------- | |
| 2 | -# Software: InVesalius - Software de Reconstrucao 3D de Imagens Medicas | |
| 3 | -# Copyright: (C) 2001 Centro de Pesquisas Renato Archer | |
| 4 | -# Homepage: http://www.softwarepublico.gov.br | |
| 5 | -# Contact: invesalius@cti.gov.br | |
| 6 | -# License: GNU - GPL 2 (LICENSE.txt/LICENCA.txt) | |
| 7 | -#-------------------------------------------------------------------------- | |
| 8 | -# Este programa e software livre; voce pode redistribui-lo e/ou | |
| 9 | -# modifica-lo sob os termos da Licenca Publica Geral GNU, conforme | |
| 10 | -# publicada pela Free Software Foundation; de acordo com a versao 2 | |
| 11 | -# da Licenca. | |
| 12 | -# | |
| 13 | -# Este programa eh distribuido na expectativa de ser util, mas SEM | |
| 14 | -# QUALQUER GARANTIA; sem mesmo a garantia implicita de | |
| 15 | -# COMERCIALIZACAO ou de ADEQUACAO A QUALQUER PROPOSITO EM | |
| 16 | -# PARTICULAR. Consulte a Licenca Publica Geral GNU para obter mais | |
| 17 | -# detalhes. | |
| 18 | -#-------------------------------------------------------------------------- | |
| 1 | +#-------------------------------------------------------------------------- | |
| 2 | +# Software: InVesalius - Software de Reconstrucao 3D de Imagens Medicas | |
| 3 | +# Copyright: (C) 2001 Centro de Pesquisas Renato Archer | |
| 4 | +# Homepage: http://www.softwarepublico.gov.br | |
| 5 | +# Contact: invesalius@cti.gov.br | |
| 6 | +# License: GNU - GPL 2 (LICENSE.txt/LICENCA.txt) | |
| 7 | +#-------------------------------------------------------------------------- | |
| 8 | +# Este programa e software livre; voce pode redistribui-lo e/ou | |
| 9 | +# modifica-lo sob os termos da Licenca Publica Geral GNU, conforme | |
| 10 | +# publicada pela Free Software Foundation; de acordo com a versao 2 | |
| 11 | +# da Licenca. | |
| 12 | +# | |
| 13 | +# Este programa eh distribuido na expectativa de ser util, mas SEM | |
| 14 | +# QUALQUER GARANTIA; sem mesmo a garantia implicita de | |
| 15 | +# COMERCIALIZACAO ou de ADEQUACAO A QUALQUER PROPOSITO EM | |
| 16 | +# PARTICULAR. Consulte a Licenca Publica Geral GNU para obter mais | |
| 17 | +# detalhes. | |
| 18 | +#-------------------------------------------------------------------------- | ... | ... |
invesalius/session.py
| 1 | -import ConfigParser | |
| 2 | -import os | |
| 3 | -import shutil | |
| 4 | -import sys | |
| 5 | -from threading import Thread | |
| 6 | -import time | |
| 7 | - | |
| 8 | -import wx.lib.pubsub as ps | |
| 9 | - | |
| 10 | -from utils import Singleton, debug | |
| 11 | - | |
| 12 | -class Session(object): | |
| 13 | - # Only one session will be initialized per time. Therefore, we use | |
| 14 | - # Singleton design pattern for implementing it | |
| 15 | - __metaclass__= Singleton | |
| 16 | - | |
| 17 | - def __init__(self): | |
| 18 | - self.temp_item = False | |
| 19 | - | |
| 20 | - ws = self.ws = WriteSession(self) | |
| 21 | - ws.start() | |
| 22 | - ps.Publisher().subscribe(self.StopRecording, "Stop Config Recording") | |
| 23 | - | |
| 24 | - def CreateItens(self): | |
| 25 | - import constants as const | |
| 26 | - self.project_path = () | |
| 27 | - self.debug = False | |
| 28 | - | |
| 29 | - self.project_status = const.PROJ_CLOSE | |
| 30 | - # const.PROJ_NEW*, const.PROJ_OPEN, const.PROJ_CHANGE*, | |
| 31 | - # const.PROJ_CLOSE | |
| 32 | - | |
| 33 | - self.mode = const.MODE_RP | |
| 34 | - # const.MODE_RP, const.MODE_NAVIGATOR, const.MODE_RADIOLOGY, | |
| 35 | - # const.MODE_ODONTOLOGY | |
| 36 | - | |
| 37 | - # InVesalius default projects' directory | |
| 38 | - homedir = self.homedir = os.path.expanduser('~') | |
| 39 | - tempdir = os.path.join(homedir, ".invesalius", "temp") | |
| 40 | - if not os.path.isdir(tempdir): | |
| 41 | - os.makedirs(tempdir) | |
| 42 | - self.tempdir = tempdir | |
| 43 | - | |
| 44 | - # GUI language | |
| 45 | - self.language = "" # "pt_BR", "es" | |
| 46 | - | |
| 47 | - # Recent projects list | |
| 48 | - self.recent_projects = [(const.SAMPLE_DIR, "Cranium.inv3")] | |
| 49 | - self.last_dicom_folder = '' | |
| 50 | - | |
| 51 | - self.CreateSessionFile() | |
| 52 | - | |
| 53 | - def StopRecording(self, pubsub_evt): | |
| 54 | - self.ws.Stop() | |
| 55 | - | |
| 56 | - def SaveConfigFileBackup(self): | |
| 57 | - path = os.path.join(self.homedir , | |
| 58 | - '.invesalius', 'config.cfg') | |
| 59 | - path_dst = os.path.join(self.homedir , | |
| 60 | - '.invesalius', 'config.backup') | |
| 61 | - shutil.copy(path, path_dst) | |
| 62 | - | |
| 63 | - def RecoveryConfigFile(self): | |
| 64 | - homedir = self.homedir = os.path.expanduser('~') | |
| 65 | - try: | |
| 66 | - path = os.path.join(self.homedir , | |
| 67 | - '.invesalius', 'config.backup') | |
| 68 | - path_dst = os.path.join(self.homedir , | |
| 69 | - '.invesalius', 'config.cfg') | |
| 70 | - shutil.copy(path, path_dst) | |
| 71 | - return True | |
| 72 | - except(IOError): | |
| 73 | - return False | |
| 74 | - | |
| 75 | - | |
| 76 | - def CloseProject(self): | |
| 77 | - import constants as const | |
| 78 | - debug("Session.CloseProject") | |
| 79 | - self.project_path = () | |
| 80 | - self.project_status = const.PROJ_CLOSE | |
| 81 | - #self.mode = const.MODE_RP | |
| 82 | - self.temp_item = False | |
| 83 | - | |
| 84 | - def SaveProject(self, path=()): | |
| 85 | - import constants as const | |
| 86 | - debug("Session.SaveProject") | |
| 87 | - self.project_status = const.PROJ_OPEN | |
| 88 | - if path: | |
| 89 | - self.project_path = path | |
| 90 | - self.__add_to_list(path) | |
| 91 | - if self.temp_item: | |
| 92 | - self.temp_item = False | |
| 93 | - | |
| 94 | - def ChangeProject(self): | |
| 95 | - import constants as const | |
| 96 | - debug("Session.ChangeProject") | |
| 97 | - self.project_status = const.PROJ_CHANGE | |
| 98 | - | |
| 99 | - def CreateProject(self, filename): | |
| 100 | - import constants as const | |
| 101 | - debug("Session.CreateProject") | |
| 102 | - ps.Publisher().sendMessage('Begin busy cursor') | |
| 103 | - # Set session info | |
| 104 | - self.project_path = (self.tempdir, filename) | |
| 105 | - self.project_status = const.PROJ_NEW | |
| 106 | - self.temp_item = True | |
| 107 | - return self.tempdir | |
| 108 | - | |
| 109 | - def OpenProject(self, filepath): | |
| 110 | - import constants as const | |
| 111 | - debug("Session.OpenProject") | |
| 112 | - # Add item to recent projects list | |
| 113 | - item = (path, file) = os.path.split(filepath) | |
| 114 | - self.__add_to_list(item) | |
| 115 | - | |
| 116 | - # Set session info | |
| 117 | - self.project_path = item | |
| 118 | - self.project_status = const.PROJ_OPEN | |
| 119 | - | |
| 120 | - def RemoveTemp(self): | |
| 121 | - if self.temp_item: | |
| 122 | - (dirpath, file) = self.project_path | |
| 123 | - path = os.path.join(dirpath, file) | |
| 124 | - os.remove(path) | |
| 125 | - self.temp_item = False | |
| 126 | - | |
| 127 | - def CreateSessionFile(self): | |
| 128 | - config = ConfigParser.RawConfigParser() | |
| 129 | - | |
| 130 | - config.add_section('session') | |
| 131 | - config.set('session', 'mode', self.mode) | |
| 132 | - config.set('session', 'status', self.project_status) | |
| 133 | - config.set('session','debug', self.debug) | |
| 134 | - config.set('session', 'language', self.language) | |
| 135 | - | |
| 136 | - config.add_section('project') | |
| 137 | - config.set('project', 'recent_projects', self.recent_projects) | |
| 138 | - | |
| 139 | - config.add_section('paths') | |
| 140 | - config.set('paths','homedir',self.homedir) | |
| 141 | - config.set('paths','tempdir',self.tempdir) | |
| 142 | - try: | |
| 143 | - config.set('paths','last_dicom_folder',self.last_dicom_folder.encode('utf-8')) | |
| 144 | - except (UnicodeEncodeError, UnicodeDecodeError): | |
| 145 | - config.set('paths','last_dicom_folder',self.last_dicom_folder) | |
| 146 | - path = os.path.join(self.homedir , | |
| 147 | - '.invesalius', 'config.cfg') | |
| 148 | - | |
| 149 | - configfile = open(path, 'wb') | |
| 150 | - config.write(configfile) | |
| 151 | - configfile.close() | |
| 152 | - | |
| 153 | - | |
| 154 | - def __add_to_list(self, item): | |
| 155 | - import constants as const | |
| 156 | - # Last projects list | |
| 157 | - l = self.recent_projects | |
| 158 | - | |
| 159 | - # If item exists, remove it from list | |
| 160 | - if l.count(item): | |
| 161 | - l.remove(item) | |
| 162 | - | |
| 163 | - # Add new item | |
| 164 | - l.insert(0, item) | |
| 165 | - | |
| 166 | - # Remove oldest projects from list | |
| 167 | - if len(l)>const.PROJ_MAX: | |
| 168 | - for i in xrange(len(l)-const.PROJ_MAX): | |
| 169 | - l.pop() | |
| 170 | - | |
| 171 | - def GetLanguage(self): | |
| 172 | - return self.language | |
| 173 | - | |
| 174 | - def SetLanguage(self, language): | |
| 175 | - self.language = language | |
| 176 | - | |
| 177 | - def GetLastDicomFolder(self): | |
| 178 | - return self.last_dicom_folder | |
| 179 | - | |
| 180 | - def SetLastDicomFolder(self, folder): | |
| 181 | - self.last_dicom_folder = folder | |
| 182 | - self.CreateSessionFile() | |
| 183 | - | |
| 184 | - def ReadLanguage(self): | |
| 185 | - config = ConfigParser.ConfigParser() | |
| 186 | - home_path = os.path.expanduser('~') | |
| 187 | - path = os.path.join(home_path ,'.invesalius', 'config.cfg') | |
| 188 | - try: | |
| 189 | - config.read(path) | |
| 190 | - self.language = config.get('session','language') | |
| 191 | - return self.language | |
| 192 | - except (ConfigParser.NoSectionError, | |
| 193 | - ConfigParser.NoOptionError, | |
| 194 | - ConfigParser.MissingSectionHeaderError): | |
| 195 | - return False | |
| 196 | - | |
| 197 | - def ReadSession(self): | |
| 198 | - config = ConfigParser.ConfigParser() | |
| 199 | - home_path = os.path.expanduser('~') | |
| 200 | - path = os.path.join(home_path ,'.invesalius', 'config.cfg') | |
| 201 | - try: | |
| 202 | - config.read(path) | |
| 203 | - self.mode = config.get('session', 'mode') | |
| 204 | - self.project_status = config.get('session', 'status') | |
| 205 | - self.debug = config.get('session','debug') | |
| 206 | - self.language = config.get('session','language') | |
| 207 | - self.recent_projects = eval(config.get('project','recent_projects')) | |
| 208 | - self.homedir = config.get('paths','homedir') | |
| 209 | - self.tempdir = config.get('paths','tempdir') | |
| 210 | - self.last_dicom_folder = config.get('paths','last_dicom_folder') | |
| 211 | - self.last_dicom_folder = self.last_dicom_folder.decode('utf-8') | |
| 212 | - return True | |
| 213 | - | |
| 214 | - except(ConfigParser.NoSectionError, ConfigParser.NoOptionError, | |
| 215 | - ConfigParser.MissingSectionHeaderError, ConfigParser.ParsingError): | |
| 216 | - | |
| 217 | - if (self.RecoveryConfigFile()): | |
| 218 | - self.ReadSession() | |
| 219 | - return True | |
| 220 | - else: | |
| 221 | - return False | |
| 222 | - | |
| 223 | - | |
| 224 | -class WriteSession(Thread): | |
| 225 | - | |
| 226 | - def __init__ (self, session): | |
| 227 | - Thread.__init__(self) | |
| 228 | - self.session = session | |
| 229 | - self.runing = 1 | |
| 230 | - | |
| 231 | - def run(self): | |
| 232 | - while self.runing: | |
| 233 | - time.sleep(10) | |
| 234 | - try: | |
| 235 | - self.Write() | |
| 236 | - except AttributeError: | |
| 237 | - debug("Session: trying to write into inexistent file") | |
| 238 | - | |
| 239 | - def Stop(self): | |
| 240 | - self.runing = 0 | |
| 241 | - | |
| 242 | - def Write(self): | |
| 243 | - import utils as utl | |
| 244 | - | |
| 245 | - config = ConfigParser.RawConfigParser() | |
| 246 | - | |
| 247 | - config.add_section('session') | |
| 248 | - config.set('session', 'mode', self.session.mode) | |
| 249 | - config.set('session', 'status', self.session.project_status) | |
| 250 | - config.set('session','debug', self.session.debug) | |
| 251 | - config.set('session', 'language', self.session.language) | |
| 252 | - | |
| 253 | - config.add_section('project') | |
| 254 | - config.set('project', 'recent_projects', self.session.recent_projects) | |
| 255 | - | |
| 256 | - config.add_section('paths') | |
| 257 | - config.set('paths','homedir',self.session.homedir) | |
| 258 | - config.set('paths','tempdir',self.session.tempdir) | |
| 259 | - config.set('paths','last_dicom_folder', self.session.last_dicom_folder) | |
| 260 | - | |
| 261 | - path = os.path.join(self.session.homedir , | |
| 262 | - '.invesalius', 'config.cfg') | |
| 263 | - | |
| 264 | - try: | |
| 265 | - configfile = open(path, 'wb') | |
| 266 | - except IOError: | |
| 267 | - return | |
| 268 | - utl.debug("Session - IOError") | |
| 269 | - finally: | |
| 270 | - self.session.CreateSessionFile() | |
| 271 | - | |
| 272 | - configfile.close() | |
| 273 | - | |
| 274 | - | |
| 275 | - | |
| 276 | - | |
| 1 | +import ConfigParser | |
| 2 | +import os | |
| 3 | +import shutil | |
| 4 | +import sys | |
| 5 | +from threading import Thread | |
| 6 | +import time | |
| 7 | + | |
| 8 | +import wx.lib.pubsub as ps | |
| 9 | + | |
| 10 | +from utils import Singleton, debug | |
| 11 | + | |
| 12 | +class Session(object): | |
| 13 | + # Only one session will be initialized per time. Therefore, we use | |
| 14 | + # Singleton design pattern for implementing it | |
| 15 | + __metaclass__= Singleton | |
| 16 | + | |
| 17 | + def __init__(self): | |
| 18 | + self.temp_item = False | |
| 19 | + | |
| 20 | + ws = self.ws = WriteSession(self) | |
| 21 | + ws.start() | |
| 22 | + ps.Publisher().subscribe(self.StopRecording, "Stop Config Recording") | |
| 23 | + | |
| 24 | + def CreateItens(self): | |
| 25 | + import constants as const | |
| 26 | + self.project_path = () | |
| 27 | + self.debug = False | |
| 28 | + | |
| 29 | + self.project_status = const.PROJ_CLOSE | |
| 30 | + # const.PROJ_NEW*, const.PROJ_OPEN, const.PROJ_CHANGE*, | |
| 31 | + # const.PROJ_CLOSE | |
| 32 | + | |
| 33 | + self.mode = const.MODE_RP | |
| 34 | + # const.MODE_RP, const.MODE_NAVIGATOR, const.MODE_RADIOLOGY, | |
| 35 | + # const.MODE_ODONTOLOGY | |
| 36 | + | |
| 37 | + # InVesalius default projects' directory | |
| 38 | + homedir = self.homedir = os.path.expanduser('~') | |
| 39 | + tempdir = os.path.join(homedir, ".invesalius", "temp") | |
| 40 | + if not os.path.isdir(tempdir): | |
| 41 | + os.makedirs(tempdir) | |
| 42 | + self.tempdir = tempdir | |
| 43 | + | |
| 44 | + # GUI language | |
| 45 | + self.language = "" # "pt_BR", "es" | |
| 46 | + | |
| 47 | + # Recent projects list | |
| 48 | + self.recent_projects = [(const.SAMPLE_DIR, "Cranium.inv3")] | |
| 49 | + self.last_dicom_folder = '' | |
| 50 | + | |
| 51 | + self.CreateSessionFile() | |
| 52 | + | |
| 53 | + def StopRecording(self, pubsub_evt): | |
| 54 | + self.ws.Stop() | |
| 55 | + | |
| 56 | + def SaveConfigFileBackup(self): | |
| 57 | + path = os.path.join(self.homedir , | |
| 58 | + '.invesalius', 'config.cfg') | |
| 59 | + path_dst = os.path.join(self.homedir , | |
| 60 | + '.invesalius', 'config.backup') | |
| 61 | + shutil.copy(path, path_dst) | |
| 62 | + | |
| 63 | + def RecoveryConfigFile(self): | |
| 64 | + homedir = self.homedir = os.path.expanduser('~') | |
| 65 | + try: | |
| 66 | + path = os.path.join(self.homedir , | |
| 67 | + '.invesalius', 'config.backup') | |
| 68 | + path_dst = os.path.join(self.homedir , | |
| 69 | + '.invesalius', 'config.cfg') | |
| 70 | + shutil.copy(path, path_dst) | |
| 71 | + return True | |
| 72 | + except(IOError): | |
| 73 | + return False | |
| 74 | + | |
| 75 | + | |
| 76 | + def CloseProject(self): | |
| 77 | + import constants as const | |
| 78 | + debug("Session.CloseProject") | |
| 79 | + self.project_path = () | |
| 80 | + self.project_status = const.PROJ_CLOSE | |
| 81 | + #self.mode = const.MODE_RP | |
| 82 | + self.temp_item = False | |
| 83 | + | |
| 84 | + def SaveProject(self, path=()): | |
| 85 | + import constants as const | |
| 86 | + debug("Session.SaveProject") | |
| 87 | + self.project_status = const.PROJ_OPEN | |
| 88 | + if path: | |
| 89 | + self.project_path = path | |
| 90 | + self.__add_to_list(path) | |
| 91 | + if self.temp_item: | |
| 92 | + self.temp_item = False | |
| 93 | + | |
| 94 | + def ChangeProject(self): | |
| 95 | + import constants as const | |
| 96 | + debug("Session.ChangeProject") | |
| 97 | + self.project_status = const.PROJ_CHANGE | |
| 98 | + | |
| 99 | + def CreateProject(self, filename): | |
| 100 | + import constants as const | |
| 101 | + debug("Session.CreateProject") | |
| 102 | + ps.Publisher().sendMessage('Begin busy cursor') | |
| 103 | + # Set session info | |
| 104 | + self.project_path = (self.tempdir, filename) | |
| 105 | + self.project_status = const.PROJ_NEW | |
| 106 | + self.temp_item = True | |
| 107 | + return self.tempdir | |
| 108 | + | |
| 109 | + def OpenProject(self, filepath): | |
| 110 | + import constants as const | |
| 111 | + debug("Session.OpenProject") | |
| 112 | + # Add item to recent projects list | |
| 113 | + item = (path, file) = os.path.split(filepath) | |
| 114 | + self.__add_to_list(item) | |
| 115 | + | |
| 116 | + # Set session info | |
| 117 | + self.project_path = item | |
| 118 | + self.project_status = const.PROJ_OPEN | |
| 119 | + | |
| 120 | + def RemoveTemp(self): | |
| 121 | + if self.temp_item: | |
| 122 | + (dirpath, file) = self.project_path | |
| 123 | + path = os.path.join(dirpath, file) | |
| 124 | + os.remove(path) | |
| 125 | + self.temp_item = False | |
| 126 | + | |
| 127 | + def CreateSessionFile(self): | |
| 128 | + config = ConfigParser.RawConfigParser() | |
| 129 | + | |
| 130 | + config.add_section('session') | |
| 131 | + config.set('session', 'mode', self.mode) | |
| 132 | + config.set('session', 'status', self.project_status) | |
| 133 | + config.set('session','debug', self.debug) | |
| 134 | + config.set('session', 'language', self.language) | |
| 135 | + | |
| 136 | + config.add_section('project') | |
| 137 | + config.set('project', 'recent_projects', self.recent_projects) | |
| 138 | + | |
| 139 | + config.add_section('paths') | |
| 140 | + config.set('paths','homedir',self.homedir) | |
| 141 | + config.set('paths','tempdir',self.tempdir) | |
| 142 | + try: | |
| 143 | + config.set('paths','last_dicom_folder',self.last_dicom_folder.encode('utf-8')) | |
| 144 | + except (UnicodeEncodeError, UnicodeDecodeError): | |
| 145 | + config.set('paths','last_dicom_folder',self.last_dicom_folder) | |
| 146 | + path = os.path.join(self.homedir , | |
| 147 | + '.invesalius', 'config.cfg') | |
| 148 | + | |
| 149 | + configfile = open(path, 'wb') | |
| 150 | + config.write(configfile) | |
| 151 | + configfile.close() | |
| 152 | + | |
| 153 | + | |
| 154 | + def __add_to_list(self, item): | |
| 155 | + import constants as const | |
| 156 | + # Last projects list | |
| 157 | + l = self.recent_projects | |
| 158 | + | |
| 159 | + # If item exists, remove it from list | |
| 160 | + if l.count(item): | |
| 161 | + l.remove(item) | |
| 162 | + | |
| 163 | + # Add new item | |
| 164 | + l.insert(0, item) | |
| 165 | + | |
| 166 | + # Remove oldest projects from list | |
| 167 | + if len(l)>const.PROJ_MAX: | |
| 168 | + for i in xrange(len(l)-const.PROJ_MAX): | |
| 169 | + l.pop() | |
| 170 | + | |
| 171 | + def GetLanguage(self): | |
| 172 | + return self.language | |
| 173 | + | |
| 174 | + def SetLanguage(self, language): | |
| 175 | + self.language = language | |
| 176 | + | |
| 177 | + def GetLastDicomFolder(self): | |
| 178 | + return self.last_dicom_folder | |
| 179 | + | |
| 180 | + def SetLastDicomFolder(self, folder): | |
| 181 | + self.last_dicom_folder = folder | |
| 182 | + self.CreateSessionFile() | |
| 183 | + | |
| 184 | + def ReadLanguage(self): | |
| 185 | + config = ConfigParser.ConfigParser() | |
| 186 | + home_path = os.path.expanduser('~') | |
| 187 | + path = os.path.join(home_path ,'.invesalius', 'config.cfg') | |
| 188 | + try: | |
| 189 | + config.read(path) | |
| 190 | + self.language = config.get('session','language') | |
| 191 | + return self.language | |
| 192 | + except (ConfigParser.NoSectionError, | |
| 193 | + ConfigParser.NoOptionError, | |
| 194 | + ConfigParser.MissingSectionHeaderError): | |
| 195 | + return False | |
| 196 | + | |
| 197 | + def ReadSession(self): | |
| 198 | + config = ConfigParser.ConfigParser() | |
| 199 | + home_path = os.path.expanduser('~') | |
| 200 | + path = os.path.join(home_path ,'.invesalius', 'config.cfg') | |
| 201 | + try: | |
| 202 | + config.read(path) | |
| 203 | + self.mode = config.get('session', 'mode') | |
| 204 | + self.project_status = config.get('session', 'status') | |
| 205 | + self.debug = config.get('session','debug') | |
| 206 | + self.language = config.get('session','language') | |
| 207 | + self.recent_projects = eval(config.get('project','recent_projects')) | |
| 208 | + self.homedir = config.get('paths','homedir') | |
| 209 | + self.tempdir = config.get('paths','tempdir') | |
| 210 | + self.last_dicom_folder = config.get('paths','last_dicom_folder') | |
| 211 | + self.last_dicom_folder = self.last_dicom_folder.decode('utf-8') | |
| 212 | + return True | |
| 213 | + | |
| 214 | + except(ConfigParser.NoSectionError, ConfigParser.NoOptionError, | |
| 215 | + ConfigParser.MissingSectionHeaderError, ConfigParser.ParsingError): | |
| 216 | + | |
| 217 | + if (self.RecoveryConfigFile()): | |
| 218 | + self.ReadSession() | |
| 219 | + return True | |
| 220 | + else: | |
| 221 | + return False | |
| 222 | + | |
| 223 | + | |
| 224 | +class WriteSession(Thread): | |
| 225 | + | |
| 226 | + def __init__ (self, session): | |
| 227 | + Thread.__init__(self) | |
| 228 | + self.session = session | |
| 229 | + self.runing = 1 | |
| 230 | + | |
| 231 | + def run(self): | |
| 232 | + while self.runing: | |
| 233 | + time.sleep(10) | |
| 234 | + try: | |
| 235 | + self.Write() | |
| 236 | + except AttributeError: | |
| 237 | + debug("Session: trying to write into inexistent file") | |
| 238 | + | |
| 239 | + def Stop(self): | |
| 240 | + self.runing = 0 | |
| 241 | + | |
| 242 | + def Write(self): | |
| 243 | + import utils as utl | |
| 244 | + | |
| 245 | + config = ConfigParser.RawConfigParser() | |
| 246 | + | |
| 247 | + config.add_section('session') | |
| 248 | + config.set('session', 'mode', self.session.mode) | |
| 249 | + config.set('session', 'status', self.session.project_status) | |
| 250 | + config.set('session','debug', self.session.debug) | |
| 251 | + config.set('session', 'language', self.session.language) | |
| 252 | + | |
| 253 | + config.add_section('project') | |
| 254 | + config.set('project', 'recent_projects', self.session.recent_projects) | |
| 255 | + | |
| 256 | + config.add_section('paths') | |
| 257 | + config.set('paths','homedir',self.session.homedir) | |
| 258 | + config.set('paths','tempdir',self.session.tempdir) | |
| 259 | + config.set('paths','last_dicom_folder', self.session.last_dicom_folder) | |
| 260 | + | |
| 261 | + path = os.path.join(self.session.homedir , | |
| 262 | + '.invesalius', 'config.cfg') | |
| 263 | + | |
| 264 | + try: | |
| 265 | + configfile = open(path, 'wb') | |
| 266 | + except IOError: | |
| 267 | + return | |
| 268 | + utl.debug("Session - IOError") | |
| 269 | + finally: | |
| 270 | + self.session.CreateSessionFile() | |
| 271 | + | |
| 272 | + configfile.close() | |
| 273 | + | |
| 274 | + | |
| 275 | + | |
| 276 | + | ... | ... |