brkraw-viewer 0.2.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.
- brkraw_viewer-0.2.7/PKG-INFO +170 -0
- brkraw_viewer-0.2.7/README.md +151 -0
- brkraw_viewer-0.2.7/pyproject.toml +46 -0
- brkraw_viewer-0.2.7/setup.cfg +4 -0
- brkraw_viewer-0.2.7/src/brkraw_viewer/__init__.py +4 -0
- brkraw_viewer-0.2.7/src/brkraw_viewer/apps/__init__.py +0 -0
- brkraw_viewer-0.2.7/src/brkraw_viewer/apps/config.py +90 -0
- brkraw_viewer-0.2.7/src/brkraw_viewer/apps/convert.py +1754 -0
- brkraw_viewer-0.2.7/src/brkraw_viewer/apps/hooks.py +36 -0
- brkraw_viewer-0.2.7/src/brkraw_viewer/apps/viewer.py +5541 -0
- brkraw_viewer-0.2.7/src/brkraw_viewer/assets/icon.ico +0 -0
- brkraw_viewer-0.2.7/src/brkraw_viewer/assets/icon.png +0 -0
- brkraw_viewer-0.2.7/src/brkraw_viewer/frames/__init__.py +2 -0
- brkraw_viewer-0.2.7/src/brkraw_viewer/frames/params_panel.py +80 -0
- brkraw_viewer-0.2.7/src/brkraw_viewer/frames/viewer_canvas.py +546 -0
- brkraw_viewer-0.2.7/src/brkraw_viewer/frames/viewer_config.py +101 -0
- brkraw_viewer-0.2.7/src/brkraw_viewer/plugin.py +125 -0
- brkraw_viewer-0.2.7/src/brkraw_viewer/registry.py +258 -0
- brkraw_viewer-0.2.7/src/brkraw_viewer/snippets/context_map/basic.yaml +4 -0
- brkraw_viewer-0.2.7/src/brkraw_viewer/snippets/context_map/enum-map.yaml +5 -0
- brkraw_viewer-0.2.7/src/brkraw_viewer/snippets/rule/basic.yaml +10 -0
- brkraw_viewer-0.2.7/src/brkraw_viewer/snippets/rule/when-contains.yaml +10 -0
- brkraw_viewer-0.2.7/src/brkraw_viewer/snippets/spec/basic.yaml +5 -0
- brkraw_viewer-0.2.7/src/brkraw_viewer/snippets/spec/list-source.yaml +5 -0
- brkraw_viewer-0.2.7/src/brkraw_viewer/snippets/spec/with-default.yaml +5 -0
- brkraw_viewer-0.2.7/src/brkraw_viewer/utils/__init__.py +2 -0
- brkraw_viewer-0.2.7/src/brkraw_viewer/utils/orientation.py +17 -0
- brkraw_viewer-0.2.7/src/brkraw_viewer.egg-info/PKG-INFO +170 -0
- brkraw_viewer-0.2.7/src/brkraw_viewer.egg-info/SOURCES.txt +32 -0
- brkraw_viewer-0.2.7/src/brkraw_viewer.egg-info/dependency_links.txt +1 -0
- brkraw_viewer-0.2.7/src/brkraw_viewer.egg-info/entry_points.txt +2 -0
- brkraw_viewer-0.2.7/src/brkraw_viewer.egg-info/requires.txt +9 -0
- brkraw_viewer-0.2.7/src/brkraw_viewer.egg-info/top_level.txt +1 -0
- brkraw_viewer-0.2.7/tests/test_smoke_viewer.py +29 -0
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: brkraw-viewer
|
|
3
|
+
Version: 0.2.7
|
|
4
|
+
Summary: BrkRaw scan viewer plugin for brkraw CLI.
|
|
5
|
+
Author: BrkRaw
|
|
6
|
+
License: MIT
|
|
7
|
+
Classifier: Programming Language :: Python :: 3
|
|
8
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
9
|
+
Classifier: Operating System :: OS Independent
|
|
10
|
+
Requires-Python: >=3.9
|
|
11
|
+
Description-Content-Type: text/markdown
|
|
12
|
+
Requires-Dist: brkraw>=0.5.0rc1
|
|
13
|
+
Requires-Dist: nibabel>=5.0
|
|
14
|
+
Requires-Dist: pillow>=10.0
|
|
15
|
+
Provides-Extra: docs
|
|
16
|
+
Requires-Dist: mkdocs-material>=9.5.0; extra == "docs"
|
|
17
|
+
Provides-Extra: test
|
|
18
|
+
Requires-Dist: pytest>=7.4; extra == "test"
|
|
19
|
+
|
|
20
|
+
<h1 align="left">
|
|
21
|
+
<picture>
|
|
22
|
+
<source media="(prefers-color-scheme: dark)" srcset="docs/assets/brkraw-viewer-logo-dark.svg">
|
|
23
|
+
<img alt="BrkRaw Viewer" src="docs/assets/brkraw-viewer-logo-light.svg" width="410">
|
|
24
|
+
</picture>
|
|
25
|
+
</h1>
|
|
26
|
+
|
|
27
|
+
BrkRaw Viewer is an interactive dataset viewer implemented as a
|
|
28
|
+
separate CLI plugin for the `brkraw` command.
|
|
29
|
+
|
|
30
|
+
The viewer is intentionally maintained outside the BrkRaw core to
|
|
31
|
+
enable independent development and community contributions around
|
|
32
|
+
user-facing interfaces.
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## Scope and intent
|
|
37
|
+
|
|
38
|
+
BrkRaw Viewer is designed for **interactive inspection** of Bruker
|
|
39
|
+
Paravision datasets. It focuses on quick exploration and validation
|
|
40
|
+
rather than data conversion or analysis.
|
|
41
|
+
|
|
42
|
+
The goal is to provide practical, researcher-focused features that are
|
|
43
|
+
useful in everyday workflows, such as quick dataset triage, metadata
|
|
44
|
+
checks, and lightweight visual QC.
|
|
45
|
+
|
|
46
|
+
Typical use cases include:
|
|
47
|
+
|
|
48
|
+
- Browsing studies, scans, and reconstructions
|
|
49
|
+
- Verifying scan and reconstruction IDs
|
|
50
|
+
- Inspecting acquisition metadata before conversion
|
|
51
|
+
- Lightweight visual sanity checks
|
|
52
|
+
|
|
53
|
+
All data conversion and reproducible workflows are handled by the
|
|
54
|
+
BrkRaw CLI and Python API.
|
|
55
|
+
|
|
56
|
+
---
|
|
57
|
+
|
|
58
|
+
## Why these features exist
|
|
59
|
+
|
|
60
|
+
**Viewer**
|
|
61
|
+
The Viewer tab makes it easy to confirm the right scan and orientation before
|
|
62
|
+
running a larger workflow.
|
|
63
|
+
|
|
64
|
+
**Registry**
|
|
65
|
+
The Registry reduces repeated filesystem navigation and lets you re-open the
|
|
66
|
+
current session with a single menu action.
|
|
67
|
+
|
|
68
|
+
**Extensions/hooks**
|
|
69
|
+
Extensions allow modality-specific panels (MRS, BIDS, etc.) to live outside the
|
|
70
|
+
core viewer so the default install stays lightweight.
|
|
71
|
+
|
|
72
|
+
---
|
|
73
|
+
|
|
74
|
+
## Design goal: shared extensibility
|
|
75
|
+
|
|
76
|
+
brkraw-viewer keeps the BrkRaw design philosophy: extend the ecosystem
|
|
77
|
+
without changing core logic. The viewer uses the same rules/spec/layout
|
|
78
|
+
system as the CLI and Python API, and it exposes UI extensions via the
|
|
79
|
+
`brkraw.viewer.hook` entry point so new tabs can be added with standalone
|
|
80
|
+
packages. Viewer hooks can coexist with converter hooks and CLI hooks,
|
|
81
|
+
so modality-specific logic can flow from conversion into UI without
|
|
82
|
+
patching the viewer itself.
|
|
83
|
+
|
|
84
|
+
---
|
|
85
|
+
|
|
86
|
+
## UI direction
|
|
87
|
+
|
|
88
|
+
The default viewer targets a **tkinter-based** implementation.
|
|
89
|
+
|
|
90
|
+
This choice is intentional: we want a lightweight tool that can be
|
|
91
|
+
used directly on scanner consoles or constrained environments with
|
|
92
|
+
minimal dependencies.
|
|
93
|
+
|
|
94
|
+
More modern GUI frameworks are welcome, but should be developed as
|
|
95
|
+
separate CLI extensions to keep the default viewer small and easy to
|
|
96
|
+
install.
|
|
97
|
+
|
|
98
|
+
---
|
|
99
|
+
|
|
100
|
+
## Viewer hooks
|
|
101
|
+
|
|
102
|
+
Viewer extensions are implemented as hooks discovered through
|
|
103
|
+
`brkraw.viewer.hook`. Each hook can register a new tab and provide
|
|
104
|
+
dataset callbacks, enabling feature panels to live outside the core
|
|
105
|
+
viewer while staying compatible with BrkRaw rules, specs, and converter
|
|
106
|
+
hooks. See `docs/dev/hooks.md` for the hook interface and entry point
|
|
107
|
+
setup.
|
|
108
|
+
|
|
109
|
+
---
|
|
110
|
+
|
|
111
|
+
## Installation
|
|
112
|
+
|
|
113
|
+
For development and testing, install in editable mode:
|
|
114
|
+
|
|
115
|
+
pip install -e .
|
|
116
|
+
|
|
117
|
+
---
|
|
118
|
+
|
|
119
|
+
## Usage
|
|
120
|
+
|
|
121
|
+
Launch the viewer via the BrkRaw CLI:
|
|
122
|
+
|
|
123
|
+
brkraw viewer /path/to/bruker/study
|
|
124
|
+
|
|
125
|
+
Optional arguments allow opening a specific scan or slice:
|
|
126
|
+
|
|
127
|
+
brkraw viewer /path/to/bruker/study \
|
|
128
|
+
--scan 3 \
|
|
129
|
+
--reco 1
|
|
130
|
+
|
|
131
|
+
The viewer can also open `.zip` or Paravision-exported `.PvDatasets`
|
|
132
|
+
archives using `Load` (folder or archive file).
|
|
133
|
+
|
|
134
|
+
---
|
|
135
|
+
|
|
136
|
+
## Update
|
|
137
|
+
|
|
138
|
+
Recent updates:
|
|
139
|
+
|
|
140
|
+
- Open folders or archives (`.zip` / `.PvDatasets`)
|
|
141
|
+
- Viewer: `Space` (`raw/scanner/subject_ras`), nibabel RAS display, click-to-set `X/Y/Z`, optional crosshair + zoom,
|
|
142
|
+
slicepack/frame sliders only when needed
|
|
143
|
+
- Info: rule + spec selection (installed or file), parameter search, lazy Viewer refresh on tab focus
|
|
144
|
+
- Registry: add the current session from the `+` menu when a dataset is loaded
|
|
145
|
+
- Convert: BrkRaw layout engine, template + suffix defaults from `~/.brkraw/config.yaml`, keys browser (click to add),
|
|
146
|
+
optional config `layout_entries`
|
|
147
|
+
- Config: edit `~/.brkraw/config.yaml` in-app; basic focus/icon UX
|
|
148
|
+
|
|
149
|
+
This update keeps dependencies minimal and preserves compatibility with
|
|
150
|
+
the core BrkRaw rule/spec/hook system.
|
|
151
|
+
|
|
152
|
+
---
|
|
153
|
+
|
|
154
|
+
## Contributing
|
|
155
|
+
|
|
156
|
+
We welcome contributions related to:
|
|
157
|
+
|
|
158
|
+
- New viewer hooks that add modality-specific panels or workflows
|
|
159
|
+
- Alternative UI implementations delivered as separate CLI extensions
|
|
160
|
+
- fMRI/MRS/BIDS-focused visualization or QC helpers built on hooks
|
|
161
|
+
- Multi-dataset session management and registry enhancements
|
|
162
|
+
- Performance and memory improvements for large datasets
|
|
163
|
+
|
|
164
|
+
Contributions should prefer designs where new hooks extend the viewer
|
|
165
|
+
implicitly through shared BrkRaw abstractions, and where richer UIs are
|
|
166
|
+
provided as optional CLI extensions rather than increasing the default
|
|
167
|
+
dependency footprint.
|
|
168
|
+
|
|
169
|
+
If you are interested in contributing, please start a discussion or
|
|
170
|
+
open an issue describing your use case and goals.
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
<h1 align="left">
|
|
2
|
+
<picture>
|
|
3
|
+
<source media="(prefers-color-scheme: dark)" srcset="docs/assets/brkraw-viewer-logo-dark.svg">
|
|
4
|
+
<img alt="BrkRaw Viewer" src="docs/assets/brkraw-viewer-logo-light.svg" width="410">
|
|
5
|
+
</picture>
|
|
6
|
+
</h1>
|
|
7
|
+
|
|
8
|
+
BrkRaw Viewer is an interactive dataset viewer implemented as a
|
|
9
|
+
separate CLI plugin for the `brkraw` command.
|
|
10
|
+
|
|
11
|
+
The viewer is intentionally maintained outside the BrkRaw core to
|
|
12
|
+
enable independent development and community contributions around
|
|
13
|
+
user-facing interfaces.
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## Scope and intent
|
|
18
|
+
|
|
19
|
+
BrkRaw Viewer is designed for **interactive inspection** of Bruker
|
|
20
|
+
Paravision datasets. It focuses on quick exploration and validation
|
|
21
|
+
rather than data conversion or analysis.
|
|
22
|
+
|
|
23
|
+
The goal is to provide practical, researcher-focused features that are
|
|
24
|
+
useful in everyday workflows, such as quick dataset triage, metadata
|
|
25
|
+
checks, and lightweight visual QC.
|
|
26
|
+
|
|
27
|
+
Typical use cases include:
|
|
28
|
+
|
|
29
|
+
- Browsing studies, scans, and reconstructions
|
|
30
|
+
- Verifying scan and reconstruction IDs
|
|
31
|
+
- Inspecting acquisition metadata before conversion
|
|
32
|
+
- Lightweight visual sanity checks
|
|
33
|
+
|
|
34
|
+
All data conversion and reproducible workflows are handled by the
|
|
35
|
+
BrkRaw CLI and Python API.
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
## Why these features exist
|
|
40
|
+
|
|
41
|
+
**Viewer**
|
|
42
|
+
The Viewer tab makes it easy to confirm the right scan and orientation before
|
|
43
|
+
running a larger workflow.
|
|
44
|
+
|
|
45
|
+
**Registry**
|
|
46
|
+
The Registry reduces repeated filesystem navigation and lets you re-open the
|
|
47
|
+
current session with a single menu action.
|
|
48
|
+
|
|
49
|
+
**Extensions/hooks**
|
|
50
|
+
Extensions allow modality-specific panels (MRS, BIDS, etc.) to live outside the
|
|
51
|
+
core viewer so the default install stays lightweight.
|
|
52
|
+
|
|
53
|
+
---
|
|
54
|
+
|
|
55
|
+
## Design goal: shared extensibility
|
|
56
|
+
|
|
57
|
+
brkraw-viewer keeps the BrkRaw design philosophy: extend the ecosystem
|
|
58
|
+
without changing core logic. The viewer uses the same rules/spec/layout
|
|
59
|
+
system as the CLI and Python API, and it exposes UI extensions via the
|
|
60
|
+
`brkraw.viewer.hook` entry point so new tabs can be added with standalone
|
|
61
|
+
packages. Viewer hooks can coexist with converter hooks and CLI hooks,
|
|
62
|
+
so modality-specific logic can flow from conversion into UI without
|
|
63
|
+
patching the viewer itself.
|
|
64
|
+
|
|
65
|
+
---
|
|
66
|
+
|
|
67
|
+
## UI direction
|
|
68
|
+
|
|
69
|
+
The default viewer targets a **tkinter-based** implementation.
|
|
70
|
+
|
|
71
|
+
This choice is intentional: we want a lightweight tool that can be
|
|
72
|
+
used directly on scanner consoles or constrained environments with
|
|
73
|
+
minimal dependencies.
|
|
74
|
+
|
|
75
|
+
More modern GUI frameworks are welcome, but should be developed as
|
|
76
|
+
separate CLI extensions to keep the default viewer small and easy to
|
|
77
|
+
install.
|
|
78
|
+
|
|
79
|
+
---
|
|
80
|
+
|
|
81
|
+
## Viewer hooks
|
|
82
|
+
|
|
83
|
+
Viewer extensions are implemented as hooks discovered through
|
|
84
|
+
`brkraw.viewer.hook`. Each hook can register a new tab and provide
|
|
85
|
+
dataset callbacks, enabling feature panels to live outside the core
|
|
86
|
+
viewer while staying compatible with BrkRaw rules, specs, and converter
|
|
87
|
+
hooks. See `docs/dev/hooks.md` for the hook interface and entry point
|
|
88
|
+
setup.
|
|
89
|
+
|
|
90
|
+
---
|
|
91
|
+
|
|
92
|
+
## Installation
|
|
93
|
+
|
|
94
|
+
For development and testing, install in editable mode:
|
|
95
|
+
|
|
96
|
+
pip install -e .
|
|
97
|
+
|
|
98
|
+
---
|
|
99
|
+
|
|
100
|
+
## Usage
|
|
101
|
+
|
|
102
|
+
Launch the viewer via the BrkRaw CLI:
|
|
103
|
+
|
|
104
|
+
brkraw viewer /path/to/bruker/study
|
|
105
|
+
|
|
106
|
+
Optional arguments allow opening a specific scan or slice:
|
|
107
|
+
|
|
108
|
+
brkraw viewer /path/to/bruker/study \
|
|
109
|
+
--scan 3 \
|
|
110
|
+
--reco 1
|
|
111
|
+
|
|
112
|
+
The viewer can also open `.zip` or Paravision-exported `.PvDatasets`
|
|
113
|
+
archives using `Load` (folder or archive file).
|
|
114
|
+
|
|
115
|
+
---
|
|
116
|
+
|
|
117
|
+
## Update
|
|
118
|
+
|
|
119
|
+
Recent updates:
|
|
120
|
+
|
|
121
|
+
- Open folders or archives (`.zip` / `.PvDatasets`)
|
|
122
|
+
- Viewer: `Space` (`raw/scanner/subject_ras`), nibabel RAS display, click-to-set `X/Y/Z`, optional crosshair + zoom,
|
|
123
|
+
slicepack/frame sliders only when needed
|
|
124
|
+
- Info: rule + spec selection (installed or file), parameter search, lazy Viewer refresh on tab focus
|
|
125
|
+
- Registry: add the current session from the `+` menu when a dataset is loaded
|
|
126
|
+
- Convert: BrkRaw layout engine, template + suffix defaults from `~/.brkraw/config.yaml`, keys browser (click to add),
|
|
127
|
+
optional config `layout_entries`
|
|
128
|
+
- Config: edit `~/.brkraw/config.yaml` in-app; basic focus/icon UX
|
|
129
|
+
|
|
130
|
+
This update keeps dependencies minimal and preserves compatibility with
|
|
131
|
+
the core BrkRaw rule/spec/hook system.
|
|
132
|
+
|
|
133
|
+
---
|
|
134
|
+
|
|
135
|
+
## Contributing
|
|
136
|
+
|
|
137
|
+
We welcome contributions related to:
|
|
138
|
+
|
|
139
|
+
- New viewer hooks that add modality-specific panels or workflows
|
|
140
|
+
- Alternative UI implementations delivered as separate CLI extensions
|
|
141
|
+
- fMRI/MRS/BIDS-focused visualization or QC helpers built on hooks
|
|
142
|
+
- Multi-dataset session management and registry enhancements
|
|
143
|
+
- Performance and memory improvements for large datasets
|
|
144
|
+
|
|
145
|
+
Contributions should prefer designs where new hooks extend the viewer
|
|
146
|
+
implicitly through shared BrkRaw abstractions, and where richer UIs are
|
|
147
|
+
provided as optional CLI extensions rather than increasing the default
|
|
148
|
+
dependency footprint.
|
|
149
|
+
|
|
150
|
+
If you are interested in contributing, please start a discussion or
|
|
151
|
+
open an issue describing your use case and goals.
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=68", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "brkraw-viewer"
|
|
7
|
+
version = "0.2.7"
|
|
8
|
+
description = "BrkRaw scan viewer plugin for brkraw CLI."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.9"
|
|
11
|
+
dependencies = [
|
|
12
|
+
"brkraw>=0.5.0rc1",
|
|
13
|
+
"nibabel>=5.0",
|
|
14
|
+
"pillow>=10.0",
|
|
15
|
+
]
|
|
16
|
+
authors = [{name = "BrkRaw"}]
|
|
17
|
+
license = {text = "MIT"}
|
|
18
|
+
classifiers = [
|
|
19
|
+
"Programming Language :: Python :: 3",
|
|
20
|
+
"License :: OSI Approved :: MIT License",
|
|
21
|
+
"Operating System :: OS Independent",
|
|
22
|
+
]
|
|
23
|
+
|
|
24
|
+
[project.entry-points."brkraw.cli"]
|
|
25
|
+
viewer = "brkraw_viewer.plugin:register"
|
|
26
|
+
|
|
27
|
+
[project.optional-dependencies]
|
|
28
|
+
docs = [
|
|
29
|
+
"mkdocs-material>=9.5.0",
|
|
30
|
+
]
|
|
31
|
+
test = [
|
|
32
|
+
"pytest>=7.4",
|
|
33
|
+
]
|
|
34
|
+
|
|
35
|
+
[tool.pytest.ini_options]
|
|
36
|
+
testpaths = ["tests"]
|
|
37
|
+
addopts = "-q"
|
|
38
|
+
|
|
39
|
+
[tool.setuptools]
|
|
40
|
+
package-dir = {"" = "src"}
|
|
41
|
+
|
|
42
|
+
[tool.setuptools.packages.find]
|
|
43
|
+
where = ["src"]
|
|
44
|
+
|
|
45
|
+
[tool.setuptools.package-data]
|
|
46
|
+
brkraw_viewer = ["assets/*.png", "assets/*.ico", "snippets/**/*.yaml"]
|
|
File without changes
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import datetime as dt
|
|
4
|
+
import logging
|
|
5
|
+
import shutil
|
|
6
|
+
import tkinter as tk
|
|
7
|
+
from tkinter import messagebox, ttk
|
|
8
|
+
from pathlib import Path
|
|
9
|
+
|
|
10
|
+
from brkraw.core import config as config_core
|
|
11
|
+
|
|
12
|
+
logger = logging.getLogger("brkraw.viewer")
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class ConfigTabMixin:
|
|
16
|
+
_config_text: tk.Text
|
|
17
|
+
_config_path_var: tk.StringVar
|
|
18
|
+
|
|
19
|
+
def _build_config_tab(self, config_tab: ttk.Frame) -> None:
|
|
20
|
+
config_tab.columnconfigure(0, weight=1)
|
|
21
|
+
config_tab.rowconfigure(1, weight=1)
|
|
22
|
+
config_bar = ttk.Frame(config_tab, padding=(6, 6))
|
|
23
|
+
config_bar.grid(row=0, column=0, sticky="ew")
|
|
24
|
+
ttk.Button(config_bar, text="Save", command=self._save_config_text).pack(side=tk.LEFT)
|
|
25
|
+
ttk.Button(config_bar, text="Backup", command=self._backup_config_text).pack(side=tk.LEFT, padx=(6, 0))
|
|
26
|
+
ttk.Button(config_bar, text="Reset", command=self._reset_config_text).pack(side=tk.LEFT, padx=(6, 0))
|
|
27
|
+
self._config_path_var = tk.StringVar(value="")
|
|
28
|
+
ttk.Label(config_bar, textvariable=self._config_path_var).pack(side=tk.LEFT, padx=(12, 0))
|
|
29
|
+
|
|
30
|
+
config_body = ttk.Frame(config_tab, padding=(6, 6))
|
|
31
|
+
config_body.grid(row=1, column=0, sticky="nsew")
|
|
32
|
+
config_body.columnconfigure(0, weight=1)
|
|
33
|
+
config_body.rowconfigure(0, weight=1)
|
|
34
|
+
self._config_text = tk.Text(config_body, wrap="none")
|
|
35
|
+
self._config_text.grid(row=0, column=0, sticky="nsew")
|
|
36
|
+
config_scroll = ttk.Scrollbar(config_body, orient="vertical", command=self._config_text.yview)
|
|
37
|
+
config_scroll.grid(row=0, column=1, sticky="ns")
|
|
38
|
+
self._config_text.configure(yscrollcommand=config_scroll.set)
|
|
39
|
+
|
|
40
|
+
def _load_config_text(self) -> None:
|
|
41
|
+
try:
|
|
42
|
+
paths = config_core.ensure_initialized(root=None, create_config=True, exist_ok=True)
|
|
43
|
+
self._config_path_var.set(str(paths.config_file))
|
|
44
|
+
content = paths.config_file.read_text(encoding="utf-8")
|
|
45
|
+
except Exception as exc:
|
|
46
|
+
logger.error("Failed to load config.yaml: %s", exc, exc_info=logger.isEnabledFor(logging.DEBUG))
|
|
47
|
+
self._config_path_var.set("")
|
|
48
|
+
self._config_text.delete("1.0", tk.END)
|
|
49
|
+
self._config_text.insert(tk.END, f"# Failed to load config.yaml: {exc}\n")
|
|
50
|
+
return
|
|
51
|
+
self._config_text.delete("1.0", tk.END)
|
|
52
|
+
self._config_text.insert(tk.END, content)
|
|
53
|
+
|
|
54
|
+
def _save_config_text(self) -> None:
|
|
55
|
+
try:
|
|
56
|
+
paths = config_core.ensure_initialized(root=None, create_config=True, exist_ok=True)
|
|
57
|
+
self._config_path_var.set(str(paths.config_file))
|
|
58
|
+
text = self._config_text.get("1.0", tk.END)
|
|
59
|
+
paths.config_file.write_text(text, encoding="utf-8")
|
|
60
|
+
logger.info("Saved config.yaml: %s", paths.config_file)
|
|
61
|
+
except Exception as exc:
|
|
62
|
+
logger.error("Failed to save config.yaml: %s", exc, exc_info=logger.isEnabledFor(logging.DEBUG))
|
|
63
|
+
messagebox.showerror("Save error", f"Failed to save config.yaml:\n{exc}")
|
|
64
|
+
|
|
65
|
+
def _backup_config_text(self) -> None:
|
|
66
|
+
try:
|
|
67
|
+
paths = config_core.ensure_initialized(root=None, create_config=True, exist_ok=True)
|
|
68
|
+
config_path = paths.config_file
|
|
69
|
+
self._config_path_var.set(str(config_path))
|
|
70
|
+
if not config_path.exists():
|
|
71
|
+
messagebox.showwarning("Backup", f"Config file not found:\n{config_path}")
|
|
72
|
+
return
|
|
73
|
+
ts = dt.datetime.now().strftime("%Y%m%d-%H%M%S")
|
|
74
|
+
backup_path = Path(f"{config_path}.bak-{ts}")
|
|
75
|
+
shutil.copy2(config_path, backup_path)
|
|
76
|
+
logger.info("Backed up config.yaml: %s", backup_path)
|
|
77
|
+
messagebox.showinfo("Backup", f"Created backup:\n{backup_path}")
|
|
78
|
+
except Exception as exc:
|
|
79
|
+
logger.error("Failed to back up config.yaml: %s", exc, exc_info=logger.isEnabledFor(logging.DEBUG))
|
|
80
|
+
messagebox.showerror("Backup error", f"Failed to back up config.yaml:\n{exc}")
|
|
81
|
+
|
|
82
|
+
def _reset_config_text(self) -> None:
|
|
83
|
+
try:
|
|
84
|
+
config_core.reset_config(root=None)
|
|
85
|
+
logger.info("Reset config.yaml to defaults.")
|
|
86
|
+
except Exception as exc:
|
|
87
|
+
logger.error("Failed to reset config.yaml: %s", exc, exc_info=logger.isEnabledFor(logging.DEBUG))
|
|
88
|
+
messagebox.showerror("Reset error", f"Failed to reset config.yaml:\n{exc}")
|
|
89
|
+
return
|
|
90
|
+
self._load_config_text()
|