config-cli-gui 0.3.5__tar.gz → 0.3.7__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (87) hide show
  1. {config_cli_gui-0.3.5 → config_cli_gui-0.3.7}/HISTORY.md +13 -0
  2. {config_cli_gui-0.3.5/src/config_cli_gui.egg-info → config_cli_gui-0.3.7}/PKG-INFO +1 -1
  3. {config_cli_gui-0.3.5 → config_cli_gui-0.3.7}/src/config_cli_gui/_version.py +3 -3
  4. {config_cli_gui-0.3.5 → config_cli_gui-0.3.7}/src/config_cli_gui/config.py +29 -10
  5. {config_cli_gui-0.3.5 → config_cli_gui-0.3.7/src/config_cli_gui.egg-info}/PKG-INFO +1 -1
  6. {config_cli_gui-0.3.5 → config_cli_gui-0.3.7}/src/config_cli_gui.egg-info/SOURCES.txt +2 -0
  7. config_cli_gui-0.3.7/src/config_cli_gui.egg-info/scm_file_list.json +80 -0
  8. config_cli_gui-0.3.7/src/config_cli_gui.egg-info/scm_version.json +8 -0
  9. {config_cli_gui-0.3.5 → config_cli_gui-0.3.7}/tests/example_project/cli/cli_example.py +4 -4
  10. {config_cli_gui-0.3.5 → config_cli_gui-0.3.7}/tests/example_project/config/config_example.py +11 -2
  11. {config_cli_gui-0.3.5 → config_cli_gui-0.3.7}/tests/example_project/gui/gui_example.py +40 -6
  12. {config_cli_gui-0.3.5 → config_cli_gui-0.3.7}/tests/test_cli.py +2 -2
  13. {config_cli_gui-0.3.5 → config_cli_gui-0.3.7}/tests/test_generic_cli.py +5 -5
  14. {config_cli_gui-0.3.5 → config_cli_gui-0.3.7}/.github/FUNDING.yml +0 -0
  15. {config_cli_gui-0.3.5 → config_cli_gui-0.3.7}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  16. {config_cli_gui-0.3.5 → config_cli_gui-0.3.7}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  17. {config_cli_gui-0.3.5 → config_cli_gui-0.3.7}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  18. {config_cli_gui-0.3.5 → config_cli_gui-0.3.7}/.github/actions/setup-environment/action.yml +0 -0
  19. {config_cli_gui-0.3.5 → config_cli_gui-0.3.7}/.github/dependabot.yml +0 -0
  20. {config_cli_gui-0.3.5 → config_cli_gui-0.3.7}/.github/init.sh +0 -0
  21. {config_cli_gui-0.3.5 → config_cli_gui-0.3.7}/.github/release_message.sh +0 -0
  22. {config_cli_gui-0.3.5 → config_cli_gui-0.3.7}/.github/update_funding.py +0 -0
  23. {config_cli_gui-0.3.5 → config_cli_gui-0.3.7}/.github/workflows/main.yml +0 -0
  24. {config_cli_gui-0.3.5 → config_cli_gui-0.3.7}/.github/workflows/release.yml +0 -0
  25. {config_cli_gui-0.3.5 → config_cli_gui-0.3.7}/.github/workflows/update_readme.yml +0 -0
  26. {config_cli_gui-0.3.5 → config_cli_gui-0.3.7}/.gitignore +0 -0
  27. {config_cli_gui-0.3.5 → config_cli_gui-0.3.7}/.idea/runConfigurations/config_generate.xml +0 -0
  28. {config_cli_gui-0.3.5 → config_cli_gui-0.3.7}/.idea/runConfigurations/example_project_cli.xml +0 -0
  29. {config_cli_gui-0.3.5 → config_cli_gui-0.3.7}/.idea/runConfigurations/example_project_gui.xml +0 -0
  30. {config_cli_gui-0.3.5 → config_cli_gui-0.3.7}/.pre-commit-config.yaml +0 -0
  31. {config_cli_gui-0.3.5 → config_cli_gui-0.3.7}/.readthedocs.yaml +0 -0
  32. {config_cli_gui-0.3.5 → config_cli_gui-0.3.7}/LICENSE +0 -0
  33. {config_cli_gui-0.3.5 → config_cli_gui-0.3.7}/Makefile +0 -0
  34. {config_cli_gui-0.3.5 → config_cli_gui-0.3.7}/README.md +0 -0
  35. {config_cli_gui-0.3.5 → config_cli_gui-0.3.7}/config.yaml +0 -0
  36. {config_cli_gui-0.3.5 → config_cli_gui-0.3.7}/docs/.nav.yml +0 -0
  37. {config_cli_gui-0.3.5 → config_cli_gui-0.3.7}/docs/_static/img/favicon.png +0 -0
  38. {config_cli_gui-0.3.5 → config_cli_gui-0.3.7}/docs/_static/img/logo.png +0 -0
  39. {config_cli_gui-0.3.5 → config_cli_gui-0.3.7}/docs/_static/img/settings_dlg.png +0 -0
  40. {config_cli_gui-0.3.5 → config_cli_gui-0.3.7}/docs/_static/img/settings_doc.png +0 -0
  41. {config_cli_gui-0.3.5 → config_cli_gui-0.3.7}/docs/css/custom.css +0 -0
  42. {config_cli_gui-0.3.5 → config_cli_gui-0.3.7}/docs/develop/contributing.md +0 -0
  43. {config_cli_gui-0.3.5 → config_cli_gui-0.3.7}/docs/develop/make_windows.md +0 -0
  44. {config_cli_gui-0.3.5 → config_cli_gui-0.3.7}/docs/develop/naming_convention.md +0 -0
  45. {config_cli_gui-0.3.5 → config_cli_gui-0.3.7}/docs/funding/funding.md +0 -0
  46. {config_cli_gui-0.3.5 → config_cli_gui-0.3.7}/docs/getting-started/install.md +0 -0
  47. {config_cli_gui-0.3.5 → config_cli_gui-0.3.7}/docs/getting-started/virtual-environment.md +0 -0
  48. {config_cli_gui-0.3.5 → config_cli_gui-0.3.7}/docs/index.md +0 -0
  49. {config_cli_gui-0.3.5 → config_cli_gui-0.3.7}/docs/usage/cli.md +0 -0
  50. {config_cli_gui-0.3.5 → config_cli_gui-0.3.7}/docs/usage/config.md +0 -0
  51. {config_cli_gui-0.3.5 → config_cli_gui-0.3.7}/mkdocs.yml +0 -0
  52. {config_cli_gui-0.3.5 → config_cli_gui-0.3.7}/pyproject.toml +0 -0
  53. {config_cli_gui-0.3.5 → config_cli_gui-0.3.7}/scripts/show_filelist.ps1 +0 -0
  54. {config_cli_gui-0.3.5 → config_cli_gui-0.3.7}/scripts/show_tree.ps1 +0 -0
  55. {config_cli_gui-0.3.5 → config_cli_gui-0.3.7}/scripts/show_tree.py +0 -0
  56. {config_cli_gui-0.3.5 → config_cli_gui-0.3.7}/scripts/update_readme.py +0 -0
  57. {config_cli_gui-0.3.5 → config_cli_gui-0.3.7}/setup.cfg +0 -0
  58. {config_cli_gui-0.3.5 → config_cli_gui-0.3.7}/src/__init__.py +0 -0
  59. {config_cli_gui-0.3.5 → config_cli_gui-0.3.7}/src/config_cli_gui/__init__.py +0 -0
  60. {config_cli_gui-0.3.5 → config_cli_gui-0.3.7}/src/config_cli_gui/cli.py +0 -0
  61. {config_cli_gui-0.3.5 → config_cli_gui-0.3.7}/src/config_cli_gui/configtypes/__init__.py +0 -0
  62. {config_cli_gui-0.3.5 → config_cli_gui-0.3.7}/src/config_cli_gui/configtypes/color.py +0 -0
  63. {config_cli_gui-0.3.5 → config_cli_gui-0.3.7}/src/config_cli_gui/configtypes/font.py +0 -0
  64. {config_cli_gui-0.3.5 → config_cli_gui-0.3.7}/src/config_cli_gui/configtypes/vector.py +0 -0
  65. {config_cli_gui-0.3.5 → config_cli_gui-0.3.7}/src/config_cli_gui/docs.py +0 -0
  66. {config_cli_gui-0.3.5 → config_cli_gui-0.3.7}/src/config_cli_gui/gui.py +0 -0
  67. {config_cli_gui-0.3.5 → config_cli_gui-0.3.7}/src/config_cli_gui/logging.py +0 -0
  68. {config_cli_gui-0.3.5 → config_cli_gui-0.3.7}/src/config_cli_gui/persistence.py +0 -0
  69. {config_cli_gui-0.3.5 → config_cli_gui-0.3.7}/src/config_cli_gui.egg-info/dependency_links.txt +0 -0
  70. {config_cli_gui-0.3.5 → config_cli_gui-0.3.7}/src/config_cli_gui.egg-info/entry_points.txt +0 -0
  71. {config_cli_gui-0.3.5 → config_cli_gui-0.3.7}/src/config_cli_gui.egg-info/requires.txt +0 -0
  72. {config_cli_gui-0.3.5 → config_cli_gui-0.3.7}/src/config_cli_gui.egg-info/top_level.txt +0 -0
  73. {config_cli_gui-0.3.5 → config_cli_gui-0.3.7}/template.yml.url +0 -0
  74. {config_cli_gui-0.3.5 → config_cli_gui-0.3.7}/tests/__init__.py +0 -0
  75. {config_cli_gui-0.3.5 → config_cli_gui-0.3.7}/tests/example_project/__init__.py +0 -0
  76. {config_cli_gui-0.3.5 → config_cli_gui-0.3.7}/tests/example_project/__main__.py +0 -0
  77. {config_cli_gui-0.3.5 → config_cli_gui-0.3.7}/tests/example_project/cli/__init__.py +0 -0
  78. {config_cli_gui-0.3.5 → config_cli_gui-0.3.7}/tests/example_project/cli/__main__.py +0 -0
  79. {config_cli_gui-0.3.5 → config_cli_gui-0.3.7}/tests/example_project/config/__init__.py +0 -0
  80. {config_cli_gui-0.3.5 → config_cli_gui-0.3.7}/tests/example_project/core/__init__.py +0 -0
  81. {config_cli_gui-0.3.5 → config_cli_gui-0.3.7}/tests/example_project/core/base.py +0 -0
  82. {config_cli_gui-0.3.5 → config_cli_gui-0.3.7}/tests/example_project/example.gpx +0 -0
  83. {config_cli_gui-0.3.5 → config_cli_gui-0.3.7}/tests/example_project/gui/__init__.py +0 -0
  84. {config_cli_gui-0.3.5 → config_cli_gui-0.3.7}/tests/example_project/gui/__main__.py +0 -0
  85. {config_cli_gui-0.3.5 → config_cli_gui-0.3.7}/tests/test_config_manager.py +0 -0
  86. {config_cli_gui-0.3.5 → config_cli_gui-0.3.7}/tests/test_docs.py +0 -0
  87. {config_cli_gui-0.3.5 → config_cli_gui-0.3.7}/uv.lock +0 -0
