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,65 +151,6 @@ icons/volume_raycasting.png -text | ||
151 | icons/volume_raycasting_original.png -text | 151 | icons/volume_raycasting_original.png -text |
152 | icons/zh_TW.bmp -text | 152 | icons/zh_TW.bmp -text |
153 | invesalius/.svnignore -text | 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 | locale/de/LC_MESSAGES/invesalius.mo -text | 154 | locale/de/LC_MESSAGES/invesalius.mo -text |
214 | locale/el/LC_MESSAGES/invesalius.mo -text | 155 | locale/el/LC_MESSAGES/invesalius.mo -text |
215 | locale/en/LC_MESSAGES/invesalius.mo -text | 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,6 +235,7 @@ class SurfaceManager(): | ||
235 | mapper = vtk.vtkPolyDataMapper() | 235 | mapper = vtk.vtkPolyDataMapper() |
236 | mapper.SetInput(normals.GetOutput()) | 236 | mapper.SetInput(normals.GetOutput()) |
237 | mapper.ScalarVisibilityOff() | 237 | mapper.ScalarVisibilityOff() |
238 | + mapper.ImmediateModeRenderingOn() | ||
238 | 239 | ||
239 | actor = vtk.vtkActor() | 240 | actor = vtk.vtkActor() |
240 | actor.SetMapper(mapper) | 241 | actor.SetMapper(mapper) |
@@ -339,6 +340,7 @@ class SurfaceManager(): | @@ -339,6 +340,7 @@ class SurfaceManager(): | ||
339 | mapper = vtk.vtkPolyDataMapper() | 340 | mapper = vtk.vtkPolyDataMapper() |
340 | mapper.SetInput(stripper.GetOutput()) | 341 | mapper.SetInput(stripper.GetOutput()) |
341 | mapper.ScalarVisibilityOff() | 342 | mapper.ScalarVisibilityOff() |
343 | + mapper.ImmediateModeRenderingOn() | ||
342 | 344 | ||
343 | # Represent an object (geometry & properties) in the rendered scene | 345 | # Represent an object (geometry & properties) in the rendered scene |
344 | actor = vtk.vtkActor() | 346 | actor = vtk.vtkActor() |
@@ -470,6 +472,7 @@ class SurfaceManager(): | @@ -470,6 +472,7 @@ class SurfaceManager(): | ||
470 | mapper = vtk.vtkPolyDataMapper() | 472 | mapper = vtk.vtkPolyDataMapper() |
471 | mapper.SetInput(stripper.GetOutput()) | 473 | mapper.SetInput(stripper.GetOutput()) |
472 | mapper.ScalarVisibilityOff() | 474 | mapper.ScalarVisibilityOff() |
475 | + mapper.ImmediateModeRendering() | ||
473 | 476 | ||
474 | # Represent an object (geometry & properties) in the rendered scene | 477 | # Represent an object (geometry & properties) in the rendered scene |
475 | actor = vtk.vtkActor() | 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 | + |