Skip to content

Let the user choose which settings persist - #915

Merged
marcinz606 merged 1 commit into
mainfrom
feat/configurable-sticky-settings
Aug 19, 2026
Merged

Let the user choose which settings persist#915
marcinz606 merged 1 commit into
mainfrom
feat/configurable-sticky-settings

Conversation

@marcinz606

Copy link
Copy Markdown
Owner

What

Which settings carry onto a freshly-opened file is now a user choice, edited in a Persistent Settings… picker on the canvas menu.

Why

_apply_sticky_settings hard-coded the list across ~25 inline blocks reading 38 last_* global keys. The set had drifted: 11 of those keys had no reader at all (last_density, last_grade, last_wb_*, last_toe*, last_shoulder*, last_toning_config, last_retouch_config), 6 that were read got written from five other places, and nothing enumerated them.

How

settings_catalog.py already describes every copyable setting as a SettingRow and already knows how to overlay a chosen subset (apply_selected_fields). Sticky is the same operation with a different source, so it is rewritten on top of it rather than gated key by key:

  • Store: one snapshot of the last persisted edit + one list of chosen row ids, both in the existing global_settings table.
  • Apply: apply_selected_fields(snapshot, config, chosen_rows).
  • Rows carry a sticky=True default flag, so out-of-the-box behaviour is unchanged (50 of 140 rows).

Both functions shrink to a few lines, and all 140 catalog rows become opt-in stickyable — a look setting can be opted in, a default one opted out.

Four carries stay hard-coded

They are not plain config-value copies:

Carry Why
Flat-field profile_id/k1 rig-global, always overrides
Three wb_temp_lock* Kelvin locks re-aim M/Y via kelvin_to_wb
21 ExportConfig fields no catalog row — output folder, ICC paths, contact-sheet layout
linear_raw / narrowband_scan kept out of the catalog on purpose: as Process rows they'd land in _LOOK_ROWS, so preset "Replace look" would reset the decode mode

description_fields keeps its own key so the last Description… confirm wins for the roll rather than whichever frame was saved last.

A EXPORT_REMAINDER test asserts the catalog's Export rows plus the remainder cover ExportConfig exactly — that's the guard stopping a future export field from silently losing its carry (the output folder nearly did).

UI

GranularSettingsDialog gains a preselect_ids pick mode (values shown come from the snapshot, so the list reads as what would actually carry), and CollapsibleSection gains an optional tri-state header checkbox. Both default off, so paste/preset/apply callers are untouched.

Migration

Legacy last_* keys seed the snapshot once on startup, including the pre-rename last_true_black → inverted paper_black.

Testing

  • make lint, make type clean; 4574 passed.
  • New: tests/test_sticky_settings.py (18), tests/test_sticky_dialog.py (6); tests/test_desktop_session.py rewritten onto the new storage plus 5 new behaviour tests.
  • Driven end-to-end against the real app under Xvfb: menu item present, picker opens, choice persists, a ticked row carries onto a fresh file, an unticked one stops, and an already-edited file keeps its own look.

Note

tests/test_scanner_icc.py fails on this branch, but it fails identically on main — it is untracked WIP from another work stream and is not included here.

Which settings carried onto a freshly-opened file was hard-coded across ~25
inline blocks reading 38 `last_*` global keys. Eleven of those keys had no
reader at all, six were written from five other places, and nothing enumerated
them.

Rewrite the mechanism onto the existing settings catalog: the sticky store is
now one snapshot of the last persisted edit plus a list of chosen SettingRow
ids, applied with apply_selected_fields. Every catalog row becomes stickyable,
so a look setting can be opted in and a default one opted out.

Persistent Settings… in the canvas overflow menu opens the picker, reusing
GranularSettingsDialog in a new pick mode with tri-state group checkboxes on
CollapsibleSection.

Four carries stay hard-coded because they are not plain config-value copies:
the rig-global flat-field profile, the Kelvin roll-locks, the 21 ExportConfig
fields with no catalog row (output folder, ICC paths, contact-sheet layout),
and the scan-setup prefs, which are kept out of the catalog so preset "Replace
look" cannot reset the decode mode. Description fields keep their own key so
the last confirm wins for the roll.

Legacy keys migrate once on startup.
@marcinz606
marcinz606 marked this pull request as ready for review August 19, 2026 20:50
@marcinz606
marcinz606 merged commit cba28dc into main Aug 19, 2026
1 check was pending
@marcinz606
marcinz606 deleted the feat/configurable-sticky-settings branch August 19, 2026 20:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant