@@ -98,13 +98,19 @@ def __init__(self, config: ApplicationSettings | None = None):
9898 self ._model_path_store = ModelPathStore (self .settings )
9999 self ._settings_store = DLCLiveGUISettingsStore (self .settings )
100100
101+ last_cfg_path = self ._settings_store .get_last_config_path ()
102+ last_cfg_file = self ._valid_config_file_path (last_cfg_path )
101103 if config is None :
102104 # 1) snapshot
103105 cfg = self ._settings_store .load_full_config_snapshot ()
104106 if cfg is not None :
105107 config = cfg
106- self ._config_path = None
107- logger .info ("Loaded configuration from QSettings snapshot." )
108+ self ._config_path = last_cfg_file
109+ if self ._config_path is not None :
110+ logger .info (f"Loaded configuration from QSettings snapshot; associated file: { self ._config_path } " )
111+ else :
112+ logger .info ("Loaded configuration from QSettings snapshot without associated config file." )
113+
108114 else :
109115 # 2) last config file path
110116 last_cfg_path = self ._settings_store .get_last_config_path ()
@@ -225,6 +231,19 @@ def resizeEvent(self, event):
225231 if not self .multi_camera_controller .is_running ():
226232 self ._show_logo_and_text ()
227233
234+ def _valid_config_file_path (self , path : str | None ) -> Path | None :
235+ if not path :
236+ return None
237+
238+ try :
239+ p = Path (path ).expanduser ()
240+ if p .exists () and p .is_file ():
241+ return p .resolve ()
242+ except Exception :
243+ logger .debug ("Invalid config file path: %s" , path , exc_info = True )
244+
245+ return None
246+
228247 # ------------------------------------------------------------------ UI
229248 def _init_theme_actions (self ) -> None :
230249 """Set initial checked state for theme actions based on current app stylesheet."""
@@ -1010,10 +1029,36 @@ def _visualization_settings_from_ui(self) -> VisualizationSettings:
10101029 bbox_color = self ._bbox_color ,
10111030 )
10121031
1032+ def _suggest_config_dialog_path (self ) -> str :
1033+ """Return best initial path for load/save config dialogs."""
1034+ if getattr (self , "_config_path" , None ) is not None :
1035+ try :
1036+ return str (self ._config_path )
1037+ except Exception :
1038+ pass
1039+
1040+ last_cfg = self ._settings_store .get_last_config_path ()
1041+ valid_last = self ._valid_config_file_path (last_cfg )
1042+ if valid_last is not None :
1043+ return str (valid_last )
1044+
1045+ if last_cfg :
1046+ try :
1047+ p = Path (last_cfg ).expanduser ()
1048+ parent = p .parent
1049+ if parent .exists () and parent .is_dir ():
1050+ return str (parent / (p .name or "config.json" ))
1051+ except Exception :
1052+ logger .debug ("Failed to derive config dialog path from %s" , last_cfg , exc_info = True )
1053+
1054+ return str (Path .home () / "config.json" )
1055+
10131056 # ------------------------------------------------------------------
10141057 # Actions
10151058 def _action_load_config (self ) -> None :
1016- file_name , _ = QFileDialog .getOpenFileName (self , "Load configuration" , str (Path .home ()), "JSON files (*.json)" )
1059+ file_name , _ = QFileDialog .getOpenFileName (
1060+ self , "Load configuration" , self ._suggest_config_dialog_path (), "JSON files (*.json)"
1061+ )
10171062 if not file_name :
10181063 return
10191064 try :
@@ -1023,6 +1068,12 @@ def _action_load_config(self) -> None:
10231068 return
10241069 self ._settings_store .set_last_config_path (file_name )
10251070 self ._settings_store .save_full_config_snapshot (config )
1071+
1072+ try :
1073+ self .settings .sync ()
1074+ except Exception :
1075+ logger .debug ("Failed to sync settings after loading config" , exc_info = True )
1076+
10261077 self ._config = config
10271078 self ._config_path = Path (file_name )
10281079 self ._apply_config (config )
@@ -1034,28 +1085,32 @@ def _action_save_config(self) -> None:
10341085 if self ._config_path is None :
10351086 self ._action_save_config_as ()
10361087 return
1037- self ._save_config_to_path (self ._config_path )
1088+ if self ._save_config_to_path (self ._config_path ):
1089+ self ._config_path = self ._config_path .expanduser ()
10381090
10391091 def _action_save_config_as (self ) -> None :
1040- file_name , _ = QFileDialog .getSaveFileName (self , "Save configuration" , str (Path .home ()), "JSON files (*.json)" )
1092+ file_name , _ = QFileDialog .getSaveFileName (
1093+ self , "Save configuration" , self ._suggest_config_dialog_path (), "JSON files (*.json)"
1094+ )
10411095 if not file_name :
10421096 return
1043- path = Path (file_name )
1097+ path = Path (file_name ). expanduser ()
10441098 if path .suffix .lower () != ".json" :
10451099 path = path .with_suffix (".json" )
1046- self ._config_path = path
1047- self ._save_config_to_path ( path )
1100+ if self ._save_config_to_path ( path ):
1101+ self ._config_path = path
10481102
1049- def _save_config_to_path (self , path : Path ) -> None :
1103+ def _save_config_to_path (self , path : Path ) -> bool :
10501104 try :
10511105 config = self ._current_config (allow_empty_model_path = True )
10521106 config .save (path )
10531107 self ._settings_store .set_last_config_path (str (path ))
10541108 self ._settings_store .save_full_config_snapshot (config )
10551109 except Exception as exc : # pragma: no cover - GUI interaction
10561110 self ._show_error (str (exc ))
1057- return
1111+ return False
10581112 self .statusBar ().showMessage (f"Saved configuration to { path } " , 5000 )
1113+ return True
10591114
10601115 def _action_browse_model (self ) -> None :
10611116 # Prefer persisted last-used directory, then config.dlc.model_directory, then home
0 commit comments