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 | + | ... | ... |