mirror of
https://git.srhtnin.garden/sarah/SaraFem.git
synced 2026-10-15 02:23:17 +02:00
Add SaraSortd integration: show incoming/outgoing sort rules for the browsed directory
This commit is contained in:
1 parent
31b6c554e6
commit
d588d445b4
4 files changed
+436
-9
No files matched your search
@@ -155,6 +155,16 @@ class SaraTagIntegrationConfig:
|
||||
)
|
||||
|
||||
|
||||
@dataclass
|
||||
class SaraSortdIntegrationConfig:
|
||||
"""Points at a SaraSortd checkout's GlobalConf.toml (read-only — SaraFem
|
||||
never writes to it). Disabled until pointed at one, e.g.
|
||||
GlobalConfPath = "/home/sarah/Applications/SaraSortd/GlobalConf.toml"."""
|
||||
|
||||
Enabled: bool = False
|
||||
GlobalConfPath: str = ""
|
||||
|
||||
|
||||
@dataclass
|
||||
class AppConfig:
|
||||
"""Persisted user settings. Defaults match SaraFem's existing behaviour
|
||||
@@ -192,6 +202,9 @@ class AppConfig:
|
||||
# Grid view.
|
||||
GridIconSize: int = 64
|
||||
GridNameBelowIcon: bool = True
|
||||
ListIconSize: int = 32
|
||||
FontSize: int = 14 # entry name text, list and grid alike; metadata/header text scales with it
|
||||
ToolbarHamburger: bool = False # collapse the toolbar's buttons into one overflow menu
|
||||
|
||||
# Batch-rename pattern for multi-select rename, syntax modeled on
|
||||
# SaraSortd's own placeholder characters (see ~/Applications/SaraSortd's
|
||||
@@ -257,6 +270,7 @@ class AppConfig:
|
||||
# MaxHeight when on, since a fixed height and an even flex split conflict.
|
||||
SplitPreviewTagsEvenly: bool = False
|
||||
SaraTag: SaraTagIntegrationConfig = field(default_factory=SaraTagIntegrationConfig)
|
||||
SaraSortd: SaraSortdIntegrationConfig = field(default_factory=SaraSortdIntegrationConfig)
|
||||
|
||||
def Save(self) -> None:
|
||||
ConfigDir.mkdir(parents=True, exist_ok=True)
|
||||
@@ -285,6 +299,11 @@ def LoadConfig() -> AppConfig:
|
||||
SaraTagFiltered = {Key: Value for Key, Value in SaraTagData.items() if Key in KnownSaraTagFields}
|
||||
Filtered["SaraTag"] = SaraTagIntegrationConfig(**SaraTagFiltered)
|
||||
|
||||
SaraSortdData = Filtered.pop("SaraSortd", {})
|
||||
KnownSaraSortdFields = {Field for Field in SaraSortdIntegrationConfig.__dataclass_fields__}
|
||||
SaraSortdFiltered = {Key: Value for Key, Value in SaraSortdData.items() if Key in KnownSaraSortdFields}
|
||||
Filtered["SaraSortd"] = SaraSortdIntegrationConfig(**SaraSortdFiltered)
|
||||
|
||||
return AppConfig(**Filtered)
|
||||
|
||||
|
||||
@@ -330,6 +349,62 @@ def EffectiveSettings(Config: AppConfig) -> SharedSettings:
|
||||
return LoadSharedSettings(Config) if Config.UseSharedSettings else _OwnSettings(Config)
|
||||
|
||||
|
||||
def ExportSettings(Config: AppConfig, DestPath: Path) -> None:
|
||||
"""One portable file bundling both the cross-program shared settings
|
||||
(Theme/Font/TitleBar) and SaraFem's own, under separate top-level
|
||||
sections (Features/Major: "Exporting and importing settings as one
|
||||
file... applies to every other SaraSuite program"). A future SaraView/
|
||||
SaraTag/etc. import would read the same [SaraSuite] section plus its
|
||||
own top-level one, ignoring [SaraFem] — the same convention
|
||||
ImportSettings below uses to ignore sections that aren't its own."""
|
||||
Data = {"SaraSuite": asdict(_OwnSettings(Config)), "SaraFem": asdict(Config)}
|
||||
DestPath.write_text(toml.dumps(Data))
|
||||
|
||||
|
||||
def ImportSettings(Config: AppConfig, SrcPath: Path) -> None:
|
||||
"""Applies a [SaraSuite] section (if present) to the shared settings
|
||||
file and a [SaraFem] section (if present) onto Config in place, field
|
||||
by field — a field the import doesn't mention is left as it was, rather
|
||||
than reset to default, and unknown sections/fields (another program's,
|
||||
or a newer SaraFem version's) are silently skipped: the "should stack
|
||||
fine with others if installed or not... one file works anywhere on the
|
||||
same version no matter what you have installed" compatibility the
|
||||
feature asked for. Raises toml.TomlDecodeError on an unreadable file —
|
||||
callers show that to the user rather than silently doing nothing."""
|
||||
Data = toml.loads(SrcPath.read_text())
|
||||
|
||||
SharedData = Data.get("SaraSuite")
|
||||
if isinstance(SharedData, dict):
|
||||
KnownSharedFields = {F for F in SharedSettings.__dataclass_fields__}
|
||||
Filtered = {K: V for K, V in SharedData.items() if K in KnownSharedFields}
|
||||
Merged = asdict(_OwnSettings(Config))
|
||||
Merged.update(Filtered)
|
||||
SharedSettings(**Merged).Save()
|
||||
|
||||
OwnData = Data.get("SaraFem")
|
||||
if isinstance(OwnData, dict):
|
||||
KnownFields = {F for F in AppConfig.__dataclass_fields__}
|
||||
Filtered = {K: V for K, V in OwnData.items() if K in KnownFields}
|
||||
|
||||
SaraTagData = Filtered.pop("SaraTag", None)
|
||||
if isinstance(SaraTagData, dict):
|
||||
KnownSaraTagFields = {F for F in SaraTagIntegrationConfig.__dataclass_fields__}
|
||||
SaraTagFiltered = {K: V for K, V in SaraTagData.items() if K in KnownSaraTagFields}
|
||||
for Key, Value in SaraTagFiltered.items():
|
||||
setattr(Config.SaraTag, Key, Value)
|
||||
|
||||
SaraSortdData = Filtered.pop("SaraSortd", None)
|
||||
if isinstance(SaraSortdData, dict):
|
||||
KnownSaraSortdFields = {F for F in SaraSortdIntegrationConfig.__dataclass_fields__}
|
||||
SaraSortdFiltered = {K: V for K, V in SaraSortdData.items() if K in KnownSaraSortdFields}
|
||||
for Key, Value in SaraSortdFiltered.items():
|
||||
setattr(Config.SaraSortd, Key, Value)
|
||||
|
||||
for Key, Value in Filtered.items():
|
||||
setattr(Config, Key, Value)
|
||||
Config.Save()
|
||||
|
||||
|
||||
def ApplyAppearance(Settings: SharedSettings) -> None:
|
||||
"""Theme colours and font. Must run before anything reads Palette.X or
|
||||
calls BuildTheme(). The window title bar is applied by Main."""
|
||||
|
||||
Reference in new issue
Block a user