@@ -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."""
@@ -1013,10 +1032,36 @@ def _visualization_settings_from_ui(self) -> VisualizationSettings:
10131032 bbox_color = self ._bbox_color ,
10141033 )
10151034
1035+ def _suggest_config_dialog_path (self ) -> str :
1036+ """Return best initial path for load/save config dialogs."""
1037+ if getattr (self , "_config_path" , None ) is not None :
1038+ try :
1039+ return str (self ._config_path )
1040+ except Exception :
1041+ pass
1042+
1043+ last_cfg = self ._settings_store .get_last_config_path ()
1044+ valid_last = self ._valid_config_file_path (last_cfg )
1045+ if valid_last is not None :
1046+ return str (valid_last )
1047+
1048+ if last_cfg :
1049+ try :
1050+ p = Path (last_cfg ).expanduser ()
1051+ parent = p .parent
1052+ if parent .exists () and parent .is_dir ():
1053+ return str (parent / (p .name or "config.json" ))
1054+ except Exception :
1055+ logger .debug ("Failed to derive config dialog path from %s" , last_cfg , exc_info = True )
1056+
1057+ return str (Path .home () / "config.json" )
1058+
10161059 # ------------------------------------------------------------------
10171060 # Actions
10181061 def _action_load_config (self ) -> None :
1019- file_name , _ = QFileDialog .getOpenFileName (self , "Load configuration" , str (Path .home ()), "JSON files (*.json)" )
1062+ file_name , _ = QFileDialog .getOpenFileName (
1063+ self , "Load configuration" , self ._suggest_config_dialog_path (), "JSON files (*.json)"
1064+ )
10201065 if not file_name :
10211066 return
10221067 try :
@@ -1026,6 +1071,12 @@ def _action_load_config(self) -> None:
10261071 return
10271072 self ._settings_store .set_last_config_path (file_name )
10281073 self ._settings_store .save_full_config_snapshot (config )
1074+
1075+ try :
1076+ self .settings .sync ()
1077+ except Exception :
1078+ logger .debug ("Failed to sync settings after loading config" , exc_info = True )
1079+
10291080 self ._config = config
10301081 self ._config_path = Path (file_name )
10311082 self ._apply_config (config )
@@ -1037,28 +1088,32 @@ def _action_save_config(self) -> None:
10371088 if self ._config_path is None :
10381089 self ._action_save_config_as ()
10391090 return
1040- self ._save_config_to_path (self ._config_path )
1091+ if self ._save_config_to_path (self ._config_path ):
1092+ self ._config_path = self ._config_path .expanduser ()
10411093
10421094 def _action_save_config_as (self ) -> None :
1043- file_name , _ = QFileDialog .getSaveFileName (self , "Save configuration" , str (Path .home ()), "JSON files (*.json)" )
1095+ file_name , _ = QFileDialog .getSaveFileName (
1096+ self , "Save configuration" , self ._suggest_config_dialog_path (), "JSON files (*.json)"
1097+ )
10441098 if not file_name :
10451099 return
1046- path = Path (file_name )
1100+ path = Path (file_name ). expanduser ()
10471101 if path .suffix .lower () != ".json" :
10481102 path = path .with_suffix (".json" )
1049- self ._config_path = path
1050- self ._save_config_to_path ( path )
1103+ if self ._save_config_to_path ( path ):
1104+ self ._config_path = path
10511105
1052- def _save_config_to_path (self , path : Path ) -> None :
1106+ def _save_config_to_path (self , path : Path ) -> bool :
10531107 try :
10541108 config = self ._current_config (allow_empty_model_path = True )
10551109 config .save (path )
10561110 self ._settings_store .set_last_config_path (str (path ))
10571111 self ._settings_store .save_full_config_snapshot (config )
10581112 except Exception as exc : # pragma: no cover - GUI interaction
10591113 self ._show_error (str (exc ))
1060- return
1114+ return False
10611115 self .statusBar ().showMessage (f"Saved configuration to { path } " , 5000 )
1116+ return True
10621117
10631118 def _action_browse_model (self ) -> None :
10641119 # Prefer persisted last-used directory, then config.dlc.model_directory, then home
0 commit comments