@@ -99,13 +99,19 @@ def __init__(self, config: ApplicationSettings | None = None):
9999 self ._model_path_store = ModelPathStore (self .settings )
100100 self ._settings_store = DLCLiveGUISettingsStore (self .settings )
101101
102+ last_cfg_path = self ._settings_store .get_last_config_path ()
103+ last_cfg_file = self ._valid_config_file_path (last_cfg_path )
102104 if config is None :
103105 # 1) snapshot
104106 cfg = self ._settings_store .load_full_config_snapshot ()
105107 if cfg is not None :
106108 config = cfg
107- self ._config_path = None
108- logger .info ("Loaded configuration from QSettings snapshot." )
109+ self ._config_path = last_cfg_file
110+ if self ._config_path is not None :
111+ logger .info (f"Loaded configuration from QSettings snapshot; associated file: { self ._config_path } " )
112+ else :
113+ logger .info ("Loaded configuration from QSettings snapshot without associated config file." )
114+
109115 else :
110116 # 2) last config file path
111117 last_cfg_path = self ._settings_store .get_last_config_path ()
@@ -226,6 +232,19 @@ def resizeEvent(self, event):
226232 if not self .multi_camera_controller .is_running ():
227233 self ._show_logo_and_text ()
228234
235+ def _valid_config_file_path (self , path : str | None ) -> Path | None :
236+ if not path :
237+ return None
238+
239+ try :
240+ p = Path (path ).expanduser ()
241+ if p .exists () and p .is_file ():
242+ return p .resolve ()
243+ except Exception :
244+ logger .debug ("Invalid config file path: %s" , path , exc_info = True )
245+
246+ return None
247+
229248 # ------------------------------------------------------------------ UI
230249 def _init_theme_actions (self ) -> None :
231250 """Set initial checked state for theme actions based on current app stylesheet."""
@@ -1011,10 +1030,36 @@ def _visualization_settings_from_ui(self) -> VisualizationSettings:
10111030 bbox_color = self ._bbox_color ,
10121031 )
10131032
1033+ def _suggest_config_dialog_path (self ) -> str :
1034+ """Return best initial path for load/save config dialogs."""
1035+ if getattr (self , "_config_path" , None ) is not None :
1036+ try :
1037+ return str (self ._config_path )
1038+ except Exception :
1039+ pass
1040+
1041+ last_cfg = self ._settings_store .get_last_config_path ()
1042+ valid_last = self ._valid_config_file_path (last_cfg )
1043+ if valid_last is not None :
1044+ return str (valid_last )
1045+
1046+ if last_cfg :
1047+ try :
1048+ p = Path (last_cfg ).expanduser ()
1049+ parent = p .parent
1050+ if parent .exists () and parent .is_dir ():
1051+ return str (parent / (p .name or "config.json" ))
1052+ except Exception :
1053+ logger .debug ("Failed to derive config dialog path from %s" , last_cfg , exc_info = True )
1054+
1055+ return str (Path .home () / "config.json" )
1056+
10141057 # ------------------------------------------------------------------
10151058 # Actions
10161059 def _action_load_config (self ) -> None :
1017- file_name , _ = QFileDialog .getOpenFileName (self , "Load configuration" , str (Path .home ()), "JSON files (*.json)" )
1060+ file_name , _ = QFileDialog .getOpenFileName (
1061+ self , "Load configuration" , self ._suggest_config_dialog_path (), "JSON files (*.json)"
1062+ )
10181063 if not file_name :
10191064 return
10201065 try :
@@ -1024,6 +1069,12 @@ def _action_load_config(self) -> None:
10241069 return
10251070 self ._settings_store .set_last_config_path (file_name )
10261071 self ._settings_store .save_full_config_snapshot (config )
1072+
1073+ try :
1074+ self .settings .sync ()
1075+ except Exception :
1076+ logger .debug ("Failed to sync settings after loading config" , exc_info = True )
1077+
10271078 self ._config = config
10281079 self ._config_path = Path (file_name )
10291080 self ._apply_config (config )
@@ -1035,28 +1086,32 @@ def _action_save_config(self) -> None:
10351086 if self ._config_path is None :
10361087 self ._action_save_config_as ()
10371088 return
1038- self ._save_config_to_path (self ._config_path )
1089+ if self ._save_config_to_path (self ._config_path ):
1090+ self ._config_path = self ._config_path .expanduser ()
10391091
10401092 def _action_save_config_as (self ) -> None :
1041- file_name , _ = QFileDialog .getSaveFileName (self , "Save configuration" , str (Path .home ()), "JSON files (*.json)" )
1093+ file_name , _ = QFileDialog .getSaveFileName (
1094+ self , "Save configuration" , self ._suggest_config_dialog_path (), "JSON files (*.json)"
1095+ )
10421096 if not file_name :
10431097 return
1044- path = Path (file_name )
1098+ path = Path (file_name ). expanduser ()
10451099 if path .suffix .lower () != ".json" :
10461100 path = path .with_suffix (".json" )
1047- self ._config_path = path
1048- self ._save_config_to_path ( path )
1101+ if self ._save_config_to_path ( path ):
1102+ self ._config_path = path
10491103
1050- def _save_config_to_path (self , path : Path ) -> None :
1104+ def _save_config_to_path (self , path : Path ) -> bool :
10511105 try :
10521106 config = self ._current_config (allow_empty_model_path = True )
10531107 config .save (path )
10541108 self ._settings_store .set_last_config_path (str (path ))
10551109 self ._settings_store .save_full_config_snapshot (config )
10561110 except Exception as exc : # pragma: no cover - GUI interaction
10571111 self ._show_error (str (exc ))
1058- return
1112+ return False
10591113 self .statusBar ().showMessage (f"Saved configuration to { path } " , 5000 )
1114+ return True
10601115
10611116 def _action_browse_model (self ) -> None :
10621117 # Prefer persisted last-used directory, then config.dlc.model_directory, then home
0 commit comments