@@ -4,6 +4,19 @@ Changelog
4
4
 
5
5
  (unreleased)
6
6
  ------------
7
+ - Keep last used config file. [Paul Magister]
8
+
9
+
10
+ 0.3.6 (2026-06-24)
11
+ ------------------
12
+ - Docs: Update HISTORY.md for release 0.3.6. [Paul Magister]
13
+ - Dynamically set app name for config persistence. [Paul Magister]
14
+ - Dynamically set app name for config persistence. [Paul Magister]
15
+
16
+
17
+ 0.3.5 (2026-06-18)
18
+ ------------------
19
+ - Docs: Update HISTORY.md for release 0.3.5. [Paul Magister]
7
20
  - Improve gui. [Paul Magister]
8
21
  - Fix gui log issue: even better fix. [Paul Magister]
9
22
  - Fix gui log issue: [Paul Magister]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: config-cli-gui
3
- Version: 0.3.5
3
+ Version: 0.3.7
4
4
  Summary: Feature-rich Python project template for config-cli-gui.
5
5
  Author: pamagister
6
6
  Requires-Python: <3.12,>=3.11
@@ -18,7 +18,7 @@ version_tuple: tuple[int | str, ...]
18
18
  commit_id: str | None
19
19
  __commit_id__: str | None
20
20
 
