Commit 6e9eeb391c88e0815023573632646f4dc705e4b6
Committed by
GitHub
1 parent
feaf214b
Exists in
master
Session as dict (#156)
* session as dict almost working * writing to json * Better last projection handling * was not closing when didn't have config * Not reading status from config file * removed unused fucntion * reading from cfg specifing the types * reading from cfg specifing the types * Removed unused parts * Added a get method to session * Using default in session * last folder to inv3 and other files in session * last folder to export and import stl export screenshots and open bmp folder in session
Showing
8 changed files
with
239 additions
and
176 deletions
Show diff stats
app.py
@@ -147,9 +147,8 @@ class Inv3SplashScreen(SplashScreen): | @@ -147,9 +147,8 @@ class Inv3SplashScreen(SplashScreen): | ||
147 | create_session = True | 147 | create_session = True |
148 | 148 | ||
149 | install_lang = 0 | 149 | install_lang = 0 |
150 | - # Check if there is a language set (if session file exists | ||
151 | - if session.ReadLanguage(): | ||
152 | - lang = session.GetLanguage() | 150 | + lang = session.GetLanguage() |
151 | + if lang: | ||
153 | if (lang != "False"): | 152 | if (lang != "False"): |
154 | _ = i18n.InstallLanguage(lang) | 153 | _ = i18n.InstallLanguage(lang) |
155 | install_lang = 1 | 154 | install_lang = 1 |
@@ -179,7 +178,9 @@ class Inv3SplashScreen(SplashScreen): | @@ -179,7 +178,9 @@ class Inv3SplashScreen(SplashScreen): | ||
179 | invdir = os.path.join(homedir, ".invesalius") | 178 | invdir = os.path.join(homedir, ".invesalius") |
180 | shutil.rmtree(invdir) | 179 | shutil.rmtree(invdir) |
181 | sys.exit() | 180 | sys.exit() |
182 | - | 181 | + |
182 | + dialog.Destroy() | ||
183 | + | ||
183 | # Session file should be created... So we set the recent | 184 | # Session file should be created... So we set the recent |
184 | # choosen language | 185 | # choosen language |
185 | if (create_session): | 186 | if (create_session): |
@@ -187,7 +188,7 @@ class Inv3SplashScreen(SplashScreen): | @@ -187,7 +188,7 @@ class Inv3SplashScreen(SplashScreen): | ||
187 | session.SetLanguage(lang) | 188 | session.SetLanguage(lang) |
188 | session.WriteSessionFile() | 189 | session.WriteSessionFile() |
189 | 190 | ||
190 | - session.SaveConfigFileBackup() | 191 | + # session.SaveConfigFileBackup() |
191 | 192 | ||
192 | 193 | ||
193 | # Only after language was defined, splash screen will be | 194 | # Only after language was defined, splash screen will be |
invesalius/control.py
@@ -249,6 +249,7 @@ class Controller(): | @@ -249,6 +249,7 @@ class Controller(): | ||
249 | def ShowDialogCloseProject(self): | 249 | def ShowDialogCloseProject(self): |
250 | session = ses.Session() | 250 | session = ses.Session() |
251 | st = session.project_status | 251 | st = session.project_status |
252 | + print('Status', st, type(st)) | ||
252 | if st == const.PROJ_CLOSE: | 253 | if st == const.PROJ_CLOSE: |
253 | return -1 | 254 | return -1 |
254 | try: | 255 | try: |
invesalius/data/surface.py
@@ -159,6 +159,28 @@ class SurfaceManager(): | @@ -159,6 +159,28 @@ class SurfaceManager(): | ||
159 | self.last_surface_index = 0 | 159 | self.last_surface_index = 0 |
160 | self.__bind_events() | 160 | self.__bind_events() |
161 | 161 | ||
162 | + self._default_parameters = { | ||
163 | + 'algorithm': 'Default', | ||
164 | + 'quality': const.DEFAULT_SURFACE_QUALITY, | ||
165 | + 'fill_holes': False, | ||
166 | + 'keep_largest': False, | ||
167 | + 'fill_border_holes': True, | ||
168 | + } | ||
169 | + | ||
170 | + self._load_user_parameters() | ||
171 | + | ||
172 | + def _load_user_parameters(self): | ||
173 | + session = ses.Session() | ||
174 | + | ||
175 | + if 'surface' in session: | ||
176 | + self._default_parameters.update(session['surface']) | ||
177 | + else: | ||
178 | + session['surface'] = self._default_parameters | ||
179 | + session.WriteSessionFile() | ||
180 | + | ||
181 | + print('Session', session) | ||
182 | + | ||
183 | + | ||
162 | def __bind_events(self): | 184 | def __bind_events(self): |
163 | Publisher.subscribe(self.AddNewActor, 'Create surface') | 185 | Publisher.subscribe(self.AddNewActor, 'Create surface') |
164 | Publisher.subscribe(self.SetActorTransparency, | 186 | Publisher.subscribe(self.SetActorTransparency, |
invesalius/gui/dialogs.py
@@ -268,8 +268,10 @@ WILDCARD_MESH_FILES = "STL File format (*.stl)|*.stl|" \ | @@ -268,8 +268,10 @@ WILDCARD_MESH_FILES = "STL File format (*.stl)|*.stl|" \ | ||
268 | def ShowOpenProjectDialog(): | 268 | def ShowOpenProjectDialog(): |
269 | # Default system path | 269 | # Default system path |
270 | current_dir = os.path.abspath(".") | 270 | current_dir = os.path.abspath(".") |
271 | + session = ses.Session() | ||
272 | + last_directory = session.get('paths', 'last_directory_inv3', '') | ||
271 | dlg = wx.FileDialog(None, message=_("Open InVesalius 3 project..."), | 273 | dlg = wx.FileDialog(None, message=_("Open InVesalius 3 project..."), |
272 | - defaultDir="", | 274 | + defaultDir=last_directory, |
273 | defaultFile="", wildcard=WILDCARD_OPEN, | 275 | defaultFile="", wildcard=WILDCARD_OPEN, |
274 | style=wx.FD_OPEN|wx.FD_CHANGE_DIR) | 276 | style=wx.FD_OPEN|wx.FD_CHANGE_DIR) |
275 | 277 | ||
@@ -286,6 +288,10 @@ def ShowOpenProjectDialog(): | @@ -286,6 +288,10 @@ def ShowOpenProjectDialog(): | ||
286 | except(wx._core.PyAssertionError): # FIX: win64 | 288 | except(wx._core.PyAssertionError): # FIX: win64 |
287 | filepath = dlg.GetPath() | 289 | filepath = dlg.GetPath() |
288 | 290 | ||
291 | + if filepath: | ||
292 | + session['paths']['last_directory_inv3'] = os.path.split(filepath)[0] | ||
293 | + session.WriteSessionFile() | ||
294 | + | ||
289 | # Destroy the dialog. Don't do this until you are done with it! | 295 | # Destroy the dialog. Don't do this until you are done with it! |
290 | # BAD things can happen otherwise! | 296 | # BAD things can happen otherwise! |
291 | dlg.Destroy() | 297 | dlg.Destroy() |
@@ -337,17 +343,19 @@ def ShowImportDirDialog(self): | @@ -337,17 +343,19 @@ def ShowImportDirDialog(self): | ||
337 | def ShowImportBitmapDirDialog(self): | 343 | def ShowImportBitmapDirDialog(self): |
338 | current_dir = os.path.abspath(".") | 344 | current_dir = os.path.abspath(".") |
339 | 345 | ||
340 | - if sys.platform == 'win32' or sys.platform.startswith('linux'): | ||
341 | - session = ses.Session() | 346 | + # if sys.platform == 'win32' or sys.platform.startswith('linux'): |
347 | + # session = ses.Session() | ||
342 | 348 | ||
343 | - if (session.GetLastDicomFolder()): | ||
344 | - folder = session.GetLastDicomFolder() | ||
345 | - else: | ||
346 | - folder = '' | ||
347 | - else: | ||
348 | - folder = '' | 349 | + # if (session.GetLastDicomFolder()): |
350 | + # folder = session.GetLastDicomFolder() | ||
351 | + # else: | ||
352 | + # folder = '' | ||
353 | + # else: | ||
354 | + # folder = '' | ||
355 | + session = ses.Session() | ||
356 | + last_directory = session.get('paths', 'last_directory_bitmap', '') | ||
349 | 357 | ||
350 | - dlg = wx.DirDialog(self, _("Choose a folder with TIFF, BMP, JPG or PNG:"), folder, | 358 | + dlg = wx.DirDialog(self, _("Choose a folder with TIFF, BMP, JPG or PNG:"), last_directory, |
351 | style=wx.DD_DEFAULT_STYLE | 359 | style=wx.DD_DEFAULT_STYLE |
352 | | wx.DD_DIR_MUST_EXIST | 360 | | wx.DD_DIR_MUST_EXIST |
353 | | wx.DD_CHANGE_DIR) | 361 | | wx.DD_CHANGE_DIR) |
@@ -363,9 +371,13 @@ def ShowImportBitmapDirDialog(self): | @@ -363,9 +371,13 @@ def ShowImportBitmapDirDialog(self): | ||
363 | if (dlg.GetPath()): | 371 | if (dlg.GetPath()): |
364 | path = dlg.GetPath() | 372 | path = dlg.GetPath() |
365 | 373 | ||
366 | - if (sys.platform != 'darwin'): | ||
367 | - if (path): | ||
368 | - session.SetLastDicomFolder(path) | 374 | + # if (sys.platform != 'darwin'): |
375 | + # if (path): | ||
376 | + # session.SetLastDicomFolder(path) | ||
377 | + | ||
378 | + if path: | ||
379 | + session['paths']['last_directory_bitmap'] = path | ||
380 | + session.WriteSessionFile() | ||
369 | 381 | ||
370 | # Only destroy a dialog after you're done with it. | 382 | # Only destroy a dialog after you're done with it. |
371 | dlg.Destroy() | 383 | dlg.Destroy() |
@@ -375,9 +387,10 @@ def ShowImportBitmapDirDialog(self): | @@ -375,9 +387,10 @@ def ShowImportBitmapDirDialog(self): | ||
375 | 387 | ||
376 | def ShowImportOtherFilesDialog(id_type): | 388 | def ShowImportOtherFilesDialog(id_type): |
377 | # Default system path | 389 | # Default system path |
378 | - current_dir = os.path.abspath(".") | 390 | + session = ses.Session() |
391 | + last_directory = session.get('paths', 'last_directory_%d' % id_type, '') | ||
379 | dlg = wx.FileDialog(None, message=_("Import Analyze 7.5 file"), | 392 | dlg = wx.FileDialog(None, message=_("Import Analyze 7.5 file"), |
380 | - defaultDir="", | 393 | + defaultDir=last_directory, |
381 | defaultFile="", wildcard=WILDCARD_ANALYZE, | 394 | defaultFile="", wildcard=WILDCARD_ANALYZE, |
382 | style=wx.FD_OPEN | wx.FD_CHANGE_DIR) | 395 | style=wx.FD_OPEN | wx.FD_CHANGE_DIR) |
383 | 396 | ||
@@ -407,17 +420,22 @@ def ShowImportOtherFilesDialog(id_type): | @@ -407,17 +420,22 @@ def ShowImportOtherFilesDialog(id_type): | ||
407 | if (dlg.GetPath()): | 420 | if (dlg.GetPath()): |
408 | filename = dlg.GetPath() | 421 | filename = dlg.GetPath() |
409 | 422 | ||
423 | + if filename: | ||
424 | + session['paths']['last_directory_%d' % id_type] = os.path.split(dlg.GetPath())[0] | ||
425 | + session.WriteSessionFile() | ||
410 | # Destroy the dialog. Don't do this until you are done with it! | 426 | # Destroy the dialog. Don't do this until you are done with it! |
411 | # BAD things can happen otherwise! | 427 | # BAD things can happen otherwise! |
412 | dlg.Destroy() | 428 | dlg.Destroy() |
413 | - os.chdir(current_dir) | ||
414 | return filename | 429 | return filename |
415 | 430 | ||
416 | 431 | ||
417 | def ShowImportMeshFilesDialog(): | 432 | def ShowImportMeshFilesDialog(): |
418 | # Default system path | 433 | # Default system path |
419 | current_dir = os.path.abspath(".") | 434 | current_dir = os.path.abspath(".") |
435 | + session = ses.Session() | ||
436 | + last_directory = session.get('paths', 'last_directory_surface_import', '') | ||
420 | dlg = wx.FileDialog(None, message=_("Import surface file"), | 437 | dlg = wx.FileDialog(None, message=_("Import surface file"), |
438 | + defaultDir=last_directory, | ||
421 | wildcard=WILDCARD_MESH_FILES, | 439 | wildcard=WILDCARD_MESH_FILES, |
422 | style=wx.FD_OPEN | wx.FD_CHANGE_DIR) | 440 | style=wx.FD_OPEN | wx.FD_CHANGE_DIR) |
423 | 441 | ||
@@ -435,6 +453,10 @@ def ShowImportMeshFilesDialog(): | @@ -435,6 +453,10 @@ def ShowImportMeshFilesDialog(): | ||
435 | if (dlg.GetPath()): | 453 | if (dlg.GetPath()): |
436 | filename = dlg.GetPath() | 454 | filename = dlg.GetPath() |
437 | 455 | ||
456 | + if filename: | ||
457 | + session['paths']['last_directory_surface_import'] = os.path.split(filename)[0] | ||
458 | + session.WriteSessionFile() | ||
459 | + | ||
438 | # Destroy the dialog. Don't do this until you are done with it! | 460 | # Destroy the dialog. Don't do this until you are done with it! |
439 | # BAD things can happen otherwise! | 461 | # BAD things can happen otherwise! |
440 | dlg.Destroy() | 462 | dlg.Destroy() |
@@ -444,9 +466,11 @@ def ShowImportMeshFilesDialog(): | @@ -444,9 +466,11 @@ def ShowImportMeshFilesDialog(): | ||
444 | 466 | ||
445 | def ShowSaveAsProjectDialog(default_filename=None): | 467 | def ShowSaveAsProjectDialog(default_filename=None): |
446 | current_dir = os.path.abspath(".") | 468 | current_dir = os.path.abspath(".") |
469 | + session = ses.Session() | ||
470 | + last_directory = session.get('paths', 'last_directory_inv3', '') | ||
447 | dlg = wx.FileDialog(None, | 471 | dlg = wx.FileDialog(None, |
448 | _("Save project as..."), # title | 472 | _("Save project as..."), # title |
449 | - "", # last used directory | 473 | + last_directory, # last used directory |
450 | default_filename, | 474 | default_filename, |
451 | WILDCARD_INV_SAVE, | 475 | WILDCARD_INV_SAVE, |
452 | wx.FD_SAVE|wx.FD_OVERWRITE_PROMPT) | 476 | wx.FD_SAVE|wx.FD_OVERWRITE_PROMPT) |
@@ -469,6 +493,10 @@ def ShowSaveAsProjectDialog(default_filename=None): | @@ -469,6 +493,10 @@ def ShowSaveAsProjectDialog(default_filename=None): | ||
469 | if filename.split(".")[-1] != extension: | 493 | if filename.split(".")[-1] != extension: |
470 | filename = filename + "." + extension | 494 | filename = filename + "." + extension |
471 | 495 | ||
496 | + if filename: | ||
497 | + session['paths']['last_directory_inv3'] = os.path.split(filename)[0] | ||
498 | + session.WriteSessionFile() | ||
499 | + | ||
472 | wildcard = dlg.GetFilterIndex() | 500 | wildcard = dlg.GetFilterIndex() |
473 | os.chdir(current_dir) | 501 | os.chdir(current_dir) |
474 | return filename, wildcard == INV_COMPRESSED | 502 | return filename, wildcard == INV_COMPRESSED |
@@ -1457,13 +1485,16 @@ def ExportPicture(type_=""): | @@ -1457,13 +1485,16 @@ def ExportPicture(type_=""): | ||
1457 | utils.debug("ExportPicture") | 1485 | utils.debug("ExportPicture") |
1458 | project = proj.Project() | 1486 | project = proj.Project() |
1459 | 1487 | ||
1488 | + session = ses.Session() | ||
1489 | + last_directory = session.get('paths', 'last_directory_screenshot', '') | ||
1490 | + | ||
1460 | project_name = "%s_%s" % (project.name, type_) | 1491 | project_name = "%s_%s" % (project.name, type_) |
1461 | if not sys.platform in ('win32', 'linux2', 'linux'): | 1492 | if not sys.platform in ('win32', 'linux2', 'linux'): |
1462 | project_name += ".jpg" | 1493 | project_name += ".jpg" |
1463 | 1494 | ||
1464 | dlg = wx.FileDialog(None, | 1495 | dlg = wx.FileDialog(None, |
1465 | "Save %s picture as..." %type_, | 1496 | "Save %s picture as..." %type_, |
1466 | - "", # last used directory | 1497 | + last_directory, # last used directory |
1467 | project_name, # filename | 1498 | project_name, # filename |
1468 | WILDCARD_SAVE_PICTURE, | 1499 | WILDCARD_SAVE_PICTURE, |
1469 | wx.FD_SAVE|wx.FD_OVERWRITE_PROMPT) | 1500 | wx.FD_SAVE|wx.FD_OVERWRITE_PROMPT) |
@@ -1474,6 +1505,8 @@ def ExportPicture(type_=""): | @@ -1474,6 +1505,8 @@ def ExportPicture(type_=""): | ||
1474 | filetype = INDEX_TO_TYPE[filetype_index] | 1505 | filetype = INDEX_TO_TYPE[filetype_index] |
1475 | extension = INDEX_TO_EXTENSION[filetype_index] | 1506 | extension = INDEX_TO_EXTENSION[filetype_index] |
1476 | filename = dlg.GetPath() | 1507 | filename = dlg.GetPath() |
1508 | + session['paths']['last_directory_screenshot'] = os.path.split(filename)[0] | ||
1509 | + session.WriteSessionFile() | ||
1477 | if sys.platform != 'win32': | 1510 | if sys.platform != 'win32': |
1478 | if filename.split(".")[-1] != extension: | 1511 | if filename.split(".")[-1] != extension: |
1479 | filename = filename + "."+ extension | 1512 | filename = filename + "."+ extension |
invesalius/gui/preferences.py
@@ -222,7 +222,7 @@ class Language(wx.Panel): | @@ -222,7 +222,7 @@ class Language(wx.Panel): | ||
222 | class SurfaceCreation(wx.Panel): | 222 | class SurfaceCreation(wx.Panel): |
223 | def __init__(self, parent): | 223 | def __init__(self, parent): |
224 | wx.Panel.__init__(self, parent) | 224 | wx.Panel.__init__(self, parent) |
225 | - self.rb_fill_border = wx.RadioBox(self, -1, "Fill border holes", choices=[_('Yes'), _('No')], style=wx.RA_SPECIFY_COLS | wx.NO_BORDER) | 225 | + self.rb_fill_border = wx.RadioBox(self, -1, _("Fill border holes"), choices=[_('Yes'), _('No')], style=wx.RA_SPECIFY_COLS | wx.NO_BORDER) |
226 | 226 | ||
227 | sizer = wx.BoxSizer(wx.VERTICAL) | 227 | sizer = wx.BoxSizer(wx.VERTICAL) |
228 | sizer.Add(self.rb_fill_border) | 228 | sizer.Add(self.rb_fill_border) |
invesalius/gui/task_exporter.py
@@ -33,6 +33,7 @@ from wx.lib.pubsub import pub as Publisher | @@ -33,6 +33,7 @@ from wx.lib.pubsub import pub as Publisher | ||
33 | import invesalius.constants as const | 33 | import invesalius.constants as const |
34 | import invesalius.gui.dialogs as dlg | 34 | import invesalius.gui.dialogs as dlg |
35 | import invesalius.project as proj | 35 | import invesalius.project as proj |
36 | +import invesalius.session as ses | ||
36 | 37 | ||
37 | BTN_MASK = wx.NewId() | 38 | BTN_MASK = wx.NewId() |
38 | BTN_PICTURE = wx.NewId() | 39 | BTN_PICTURE = wx.NewId() |
@@ -318,10 +319,12 @@ class InnerTaskPanel(wx.Panel): | @@ -318,10 +319,12 @@ class InnerTaskPanel(wx.Panel): | ||
318 | else: | 319 | else: |
319 | project_name = project.name+".stl" | 320 | project_name = project.name+".stl" |
320 | 321 | ||
322 | + session = ses.Session() | ||
323 | + last_directory = session.get('paths', 'last_directory_3d_surface', '') | ||
321 | 324 | ||
322 | dlg = wx.FileDialog(None, | 325 | dlg = wx.FileDialog(None, |
323 | _("Save 3D surface as..."), # title | 326 | _("Save 3D surface as..."), # title |
324 | - "", # last used directory | 327 | + last_directory, # last used directory |
325 | project_name, # filename | 328 | project_name, # filename |
326 | WILDCARD_SAVE_3D, | 329 | WILDCARD_SAVE_3D, |
327 | wx.FD_SAVE|wx.FD_OVERWRITE_PROMPT) | 330 | wx.FD_SAVE|wx.FD_OVERWRITE_PROMPT) |
@@ -335,6 +338,11 @@ class InnerTaskPanel(wx.Panel): | @@ -335,6 +338,11 @@ class InnerTaskPanel(wx.Panel): | ||
335 | if sys.platform != 'win32': | 338 | if sys.platform != 'win32': |
336 | if filename.split(".")[-1] != extension: | 339 | if filename.split(".")[-1] != extension: |
337 | filename = filename + "."+ extension | 340 | filename = filename + "."+ extension |
341 | + | ||
342 | + if filename: | ||
343 | + session['paths']['last_directory_3d_surface'] = os.path.split(filename)[0] | ||
344 | + session.WriteSessionFile() | ||
345 | + | ||
338 | Publisher.sendMessage('Export surface to file', | 346 | Publisher.sendMessage('Export surface to file', |
339 | filename=filename, filetype=filetype) | 347 | filename=filename, filetype=filetype) |
340 | if not os.path.exists(filename): | 348 | if not os.path.exists(filename): |
invesalius/session.py
@@ -30,6 +30,8 @@ import sys | @@ -30,6 +30,8 @@ import sys | ||
30 | from threading import Thread | 30 | from threading import Thread |
31 | import time | 31 | import time |
32 | import codecs | 32 | import codecs |
33 | +import collections | ||
34 | +import json | ||
33 | 35 | ||
34 | #import wx.lib.pubsub as ps | 36 | #import wx.lib.pubsub as ps |
35 | from wx.lib.pubsub import pub as Publisher | 37 | from wx.lib.pubsub import pub as Publisher |
@@ -52,7 +54,8 @@ else: | @@ -52,7 +54,8 @@ else: | ||
52 | USER_INV_DIR = os.path.join(USER_DIR, u'.invesalius') | 54 | USER_INV_DIR = os.path.join(USER_DIR, u'.invesalius') |
53 | USER_PRESET_DIR = os.path.join(USER_INV_DIR, u'presets') | 55 | USER_PRESET_DIR = os.path.join(USER_INV_DIR, u'presets') |
54 | USER_LOG_DIR = os.path.join(USER_INV_DIR, u'logs') | 56 | USER_LOG_DIR = os.path.join(USER_INV_DIR, u'logs') |
55 | -USER_INV_CFG_PATH = os.path.join(USER_INV_DIR, 'config.cfg') | 57 | +USER_INV_CFG_PATH = os.path.join(USER_INV_DIR, 'config.json') |
58 | +OLD_USER_INV_CFG_PATH = os.path.join(USER_INV_DIR, 'config.cfg') | ||
56 | 59 | ||
57 | SESSION_ENCODING = 'utf8' | 60 | SESSION_ENCODING = 'utf8' |
58 | 61 | ||
@@ -62,42 +65,98 @@ SESSION_ENCODING = 'utf8' | @@ -62,42 +65,98 @@ SESSION_ENCODING = 'utf8' | ||
62 | class Session(with_metaclass(Singleton, object)): | 65 | class Session(with_metaclass(Singleton, object)): |
63 | 66 | ||
64 | def __init__(self): | 67 | def __init__(self): |
68 | + self.project_path = () | ||
65 | self.temp_item = False | 69 | self.temp_item = False |
66 | - # Initializing as project status closed. | ||
67 | - # TODO: A better way to initialize project_status as closed (3) | ||
68 | - self.project_status = 3 | ||
69 | 70 | ||
70 | - def CreateItens(self): | ||
71 | - import invesalius.constants as const | ||
72 | - self.project_path = () | ||
73 | - self.debug = False | ||
74 | - self.project_status = const.PROJ_CLOSE | ||
75 | - # const.PROJ_NEW*, const.PROJ_OPEN, const.PROJ_CHANGE*, | ||
76 | - # const.PROJ_CLOSE | 71 | + self._values = collections.defaultdict(dict, { |
72 | + 'session': { | ||
73 | + 'status': 3, | ||
74 | + 'language': '', | ||
75 | + }, | ||
76 | + 'project': { | ||
77 | + }, | ||
78 | + | ||
79 | + 'paths': { | ||
80 | + } | ||
81 | + }) | ||
82 | + | ||
83 | + self._map_attrs = { | ||
84 | + 'mode': ('session', 'mode'), | ||
85 | + 'project_status': ('session', 'status'), | ||
86 | + 'debug': ('session', 'debug'), | ||
87 | + 'language': ('session', 'language'), | ||
88 | + 'random_id': ('session', 'random_id'), | ||
89 | + 'surface_interpolation': ('session', 'surface_interpolation'), | ||
90 | + 'rendering': ('session', 'rendering'), | ||
91 | + 'slice_interpolation': ('session', 'slice_interpolation'), | ||
92 | + 'recent_projects': ('project', 'recent_projects'), | ||
93 | + 'homedir': ('paths', 'homedir'), | ||
94 | + 'tempdir': ('paths', 'homedir'), | ||
95 | + 'last_dicom_folder': ('paths', 'last_dicom_folder'), | ||
96 | + } | ||
77 | 97 | ||
78 | - self.mode = const.MODE_RP | ||
79 | - # const.MODE_RP, const.MODE_NAVIGATOR, const.MODE_RADIOLOGY, | ||
80 | - # const.MODE_ODONTOLOGY | ||
81 | 98 | ||
82 | - # InVesalius default projects' directory | ||
83 | - homedir = self.homedir = USER_DIR | ||
84 | - tempdir = os.path.join(homedir, u".invesalius", u"temp") | 99 | + def CreateItens(self): |
100 | + import invesalius.constants as const | ||
101 | + homedir = USER_DIR | ||
102 | + tempdir = os.path.join(USER_DIR, u".invesalius", u"temp") | ||
85 | if not os.path.isdir(tempdir): | 103 | if not os.path.isdir(tempdir): |
86 | os.makedirs(tempdir) | 104 | os.makedirs(tempdir) |
87 | - self.tempdir = tempdir | ||
88 | - | ||
89 | - # GUI language | ||
90 | - self.language = "" # "pt_BR", "es" | ||
91 | 105 | ||
92 | - self.random_id = randint(0,pow(10,16)) | ||
93 | - | ||
94 | - # Recent projects list | ||
95 | - self.recent_projects = [(const.SAMPLE_DIR, u"Cranium.inv3")] | ||
96 | - self.last_dicom_folder = '' | ||
97 | - self.surface_interpolation = 1 | ||
98 | - self.slice_interpolation = 0 | ||
99 | - self.rendering = 0 | ||
100 | - self.WriteSessionFile() | 106 | + self._values = collections.defaultdict(dict, { |
107 | + 'session': { | ||
108 | + 'mode': const.MODE_RP, | ||
109 | + 'status': const.PROJ_CLOSE, | ||
110 | + 'debug': False, | ||
111 | + 'language': "", | ||
112 | + 'random_id': randint(0, pow(10,16)), | ||
113 | + 'surface_interpolation': 1, | ||
114 | + 'rendering': 0, | ||
115 | + 'slice_interpolation': 0, | ||
116 | + }, | ||
117 | + | ||
118 | + 'project': { | ||
119 | + 'recent_projects': [(const.SAMPLE_DIR, u"Cranium.inv3"), ], | ||
120 | + }, | ||
121 | + | ||
122 | + 'paths': { | ||
123 | + 'homedir': USER_DIR, | ||
124 | + 'tempdir': os.path.join(homedir, u".invesalius", u"temp"), | ||
125 | + 'last_dicom_folder': '', | ||
126 | + }, | ||
127 | + }) | ||
128 | + | ||
129 | + def __contains__(self, key): | ||
130 | + return key in self._values | ||
131 | + | ||
132 | + def __getitem__(self, key): | ||
133 | + return self._values[key] | ||
134 | + | ||
135 | + def __setitem__(self, key, value): | ||
136 | + self._values[key] = value | ||
137 | + | ||
138 | + def __getattr__(self, name): | ||
139 | + map_attrs = object.__getattribute__(self, '_map_attrs') | ||
140 | + if name not in map_attrs: | ||
141 | + raise AttributeError(name) | ||
142 | + session, key = map_attrs[name] | ||
143 | + return object.__getattribute__(self, '_values')[session][key] | ||
144 | + | ||
145 | + def __setattr__(self, name, value): | ||
146 | + if name in ("temp_item", "_map_attrs", "_values", "project_path"): | ||
147 | + return object.__setattr__(self, name, value) | ||
148 | + else: | ||
149 | + session, key = self._map_attrs[name] | ||
150 | + self._values[session][key] = value | ||
151 | + | ||
152 | + def __str__(self): | ||
153 | + return self._values.__str__() | ||
154 | + | ||
155 | + def get(self, session, key, default_value): | ||
156 | + try: | ||
157 | + return self._values[session][key] | ||
158 | + except KeyError: | ||
159 | + return default_value | ||
101 | 160 | ||
102 | def IsOpen(self): | 161 | def IsOpen(self): |
103 | import invesalius.constants as const | 162 | import invesalius.constants as const |
@@ -178,40 +237,17 @@ class Session(with_metaclass(Singleton, object)): | @@ -178,40 +237,17 @@ class Session(with_metaclass(Singleton, object)): | ||
178 | self.temp_item = False | 237 | self.temp_item = False |
179 | 238 | ||
180 | def WriteSessionFile(self): | 239 | def WriteSessionFile(self): |
181 | - config = ConfigParser.RawConfigParser() | ||
182 | - | ||
183 | - config.add_section('session') | ||
184 | - config.set('session', 'mode', self.mode) | ||
185 | - config.set('session', 'status', self.project_status) | ||
186 | - config.set('session','debug', self.debug) | ||
187 | - config.set('session', 'language', self.language) | ||
188 | - config.set('session', 'random_id', self.random_id) | ||
189 | - config.set('session', 'surface_interpolation', self.surface_interpolation) | ||
190 | - config.set('session', 'rendering', self.rendering) | ||
191 | - config.set('session', 'slice_interpolation', self.slice_interpolation) | ||
192 | - | ||
193 | - config.add_section('project') | ||
194 | - config.set('project', 'recent_projects', self.recent_projects) | ||
195 | - | ||
196 | - config.add_section('paths') | ||
197 | - config.set('paths','homedir',self.homedir) | ||
198 | - config.set('paths','tempdir',self.tempdir) | ||
199 | - config.set('paths','last_dicom_folder',self.last_dicom_folder) | ||
200 | - | ||
201 | - path = os.path.join(self.homedir , | ||
202 | - '.invesalius', 'config.cfg') | 240 | + self._write_to_json(self._values, USER_INV_CFG_PATH) |
203 | 241 | ||
204 | - configfile = codecs.open(path, 'wb', SESSION_ENCODING) | ||
205 | - try: | ||
206 | - config.write(configfile) | ||
207 | - except UnicodeDecodeError: | ||
208 | - pass | ||
209 | - configfile.close() | 242 | + def _write_to_json(self, cfg_dict, cfg_filename): |
243 | + with open(cfg_filename, 'w') as cfg_file: | ||
244 | + json.dump(cfg_dict, cfg_file, sort_keys=True, indent=4) | ||
210 | 245 | ||
211 | def __add_to_list(self, item): | 246 | def __add_to_list(self, item): |
212 | import invesalius.constants as const | 247 | import invesalius.constants as const |
213 | # Last projects list | 248 | # Last projects list |
214 | l = self.recent_projects | 249 | l = self.recent_projects |
250 | + item = list(item) | ||
215 | 251 | ||
216 | # If item exists, remove it from list | 252 | # If item exists, remove it from list |
217 | if l.count(item): | 253 | if l.count(item): |
@@ -219,11 +255,7 @@ class Session(with_metaclass(Singleton, object)): | @@ -219,11 +255,7 @@ class Session(with_metaclass(Singleton, object)): | ||
219 | 255 | ||
220 | # Add new item | 256 | # Add new item |
221 | l.insert(0, item) | 257 | l.insert(0, item) |
222 | - | ||
223 | - # Remove oldest projects from list | ||
224 | - if len(l)>const.PROJ_MAX: | ||
225 | - for i in range(len(l)-const.PROJ_MAX): | ||
226 | - l.pop() | 258 | + self.recent_projects = l[:const.PROJ_MAX] |
227 | 259 | ||
228 | def GetLanguage(self): | 260 | def GetLanguage(self): |
229 | return self.language | 261 | return self.language |
@@ -244,86 +276,59 @@ class Session(with_metaclass(Singleton, object)): | @@ -244,86 +276,59 @@ class Session(with_metaclass(Singleton, object)): | ||
244 | self.last_dicom_folder = folder | 276 | self.last_dicom_folder = folder |
245 | self.WriteSessionFile() | 277 | self.WriteSessionFile() |
246 | 278 | ||
247 | - def ReadLanguage(self): | ||
248 | - config = ConfigParser.ConfigParser() | ||
249 | - path = os.path.join(USER_INV_DIR, 'config.cfg') | ||
250 | - try: | ||
251 | - f = codecs.open(path, 'rb', SESSION_ENCODING) | ||
252 | - config.readfp(f) | ||
253 | - f.close() | ||
254 | - self.language = config.get('session','language') | ||
255 | - return self.language | ||
256 | - except IOError: | ||
257 | - return False | ||
258 | - except (ConfigParser.NoSectionError, | ||
259 | - ConfigParser.NoOptionError, | ||
260 | - ConfigParser.MissingSectionHeaderError): | ||
261 | - return False | ||
262 | - | ||
263 | - def ReadRandomId(self): | ||
264 | - config = ConfigParser.ConfigParser() | ||
265 | - path = os.path.join(USER_INV_DIR, 'config.cfg') | ||
266 | - try: | ||
267 | - f = codecs.open(path, 'rb', SESSION_ENCODING) | ||
268 | - config.readfp(f) | ||
269 | - f.close() | ||
270 | - self.random_id = config.get('session','random_id') | ||
271 | - return self.random_id | ||
272 | - except IOError: | ||
273 | - return False | ||
274 | - except (ConfigParser.NoSectionError, | ||
275 | - ConfigParser.NoOptionError, | ||
276 | - ConfigParser.MissingSectionHeaderError): | ||
277 | - return False | ||
278 | - | ||
279 | - def ReadSession(self): | ||
280 | - config = ConfigParser.ConfigParser() | ||
281 | - path = USER_INV_CFG_PATH | ||
282 | - try: | ||
283 | - f = codecs.open(path, 'rb', SESSION_ENCODING) | ||
284 | - config.readfp(f) | ||
285 | - f.close() | ||
286 | - self.mode = config.get('session', 'mode') | ||
287 | - # Do not reading project status from the config file, since there | ||
288 | - # isn't a recover sessession tool in InVesalius | ||
289 | - #self.project_status = int(config.get('session', 'status')) | ||
290 | - self.debug = config.get('session','debug') | ||
291 | - self.language = config.get('session','language') | ||
292 | - self.recent_projects = eval(config.get('project','recent_projects')) | ||
293 | - self.homedir = config.get('paths','homedir') | ||
294 | - self.tempdir = config.get('paths','tempdir') | ||
295 | - self.last_dicom_folder = config.get('paths','last_dicom_folder') | ||
296 | - | ||
297 | - #if not(sys.platform == 'win32'): | ||
298 | - # self.last_dicom_folder = self.last_dicom_folder.decode('utf-8') | ||
299 | - | ||
300 | - self.surface_interpolation = config.get('session', 'surface_interpolation') | ||
301 | - self.slice_interpolation = config.get('session', 'slice_interpolation') | ||
302 | - | ||
303 | - self.rendering = config.get('session', 'rendering') | ||
304 | - self.random_id = config.get('session','random_id') | ||
305 | - return True | 279 | + def _update_cfg_from_dict(self, config, cfg_dict): |
280 | + for session in cfg_dict: | ||
281 | + if cfg_dict[session] and isinstance(cfg_dict[session], dict): | ||
282 | + config.add_section(session) | ||
283 | + for key in cfg_dict[session]: | ||
284 | + config.set(session, key, cfg_dict[session][key]) | ||
306 | 285 | ||
307 | - except IOError: | ||
308 | - return False | 286 | + def _read_cfg_from_json(self, json_filename): |
287 | + with open(json_filename, 'r') as cfg_file: | ||
288 | + cfg_dict = json.load(cfg_file) | ||
289 | + self._values.update(cfg_dict) | ||
309 | 290 | ||
310 | - except(ConfigParser.NoSectionError, ConfigParser.MissingSectionHeaderError, | ||
311 | - ConfigParser.ParsingError): | 291 | + # Do not reading project status from the config file, since there |
292 | + # isn't a recover session tool in InVesalius yet. | ||
293 | + self.project_status = 3 | ||
312 | 294 | ||
313 | - if (self.RecoveryConfigFile()): | ||
314 | - self.ReadSession() | ||
315 | - return True | ||
316 | - else: | ||
317 | - return False | 295 | + def _read_cfg_from_ini(self, cfg_filename): |
296 | + f = codecs.open(cfg_filename, 'rb', SESSION_ENCODING) | ||
297 | + config = ConfigParser.ConfigParser() | ||
298 | + config.readfp(f) | ||
299 | + f.close() | ||
300 | + | ||
301 | + self.mode = config.getint('session', 'mode') | ||
302 | + # Do not reading project status from the config file, since there | ||
303 | + # isn't a recover sessession tool in InVesalius | ||
304 | + #self.project_status = int(config.get('session', 'status')) | ||
305 | + self.debug = config.getboolean('session','debug') | ||
306 | + self.language = config.get('session','language') | ||
307 | + recent_projects = eval(config.get('project','recent_projects')) | ||
308 | + self.recent_projects = [list(rp) for rp in recent_projects] | ||
309 | + self.homedir = config.get('paths','homedir') | ||
310 | + self.tempdir = config.get('paths','tempdir') | ||
311 | + self.last_dicom_folder = config.get('paths','last_dicom_folder') | ||
312 | + | ||
313 | + # if not(sys.platform == 'win32'): | ||
314 | + # self.last_dicom_folder = self.last_dicom_folder.decode('utf-8') | ||
315 | + | ||
316 | + self.surface_interpolation = config.getint('session', 'surface_interpolation') | ||
317 | + self.slice_interpolation = config.getint('session', 'slice_interpolation') | ||
318 | + | ||
319 | + self.rendering = config.getint('session', 'rendering') | ||
320 | + self.random_id = config.getint('session','random_id') | ||
318 | 321 | ||
319 | - except(ConfigParser.NoOptionError): | ||
320 | - #Added to fix new version compatibility | ||
321 | - self.surface_interpolation = 0 | ||
322 | - self.slice_interpolation = 0 | ||
323 | - self.rendering = 0 | ||
324 | - self.random_id = randint(0,pow(10,16)) | 322 | + def ReadSession(self): |
323 | + try: | ||
324 | + self._read_cfg_from_json(USER_INV_CFG_PATH) | ||
325 | + except Exception as e1: | ||
326 | + debug(e1) | ||
325 | try: | 327 | try: |
326 | - self.WriteSessionFile() | ||
327 | - except AttributeError: | 328 | + self._read_cfg_from_ini(OLD_USER_INV_CFG_PATH) |
329 | + except Exception as e2: | ||
330 | + debug(e2) | ||
328 | return False | 331 | return False |
329 | - return True | 332 | + |
333 | + self.WriteSessionFile() | ||
334 | + return True |
invesalius/utils.py
@@ -394,21 +394,14 @@ def UpdateCheck(): | @@ -394,21 +394,14 @@ def UpdateCheck(): | ||
394 | #msgdlg.Destroy() | 394 | #msgdlg.Destroy() |
395 | 395 | ||
396 | print("Checking updates...") | 396 | print("Checking updates...") |
397 | - | 397 | + |
398 | # Check if there is a language set | 398 | # Check if there is a language set |
399 | #import invesalius.i18n as i18n import invesalius.session as ses | 399 | #import invesalius.i18n as i18n import invesalius.session as ses |
400 | session = ses.Session() | 400 | session = ses.Session() |
401 | install_lang = 0 | 401 | install_lang = 0 |
402 | - if session.ReadLanguage(): | ||
403 | - lang = session.GetLanguage() | ||
404 | - #if (lang != "False"): | ||
405 | - #_ = i18n.InstallLanguage(lang) | ||
406 | - #install_lang = 1 | ||
407 | - #if (install_lang==0): | ||
408 | - #return | ||
409 | - if session.ReadRandomId(): | ||
410 | - random_id = session.GetRandomId() | ||
411 | - | 402 | + lang = session.GetLanguage() |
403 | + random_id = session.GetRandomId() | ||
404 | + if lang: | ||
412 | # Fetch update data from server | 405 | # Fetch update data from server |
413 | import invesalius.constants as const | 406 | import invesalius.constants as const |
414 | url = "https://www.cti.gov.br/dt3d/invesalius/update/checkupdate.php" | 407 | url = "https://www.cti.gov.br/dt3d/invesalius/update/checkupdate.php" |