21
- __version__ = version = '0.3.5'
22
- __version_tuple__ = version_tuple = (0, 3, 5)
21
+ __version__ = version = '0.3.7'
22
+ __version_tuple__ = version_tuple = (0, 3, 7)
23
23
 
24
- __commit_id__ = commit_id = 'g089c3018c'
24
+ __commit_id__ = commit_id = 'g1115f5d6c'
@@ -185,11 +185,14 @@ class ConfigManager:
185
185
  self,
186
186
  categories: tuple[ConfigCategory, ...],
187
187
  config_file: str | None = None,
188
+ persist_last_used: bool = True,
188
189
  **overrides: Any,
189
190
  ):
190
191
  self._categories: dict[str, ConfigCategory] = {}
191
192
  self._serializer = ConfigSerializer()
192
193
  self.app: AppConfig = AppConfig()
194
+ # provide a default hook for application name retrieval; projects may
195
+ # override `get_app_name` on their concrete ConfigManager subclass.
193
196
 
194
197
  categories = (self.app, *categories)
195
198
  for category in categories:
@@ -198,10 +201,23 @@ class ConfigManager:
198
201
  self.add_category(category.get_category_name(), category)
199
202
 
200
203
  if config_file:
201
- self.load_from_file(config_file)
204
+ # Allow callers to opt-out of writing the "last used" persistence
205
+ # entry when loading a configuration during initialization. This
206
+ # is useful for GUIs or libraries that want to load a default
207
+ # config without marking it as the user's last-used file.
208
+ self.load_from_file(config_file, persist_last_used=persist_last_used)
202
209
 
203
210
  self.apply_overrides(overrides)
204
211
 
212
+ @staticmethod
213
+ def get_app_name() -> str:
214
+ """Return the application identifier used by persistence helpers.
215
+
216
+ Projects can override this method in their concrete ConfigManager to
217
+ provide a different name "my-app-name"
218
+ """
219
+ return "config-cli-gui"
220
+
205
221
  def add_category(self, name: str, category: ConfigCategory) -> None:
206
222
  """Register a new configuration category."""
207
223
  self._categories[name] = category
@@ -229,7 +245,7 @@ class ConfigManager:
229
245
  else:
230
246
  setattr(category, param_name, value)
231
247
 
232
- def load_from_file(self, config_file: str) -> None:
248
+ def load_from_file(self, config_file: str, persist_last_used: bool = True) -> None:
233
249
  """Load configuration from a YAML or JSON file."""
234
250
  path = Path(config_file)
235
251
  if not path.exists():
@@ -240,12 +256,15 @@ class ConfigManager:
240
256
 
241
257
  self._apply_config_data(data)
242
258
  # Persist the information about the last used configuration file so the
243
- # application can restore the same config on next start.
244
- try:
245
- persistence.write_last_used_config("config-cli-gui", str(path))
246
- except Exception:
247
- # Persistence should not break normal config loading.
248
- pass
259
+ # application can restore the same config on next start. This can be
260
+ # disabled by callers (e.g. GUI startup loading a default file) by
261
+ # passing `persist_last_used=False`.
262
+ if persist_last_used:
263
+ try:
264
+ persistence.write_last_used_config(self.get_app_name(), str(path))
265
+ except Exception:
266
+ # Persistence should not break normal config loading.
267
+ pass
249
268
  try:
250
269
  logging.getLogger("config_cli_gui").info(f"Loaded configuration from: {path}")
251
270
  except Exception:
@@ -291,7 +310,7 @@ class ConfigManager:
291
310
 
292
311
  # Record the saved config as the last-used config as well.
293
312
  try:
294
- persistence.write_last_used_config("config-cli-gui", str(path))
313
+ persistence.write_last_used_config(self.get_app_name(), str(path))
295
314
  except Exception:
296
315
  # Ignore persistence failures when saving
297
316
  pass
@@ -307,7 +326,7 @@ class ConfigManager:
307
326
  This is a convenience wrapper around persistence.read_last_used_config.
308
327
  """
309
328
  try:
310
- return persistence.read_last_used_config("config-cli-gui")
329
+ return persistence.read_last_used_config(self.get_app_name())
311
330
  except Exception:
312
331
  return None
313
332
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: config-cli-gui
3
- Version: 0.3.5
3
+ Version: 0.3.7
4
4
  Summary: Feature-rich Python project template for config-cli-gui.
5
5
  Author: pamagister
6
6
  Requires-Python: <3.12,>=3.11
@@ -58,6 +58,8 @@ src/config_cli_gui.egg-info/SOURCES.txt
58
58
  src/config_cli_gui.egg-info/dependency_links.txt
59
59
  src/config_cli_gui.egg-info/entry_points.txt
60
60
  src/config_cli_gui.egg-info/requires.txt
61
+ src/config_cli_gui.egg-info/scm_file_list.json
62
+ src/config_cli_gui.egg-info/scm_version.json
61
63
  src/config_cli_gui.egg-info/top_level.txt
62
64
  src/config_cli_gui/configtypes/__init__.py
63
65
  src/config_cli_gui/configtypes/color.py
@@ -0,0 +1,80 @@
1
+ {
2
+ "files": [
3
+ ".pre-commit-config.yaml",
4
+ "README.md",
5
+ "uv.lock",
6
+ "Makefile",
7
+ "LICENSE",
8
+ "pyproject.toml",
9
+ "mkdocs.yml",
10
+ "HISTORY.md",
11
+ "template.yml.url",
12
+ "config.yaml",
13
+ ".gitignore",
14
+ ".readthedocs.yaml",
15
+ "scripts/show_filelist.ps1",
16
+ "scripts/show_tree.ps1",
17
+ "scripts/show_tree.py",
18
+ "scripts/update_readme.py",
19
+ "docs/.nav.yml",
20
+ "docs/index.md",
21
+ "docs/develop/contributing.md",
22
+ "docs/develop/make_windows.md",
23
+ "docs/develop/naming_convention.md",
24
+ "docs/funding/funding.md",
25
+ "docs/css/custom.css",
26
+ "docs/_static/img/logo.png",
27
+ "docs/_static/img/favicon.png",
28
+ "docs/_static/img/settings_dlg.png",
29
+ "docs/_static/img/settings_doc.png",
30
+ "docs/usage/config.md",
31
+ "docs/usage/cli.md",
32
+ "docs/getting-started/virtual-environment.md",
33
+ "docs/getting-started/install.md",
34
+ "src/__init__.py",
35
+ "src/config_cli_gui/__init__.py",
36
+ "src/config_cli_gui/config.py",
37
+ "src/config_cli_gui/docs.py",
38
+ "src/config_cli_gui/logging.py",
39
+ "src/config_cli_gui/persistence.py",
40
+ "src/config_cli_gui/cli.py",
41
+ "src/config_cli_gui/gui.py",
42
+ "src/config_cli_gui/configtypes/__init__.py",
43
+ "src/config_cli_gui/configtypes/color.py",
44
+ "src/config_cli_gui/configtypes/vector.py",
45
+ "src/config_cli_gui/configtypes/font.py",
46
+ "tests/__init__.py",
47
+ "tests/test_docs.py",
48
+ "tests/test_config_manager.py",
49
+ "tests/test_cli.py",
50
+ "tests/test_generic_cli.py",
51
+ "tests/example_project/__init__.py",
52
+ "tests/example_project/example.gpx",
53
+ "tests/example_project/__main__.py",
54
+ "tests/example_project/core/__init__.py",
55
+ "tests/example_project/core/base.py",
56
+ "tests/example_project/config/__init__.py",
57
+ "tests/example_project/config/config_example.py",
58
+ "tests/example_project/cli/__init__.py",
59
+ "tests/example_project/cli/cli_example.py",
60
+ "tests/example_project/cli/__main__.py",
61
+ "tests/example_project/gui/__init__.py",
62
+ "tests/example_project/gui/gui_example.py",
63
+ "tests/example_project/gui/__main__.py",
64
+ ".idea/runConfigurations/example_project_cli.xml",
65
+ ".idea/runConfigurations/config_generate.xml",
66
+ ".idea/runConfigurations/example_project_gui.xml",
67
+ ".github/PULL_REQUEST_TEMPLATE.md",
68
+ ".github/init.sh",
69
+ ".github/update_funding.py",
70
+ ".github/dependabot.yml",
71
+ ".github/FUNDING.yml",
72
+ ".github/release_message.sh",
73
+ ".github/actions/setup-environment/action.yml",
74
+ ".github/ISSUE_TEMPLATE/bug_report.md",
75
+ ".github/ISSUE_TEMPLATE/feature_request.md",
76
+ ".github/workflows/main.yml",
77
+ ".github/workflows/release.yml",
78
+ ".github/workflows/update_readme.yml"
79
+ ]
80
+ }
@@ -0,0 +1,8 @@
1
+ {
2
+ "tag": "0.3.7",
3
+ "distance": 0,
4
+ "node": "g1115f5d6c180b06de260c378d10a5ca3977c2714",
5
+ "dirty": false,
6
+ "branch": "HEAD",
7
+ "node_date": "2026-06-24"
8
+ }
@@ -7,11 +7,11 @@ from logging import Logger
7
7
 
8
8
  from config_cli_gui.cli import CliGenerator
9
9
  from config_cli_gui.logging import initialize_logging
10
- from tests.example_project.config.config_example import ProjectConfigManager
10
+ from tests.example_project.config.config_example import ConfigParameterManager
11
11
  from tests.example_project.core.base import BaseGPXProcessor
12
12
 
13
13
 
14
- def validate_config(config_manager: ProjectConfigManager, logger: Logger) -> bool:
14
+ def validate_config(config_manager: ConfigParameterManager, logger: Logger) -> bool:
15
15
  """Validate the configuration parameters.
16
16
 
17
17
  Args:
@@ -29,7 +29,7 @@ def validate_config(config_manager: ProjectConfigManager, logger: Logger) -> boo
29
29
  return True
30
30
 
31
31
 
32
- def run_main_processing(_config: ProjectConfigManager, logger: Logger) -> int:
32
+ def run_main_processing(_config: ConfigParameterManager, logger: Logger) -> int:
33
33
  """Main processing function that gets called by the CLI generator.
34
34
 
35
35
  Args:
@@ -71,7 +71,7 @@ def run_main_processing(_config: ProjectConfigManager, logger: Logger) -> int:
71
71
  def main():
72
72
  """Main entry point for the CLI application."""
73
73
  # Create the base configuration manager
74
- config_manager = ProjectConfigManager()
74
+ config_manager = ConfigParameterManager()
75
75
 
76
76
  # Initialize logging and get a logger
77
77
  logger_manager = initialize_logging(
@@ -164,7 +164,7 @@ class MiscConfig(ConfigCategory):
164
164
  )
165
165
 
166
166
 
167
- class ProjectConfigManager(ConfigManager): # Inherit from ConfigManager
167
+ class ConfigParameterManager(ConfigManager): # Inherit from ConfigManager
168
168
  """Main configuration manager that handles all parameter categories."""
169
169
 
170
170
  cli: CliConfig
@@ -176,13 +176,22 @@ class ProjectConfigManager(ConfigManager): # Inherit from ConfigManager
176
176
  categories = (CliConfig(), GuiConfig(), MiscConfig())
177
177
  super().__init__(categories, config_file, **kwargs)
178
178
 
179
+ @staticmethod
180
+ def get_app_name() -> str:
181
+ """Return the application identifier for this example project.
182
+
183
+ This overrides the library default so that example files use
184
+ "example-app" as their persistence directory/name.
185
+ """
186
+ return "example-app"
187
+
179
188
 
180
189
  def main():
181
190
  """Main function to generate config file and documentation."""
182
191
  default_config: str = "config.yaml"
183
192
  default_cli_doc: str = "docs/usage/cli.md"
184
193
  default_config_doc: str = "docs/usage/config.md"
185
- _config = ProjectConfigManager()
194
+ _config = ConfigParameterManager()
186
195
  doc_gen = DocumentationGenerator(_config)
187
196
  doc_gen.generate_default_config_file(output_file=default_config)
188
197
  print(f"Generated: {default_config}")
@@ -27,7 +27,7 @@ from config_cli_gui.logging import (
27
27
  initialize_logging,
28
28
  )
29
29
  from config_cli_gui.persistence import read_last_used_config
30
- from tests.example_project.config.config_example import ProjectConfigManager
30
+ from tests.example_project.config.config_example import ConfigParameterManager
31
31
  from tests.example_project.core.base import BaseGPXProcessor
32
32
 
33
33
 
@@ -118,7 +118,21 @@ class MainGui:
118
118
  self.root.geometry("1200x600") # Increased width for new layout
119
119
 
120
120
  # Initialize configuration
121
- self._config = ProjectConfigManager("config.yaml")
121
+ # Prefer the user's last used configuration if present; otherwise
122
+ # load a local default config.yaml without marking it as "last used"
123
+ # (so we don't overwrite the user's actual last-used file).
124
+ try:
125
+ last = read_last_used_config(ConfigParameterManager.get_app_name())
126
+ except Exception:
127
+ last = None
128
+
129
+ if last and Path(last).exists():
130
+ self._config = ConfigParameterManager(last)
131
+ elif Path("config.yaml").exists():
132
+ # Load default config but do not persist it as the "last used"
133
+ self._config = ConfigParameterManager("config.yaml", persist_last_used=False)
134
+ else:
135
+ self._config = ConfigParameterManager()
122
136
 
123
137
  # Initialize logging system using individual AppConfig values
124
138
  self.logger_manager = initialize_logging(
@@ -278,7 +292,8 @@ class MainGui:
278
292
  # File menu
279
293
  file_menu = tk.Menu(menubar, tearoff=0)
280
294
  menubar.add_cascade(label="File", menu=file_menu)
281
- file_menu.add_command(label="Open...", command=self._open_files)
295
+ file_menu.add_command(label="Select config file", command=self._select_config)
296
+ file_menu.add_command(label="Open gpx files...", command=self._open_files)
282
297
  file_menu.add_separator()
283
298
 
284
299
  # Create Run menu options dynamically
@@ -379,6 +394,25 @@ class MainGui:
379
394
  self.logger.error(f"Could not open file {file_path}: {e}")
380
395
  messagebox.showerror("Error", f"Could not open file {file_path}: {e}")
381
396
 
397
+ def _select_config(self):
398
+ """Open file dialog to select and load a new config file."""
399
+ config_file = filedialog.askopenfilename(
400
+ title="Select config file",
401
+ filetypes=[("YAML files", "*.yaml"), ("All files", "*.*")],
402
+ )
403
+ if not config_file:
404
+ self.logger.debug("No config file selected.")
405
+ return
406
+
407
+ self.logger.info(f"Loading new configuration from: {config_file}")
408
+ try:
409
+ # When user explicitly selects a config file, we load it and
410
+ # allow the manager to persist it as the new last-used file.
411
+ self._config = ConfigParameterManager(config_file)
412
+ except Exception as e:
413
+ self.logger.error(f"Failed to load config file: {e}", exc_info=True)
414
+ messagebox.showerror("Config Error", f"Failed to load configuration: {e}")
415
+
382
416
  def _open_files(self):
383
417
  """Open file dialog and add files to list."""
384
418
  files = filedialog.askopenfilenames(
@@ -558,11 +592,11 @@ def main():
558
592
 
559
593
  # Try to restore the last used configuration file so the GUI can start
560
594
  # with the user's preferred theme and settings.
561
- last = read_last_used_config("config-cli-gui")
595
+ last = read_last_used_config(ConfigParameterManager.get_app_name())
562
596
  if last and Path(last).exists():
563
- _config = ProjectConfigManager(last)
597
+ _config = ConfigParameterManager(last)
564
598
  else:
565
- _config = ProjectConfigManager()
599
+ _config = ConfigParameterManager()
566
600
 
567
601
  theme_choice = _config.app.theme.value
568
602
 
@@ -4,7 +4,7 @@ from unittest.mock import mock_open, patch
4
4
  import pytest
5
5
 
6
6
  from config_cli_gui.cli import CliGenerator
7
- from tests.example_project.config.config_example import ProjectConfigManager
7
+ from tests.example_project.config.config_example import ConfigParameterManager
8
8
 
9
9
  # ----------------------------------------------------------------------
10
10
  # Mock config.yaml content
@@ -29,7 +29,7 @@ cli:
29
29
  # ----------------------------------------------------------------------
30
30
  @pytest.fixture
31
31
  def config_manager():
32
- return ProjectConfigManager()
32
+ return ConfigParameterManager()
33
33
 
34
34
 
35
35
  @pytest.fixture
@@ -9,7 +9,7 @@ import unittest
9
9
  from pathlib import Path
10
10
 
11
11
  from config_cli_gui.docs import DocumentationGenerator
12
- from tests.example_project.config.config_example import ProjectConfigManager
12
+ from tests.example_project.config.config_example import ConfigParameterManager
13
13
 
14
14
 
15
15
  class TestGenericCLI(unittest.TestCase):
@@ -25,7 +25,7 @@ class TestGenericCLI(unittest.TestCase):
25
25
  self.dummy_input.write_text("dummy input content")
26
26
 
27
27
  # Default config for testing
28
- self.configManager = ProjectConfigManager()
28
+ self.configManager = ConfigParameterManager()
29
29
  self.default_cli_config = self.configManager.to_dict()["cli"]
30
30
 
31
31
  def tearDown(self):
@@ -65,13 +65,13 @@ class TestGenericCLI(unittest.TestCase):
65
65
  non_existent_file = self.temp_path / "does_not_exist.yaml"
66
66
 
67
67
  with self.assertRaises(FileNotFoundError):
68
- ProjectConfigManager(config_file=str(non_existent_file))
68
+ ConfigParameterManager(config_file=str(non_existent_file))
69
69
 
70
70
  def test_generate_default_config_file(self):
71
71
  """Test generation of default configuration file."""
72
72
  output_file = self.temp_path / "default_config.yaml"
73
73
 
74
- config_manager = ProjectConfigManager()
74
+ config_manager = ConfigParameterManager()
75
75
  docGen = DocumentationGenerator(config_manager)
76
76
  docGen.generate_default_config_file(str(output_file))
77
77
 
@@ -102,7 +102,7 @@ class TestGenericCLI(unittest.TestCase):
102
102
  """Test generation of CLI markdown documentation."""
103
103
  output_file = self.temp_path / "cli_doc_test.md"
104
104
 
105
- config_manager = ProjectConfigManager()
105
+ config_manager = ConfigParameterManager()
106
106
  docGen = DocumentationGenerator(config_manager)
107
107
  docGen.generate_cli_markdown_doc(str(output_file))
108
108
 
File without changes
File without changes
File without changes
File without changes
File without changes