spacr.qt.preferences

User-facing preferences — language, theme, font scale and accessibility.

Persistent settings backed by PySide6.QtCore.QSettings, so they survive app restarts. New knobs can slot in alongside the existing ones without changing consumers thanks to the small typed API (get_theme() / set_theme(...) etc.).

Wire-up:

Public API:

from spacr.qt.preferences import (
    get_theme, set_theme, get_theme_choice, set_theme_choice,
    get_language, set_language,
    get_cell_variant, set_cell_variant,
    cell_background_path,
    theme_background_path,
    get_sound_music_file, set_sound_music_file,
    get_ambient_enabled, set_ambient_enabled,
    get_ambient_animation, set_ambient_animation,
    get_ambient_theme, set_ambient_theme,
    get_spacr_mode, set_spacr_mode, mode_label, mode_note, mode_warning,
    confirm_resource_action, run_resource_action,
    get_ambient_palette, set_ambient_palette,
    get_ambient_blur, set_ambient_blur,
    get_ambient_speed, set_ambient_speed,
    get_ambient_size, set_ambient_size,
    get_ambient_resolution, set_ambient_resolution,
    get_ambient_density, set_ambient_density,
    get_ambient_drift_direction, set_ambient_drift_direction,
    get_spinner_delay, set_spinner_delay,
    ambient_default_palette, apply_ambient_preferences,
    get_setting_animations_enabled, set_setting_animations_enabled,
    get_tooltips_enabled, set_tooltips_enabled,
    get_font_scale, set_font_scale,
    get_gui_scale, set_gui_scale,
    get_figure_save_mode, set_figure_save_mode,
    get_color_blind_mode, set_color_blind_mode,
    get_db_browser_editable, set_db_browser_editable,
    get_dock_mode, set_dock_mode,
    get_pane_opacity, set_pane_opacity, effective_pane_alpha,
    get_field_fade_enabled, set_field_fade_enabled,
    get_show_alpha, set_show_alpha,
    get_show_beta, set_show_beta, maturity_is_visible,
    apply_preferences_to_app,
    PreferencesDialog,
)

Values:

  • theme: "dark" | "light" | "cell" | "glass" | "high_contrast" | one of the ten night themes in spacr.qt.night_themes.NIGHT_THEME_KEYS | the five data-art presets in spacr.qt.night_themes.DATA_ART_THEME_KEYS | "system" (default "dark"). "system" follows the operating system color scheme, and only once somebody has picked it: a stored "system" written before dark became the default (2026-09-21) was the old default, not a choice, and reads as "dark"; see get_theme(). "cell" uses fluorescence imagery and "glass" uses neutral layered materials over a built-in light field. A night or data-art preset also carries a backdrop and a sound set, written by apply_night_theme() when it is chosen. Space is not a selectable theme. The retired space_variant and space_seed values are removed from an older store the first time the theme is read; see get_theme().

  • font_scale: float, 1.0 = 100 % (the default). Clamped to [0.10, 2.0].

  • gui_scale: float, 1.0 = 100 % (the default). Clamped to [0.10, 2.0]. Scales every size of the interface, not only text, and applies live. See spacr.qt.gui_scale.

  • figure_save_mode: "print" | "screen" | "transparent" (default "print"). Controls the page and figure-element colours used for saved figures. SPACR_FIGURE_SAVE_MODE remains a process-local override; see spacr.figure_style.figure_save_mode().

  • color_blind_mode: "off" | "deuteranopia" | "protanopia" | "tritanopia" (default "off"). Swaps matplotlib rainbow / red-green palettes for perceptually-uniform + colour-blind-safe alternatives (viridis for continuous, Okabe-Ito for categorical).

  • performance_logging: "off" | "summary" | "detailed" (default "summary"). Records process-tree resource use independently of verbose call tracing; see get_performance_logging() and spacr.resource_log.

  • db_browser_editable: bool, default False. Permits the Database Browser to open a read-write connection at all; see get_db_browser_editable().

  • dock_mode: "locked" | "hidden" (default "locked"). Whether the left app dock reveals on hover, is pinned open as a permanent column, or is not there at all.

  • pane_opacity: int percent, default 60. How solid shared surfaces are, or the relative material strength in Glass. Clamped up to spacr.qt.theme.pane_alpha_floor() at paint time — the preference is a request, legibility is not negotiable.

  • field_fade: bool, default True. Whether an input field’s container and outline ramp from solid on the left to fully transparent on the right. Fields are exempt from pane_opacity while this is on — see get_field_fade_enabled() and spacr.qt.widgets.field_fade.

  • show_alpha / show_beta: bool, both default True. Control whether modules and settings at that maturity are shown. Stable features are always visible.

  • sound/music_file: str, default "". A WAV of the user’s own that the music bed plays instead of the synthesized one, and that the Resonance backdrop is driven by. See get_sound_music_file().

  • ambient_enabled: bool, default True. Whether module screens paint the animated background at all. Turning it off is a first-class choice — see get_ambient_enabled(). The user-facing control is the None entry in the Animation list rather than a second switch: one row, one meaning. Choosing an animation turns it back on.

  • spacr_mode: "extra_performance" | "performance" | "balanced" (default "balanced"). How hard spaCR tries to stay out of the machine’s way — when it frees its own caches, and whether it overrides the visual settings. Balanced does neither. See set_spacr_mode() and spacr.qt.resource_cleanup, which owns what a cleanup is allowed to touch (spaCR’s own memory, and nothing else — no other process, ever).

  • ambient_theme / ambient_palette: which animation, and in which colours. ambient_theme also holds spacr.qt.widgets.ambient.NO_ANIMATION — read it with get_ambient_animation(), which can answer "none", or with get_ambient_theme(), whose answer is always something paintable. Validated against spacr.qt.widgets.ambient.AMBIENT_THEMES and spacr.qt.widgets.ambient.palettes_for() respectively; palettes are per theme, so see get_ambient_palette() for how the two keys stay consistent with each other.

  • ambient_speed / ambient_size / ambient_resolution / ambient_density: floats; speed, size and detail default to 1.0, density to 0.1. All are multipliers on what the chosen animation already does — how fast it moves, how large its elements are, how much detail it is drawn with and how many elements there are. Clamped on read and on write to the ranges the engines declare (spacr.qt.widgets.ambient.SPEED_RANGE and friends).

  • ambient_blur: a legacy float retained for reading older preferences. Current animation widgets render without this saved blur setting. Image detail is controlled by ambient_resolution.

  • ambient_drift_direction: "up" | "down" | "random" (default "up"). Which way spaCR stratified travels. A preference rather than three entries in the animation menu; see spacr.qt.widgets.ambient.DRIFT_DIRECTIONS for why.

  • spinner_delay: float seconds, default 2.0. How long background work has to run before the activity spinner appears at all — see get_spinner_delay().

  • setting_animations: bool, default False. Whether setting tooltips play their animations automatically. When disabled, hover remains text-only until the user activates Animation in that tooltip’s footer; see get_setting_animations_enabled().

  • language: one of the bundled language codes from spacr.qt.i18n; defaults to English and falls back safely when a persisted value is invalid.

Classes

PreferencesDialog

Wrapper that builds the modal Preferences dialog on demand.

Functions

ambient_default_palette(→ str)

The palette a theme falls back to.

apply_ambient_preferences(→ None)

Push the ambient preferences onto every live ambient widget.

apply_figure_style(→ dict)

Push the user's style for kind into matplotlib. Returns it.

apply_night_theme(→ None)

Write the backdrop and sound set a night or data-art preset brings.

apply_preferences_to_app(→ None)

Re-apply language, theme and font scale to QApplication.

apply_quality_preset(→ dict)

Set the numbers a quality level implies, and return them.

apply_workspace_preference(→ str)

Push the stored preference into spacr.workspace. Call at startup.

auto_figure_colors(→ tuple)

What AUTO_FIGURE_COLOR resolves to right now, as

backdrop_is_switched_off(→ bool)

Whether the user has turned the animated backdrop off and left it.

cell_background_path([width, height])

Path of the background image for the Cell theme, or None.

clear_dashboard_watermark(→ None)

Forget which's watermark, so its panel shows everything again.

clear_figure_style_default(→ bool)

Forget the default for kind. True if there was one.

color_blind_categorical_palette(→ list)

Return a list of hex colours safe for the active CB mode.

color_blind_continuous_cmap(→ str)

Return a matplotlib colormap name safe for the active CB mode.

confirm_resource_action(→ bool)

Ask before doing action, by saying what it will do.

effective_pane_alpha(→ float)

The opacity a user-controlled page surface is painted at.

enable_safe_mode(→ None)

Read preferences as defaults for the rest of this process.

explain_a_fractal_number(→ str)

Why value cannot be used for name, or "" if it can.

explain_every_row(→ int)

Put a tooltip on every Preferences LABEL. Returns how many it set.

figure_bg_is_transparent(→ bool)

Whether bg means "let whatever is behind show through".

figure_color_is_auto(→ bool)

Whether token is the "follow the theme" token rather than a colour.

get_ai_on_by_default(→ bool)

Is the assistant on when spaCR opens?

get_ambient_animation(→ str)

Which animation the user chose, or NO_ANIMATION for none.

get_ambient_blur(→ float)

Read the retained legacy animation-blur preference.

get_ambient_density(→ float)

How many elements the animated background draws — blobs, curtains,

get_ambient_drift_direction(→ str)

Which way spaCR stratified travels.

get_ambient_enabled(→ bool)

Whether module screens paint the animated background.

get_ambient_palette(→ str)

Which colours the current ambient theme is painted in.

get_ambient_resolution(→ float)

The drawing-detail multiplier on each animation's working grid.

get_ambient_size(→ float)

How large the animated background's elements are, as a multiplier on

get_ambient_speed(→ float)

How fast the animated background moves, as a multiplier on each

get_ambient_theme(→ str)

Which animation screens paint in the active launch mode.

get_cache_ceiling_mb(→ int)

How much cache spaCR may hold at once, in megabytes.

get_cell_variant(→ str)

Which of the user's micrographs the Cell theme uses.

get_color_blind_mode(→ str)

Return the active colour-vision mode, falling back to off.

get_dashboard_watermark(→ str)

When Home's which panel was last cleared, as a UTC ISO string.

get_database_write_queue_gib(→ float)

Return the serialized database queue RAM budget in GiB.

get_db_browser_editable(→ bool)

True when the user has allowed the Database Browser to write.

get_default_graph_type(→ str)

The graph type the user wants drawn first for shape.

get_default_graph_types(→ dict)

Every saved default graph type, as {shape: graph_type}.

get_dock_mode(→ str)

How the left app dock behaves — one of VALID_DOCK_MODES.

get_dock_width(→ int)

The width the user dragged the dock to, or 0 for its fitting width.

get_field_fade_enabled(→ bool)

Whether input fields dissolve towards their right edge.

get_figure_color_tokens(→ tuple)

The STORED (background, text) tokens, unresolved.

get_figure_colors(→ tuple)

Return (background, text) hex colours for rendered figures,

get_figure_dynamic(→ bool)

Whether an evicted figure is reloaded from its vector page on demand.

get_figure_format(→ str)

Return the saved figure format, falling back to pdf.

get_figure_grid_size(→ int)

The tile width the user last chose, or the grid's own default.

get_figure_line_colour(→ str)

The colour a figure's LINES are drawn in, "auto" resolved.

get_figure_line_token(→ str)

The STORED line colour token, unresolved.

get_figure_live_cache(→ int)

How many of the most recent figures keep their live matplotlib Figure.

get_figure_png_dpi(→ int)

Return the saved PNG resolution, or the 300-DPI default.

get_figure_save_mode(→ str)

Return the saved figure appearance mode, defaulting to print.

get_figure_style(→ dict)

The user's GENERAL figure settings, or an empty dict.

get_figure_style_default(→ dict)

The saved default for one kind of style, or {}.

get_figure_style_defaults(→ dict)

Every saved per-project style default, as {kind: {field: value}}.

get_figure_style_per_graph(→ dict)

Per-graph overrides, {kind: {setting: value}}.

get_figure_text_size(→ int)

Return the saved figure font size; zero leaves Matplotlib unchanged.

get_folded_panels(→ dict)

Which panels the user left folded, {key: True}, or opened, {key: False}.

get_font_scale(→ float)

Return the saved UI font scale, clamped to supported bounds.

get_fractal_settings(→ dict)

Every spaceout fractal setting, ready for Settings/RuntimeControls.

get_gui_scale(→ float)

Return the saved whole-GUI scale, clamped to supported bounds.

get_hash_inputs(→ bool)

Whether a run hashes its inputs and outputs for the manifest.

get_headroom_mb(→ int)

How much memory must stay free for everything else on the machine.

get_idle_minutes(→ float)

How long an unused cache entry may sit before it is dropped.

get_interface_font_weight(→ str)

Which Open Sans weight the interface's body text uses.

get_issue_prompt_mode(→ str)

How to behave when a report could be filed.

get_language(→ str)

Return the persisted UI language code, falling back to English.

get_laptop_mode(→ str)

Whether laptop constraints apply.

get_log_console_levels(→ frozenset)

Levels echoed to the in-app console, always a subset of the files.

get_log_file_levels(→ frozenset)

Levels written to the log files. The master switch of the pair.

get_montage_columns(→ int)

Cells per row in a well's montage tab.

get_news_height(→ int)

The remembered height of Home's release-notes list, or 0.

get_pane_opacity(→ float)

The user's requested page-panel opacity, 0.0-1.0.

get_performance_level(→ str)

The single performance level, one of PERFORMANCE_LEVELS.

get_performance_logging(→ str)

Return the independent process-tree resource logging level.

get_popup_backdrop(→ str)

Which ambient theme drifts behind a settings popup, or 'off'.

get_preferred_provider(→ str)

Return the preferred AI provider name.

get_preload_policy(→ str)

When to import torch and the rest. 'on_demand' or 'eager'.

get_refresh_news(→ bool)

Whether Home's News panel may ask GitHub for newer releases.

get_rim_alignment(→ str)

Where the lit run sits relative to the pointer.

get_rim_lag(→ float)

How far the accent closes the gap to the pointer each frame.

get_rim_length(→ int)

Pixels of rim the accent lights up.

get_rim_mode(→ str)

Which way the rim is coloured -- glow, rainbow or beat.

get_rim_period(→ float)

Seconds for one pulse of beat or one hue turn of rainbow.

get_runtime_text_scale(→ float)

The right-hand column's text size, clamped to its bounds.

get_save_workspace(→ str)

Return how a completed run records its open workspace.

get_saved_sound_enabled(→ bool)

The stored master sound switch, whatever the mode.

get_section_layout(→ dict)

What panel looked like when it was last used.

get_setting_animations_enabled(→ bool)

Whether setting tooltips show their animation WITHOUT being asked.

get_share_diagnostic_logs(→ bool)

Whether an error report saves a redacted copy of the recent log.

get_show_alpha(→ bool)

Whether Alpha modules and settings are visible (default: True).

get_show_beta(→ bool)

Whether Beta modules and settings are visible (default: True).

get_sound_enabled(→ bool)

Whether spaCR plays any sound at all. Default False.

get_sound_event_enabled(→ bool)

Whether one event's sound is switched on, apart from the master.

get_sound_music_file(→ str)

A WAV of the user's own to play as the music bed, or "".

get_sound_theme(→ str)

Which sound set plays, validated against the sets that exist.

get_sound_volume(→ float)

The master volume, 0 to 1, clamped on read.

get_spacr_mode(→ str)

Which resource posture spaCR is in — one of SPACR_MODES.

get_spinner_delay(→ float)

How long background work must run before the activity spinner shows.

get_theme(→ str)

Return the saved application theme, or the default when invalid.

get_theme_choice(→ str)

Return the composite token representing the current visual theme.

get_tooltips_bottom_enabled(→ bool)

Whether a hovered setting's help also appears in the bottom strip.

get_tooltips_box_enabled(→ bool)

Whether hovering a setting's title opens the tooltip box.

get_tooltips_enabled(→ bool)

Whether ordinary tooltips appear anywhere in spaCR. Default True.

get_verbose_logging(→ bool)

Return True when the user has opted into the verbose diagnostic

get_workspace_copy_limit_mb(→ float)

The per-file ceiling on what copy mode brings in, in megabytes.

image_display_primaries(→ str)

How images should be drawn for this user, everywhere.

in_safe_mode(→ bool)

Whether this process is running in safe mode.

laptop_mode_note(→ str)

What the chosen setting will do on THIS machine, said before saving.

live_figure_allowance(→ int)

How many figures stay editable at this level.

maturity_is_visible(→ bool)

Return whether a maturity stage should be present in the UI.

mode_label(→ str)

The name the dropdown shows for mode — e.g. "Extra Performance".

mode_note(→ str)

What mode does, as the standing description under the dropdown.

mode_warning(→ str)

What choosing mode will cost, or "" when it costs nothing.

resolve_effective_theme(→ str)

Return the theme to render — one of PALETTE_THEMES.

retention_scale(→ float)

How much reusable state this level allows, relative to Balanced.

run_resource_action(action[, parent])

Confirm action, run it, and report the measured result.

scale_group_values(→ dict)

What one Scale means for every setting that follows it.

scaled_px(→ int)

Return base_px scaled by the current user font scale.

set_ai_on_by_default(→ None)

Persist whether the assistant starts enabled.

set_ambient_animation(→ None)

Persist an entry of ANIMATION_CHOICES, "none" included.

set_ambient_blur(→ None)

Store the legacy animation-blur preference. Current widgets ignore it.

set_ambient_density(→ None)

Set the element-count multiplier. Clamped.

set_ambient_drift_direction(→ None)

Persist one of spacr.qt.widgets.ambient.DRIFT_DIRECTIONS.

set_ambient_enabled(→ None)

Turn the animated background on or off.

set_ambient_palette(→ None)

Persist a palette offered by the current ambient theme.

set_ambient_resolution(→ None)

Set the detail multiplier. Clamped.

set_ambient_size(→ None)

Set the element-size multiplier. Clamped.

set_ambient_speed(→ None)

Set the motion multiplier. Clamped.

set_ambient_theme(→ None)

Persist an animation offered in the active launch mode.

set_cache_ceiling_mb(→ None)

Persist the cache ceiling.

set_cell_variant(→ None)

Persist one of the bundled Cell-theme microscopy variants.

set_color_blind_mode(→ None)

Persist a supported colour-vision mode.

set_dashboard_watermark(→ str)

Move which's watermark to when, or to now when empty.

set_database_write_queue_gib(→ None)

Persist the database queue payload budget for subsequent runs.

set_db_browser_editable(→ None)

Allow (or forbid) edit mode in the Database Browser.

set_default_graph_type(→ None)

Persist which graph is drawn first for shape.

set_dock_mode(→ None)

Persist a valid left-navigation dock mode.

set_dock_width(→ None)

Persist the dock's dragged width; 0 goes back to the fitting width.

set_field_fade_enabled(→ None)

Turn the field fade on or off.

set_figure_colors(→ None)

Persist background and text colour TOKENS for generated figures.

set_figure_colors_auto(→ None)

Put both halves back to "follow the theme".

set_figure_dynamic(→ None)

Persist whether evicted figures reload from their vector page.

set_figure_format(→ None)

Persist a supported figure format.

set_figure_grid_size(→ None)

Remember the tile width, clamped to what the grid will accept.

set_figure_line_colour(→ None)

Persist the line colour TOKEN. Pass AUTO_FIGURE_COLOR for

set_figure_live_cache(→ None)

Persist how many figures keep their live Figure.

set_figure_png_dpi(→ None)

Persist one of VALID_PNG_DPIS.

set_figure_save_mode(→ None)

Persist the saved-figure appearance mode.

set_figure_style(→ None)

Store the general figure settings.

set_figure_style_default(→ None)

Make values the default for every future figure of kind.

set_figure_style_per_graph(→ None)

Store the per-graph overrides.

set_figure_text_size(→ None)

Persist a figure font size; zero delegates sizing to Matplotlib.

set_folded_panel(→ None)

Remember that key is folded, or is not.

set_font_scale(→ None)

Persist a UI font scale after clamping it to supported bounds.

set_fractal_settings(→ None)

Persist any subset of the fractal settings.

set_gui_scale(→ None)

Persist a whole-GUI scale after clamping it to supported bounds.

set_hash_inputs(→ None)

Persist the input-hashing choice.

set_headroom_mb(→ None)

Persist the headroom floor.

set_idle_minutes(→ None)

Persist the idle timeout.

set_interface_font_weight(→ None)

Persist the weight and apply it to the running application.

set_issue_prompt_mode(→ None)

Persist the auto-issue behaviour, and that it was chosen.

set_language(→ None)

Persist one of the bundled UI languages.

set_laptop_mode(→ None)

Persist the laptop-mode preference and apply it now.

set_log_levels(→ tuple)

Persist both switch sets, then apply them to the live handlers.

set_montage_columns(→ int)

Store the cells-per-row count. Returns the value actually stored.

set_news_height(→ int)

Remember how tall Home's release-notes list was dragged.

set_pane_opacity(→ None)

Store the requested opacity. Accepts 0.0-1.0; clamped, then rounded.

set_performance_level(→ None)

Persist the performance level.

set_performance_logging(→ None)

Persist the process-tree resource logging level.

set_popup_backdrop(→ str)

Store the popup backdrop. An unknown name stores the default.

set_preferred_provider(→ None)

Store the preferred AI provider name.

set_preload_policy(→ None)

Persist it. Takes effect at the next launch, and says so.

set_refresh_news(→ None)

Persist the News panel's release-refresh opt-out.

set_rim_alignment(→ str)

Store the alignment. An unknown name stores the default instead.

set_rim_lag(→ float)

Store the chase fraction. Returns the value actually stored.

set_rim_length(→ int)

Store the rim length. Returns the value actually stored.

set_rim_mode(→ str)

Store the rim mode. An unknown name stores the default instead.

set_rim_period(→ float)

Store the pulse period. Returns the value actually stored.

set_runtime_text_scale(→ float)

Persist the right-hand column's text size, clamped to its bounds.

set_save_workspace(→ str)

Store the workspace mode and update the process-wide default.

set_section_layout([sizes, steps, boxes])

Remember which sections of panel are folded, and the divider sizes.

set_setting_animations_enabled(→ None)

Turn the animation inside setting tooltips on or off.

set_share_diagnostic_logs(→ None)

Persist the revocable diagnostic-log preview opt-in.

set_show_alpha(→ None)

Show or hide modules and settings classified as Alpha.

set_show_beta(→ None)

Show or hide modules and settings classified as Beta.

set_sound_enabled(→ None)

Persist the master sound switch.

set_sound_event_enabled(→ None)

Persist one event's switch.

set_sound_music_file(→ str)

Persist the music file the bed plays.

set_sound_theme(→ None)

Persist the chosen sound set.

set_sound_volume(→ float)

Persist the master volume.

set_spacr_mode(→ None)

Persist the mode, and move the visual settings with it.

set_spinner_delay(→ None)

Set the spinner's appearance delay, in seconds. Clamped, not

set_theme(→ None)

Persist a supported application theme.

set_theme_choice(→ None)

Persist one token from theme_choices().

set_tooltips_bottom_enabled(→ None)

Turn the bottom tooltip strip on or off, effective at the next hover.

set_tooltips_box_enabled(→ None)

Turn the hover tooltip box on or off, effective at the next hover.

set_tooltips_enabled(→ None)

Turn every tooltip on or off, effective immediately.

set_verbose_logging(→ None)

Persist whether package-wide diagnostic tracing is enabled.

set_workspace_copy_limit_mb(→ float)

Remember the per-file copy limit, and push it down with the mode.

sound_bed_rests(→ bool)

Whether the current performance level silences the music bed.

sound_is_offered(→ bool)

Whether this process offers sound at all: only in spaceout mode.

spacr_mode_for_level(→ str)

The resource posture a level implies, in the old three-mode words.

speed_group_values(→ dict)

What one Speed means for every setting that follows it.

theme_background_path(theme[, width, height])

Background image for theme, or None if it does not use one.

theme_choices(→ tuple)

Return (label, token) choices for the single Theme control.

theme_description(→ str)

Return the one-sentence explanation of a theme_choices() token.

Module Contents

class spacr.qt.preferences.PreferencesDialog[source]

Wrapper that builds the modal Preferences dialog on demand.

Kept as a factory (not a real class subclass) so this module can be imported headless without pulling in QtWidgets. The real QDialog – the subclass _preferences_window_class() makes on first use – is returned by PreferencesDialog(parent).

Build the dialog with the UI language resolved once.

The scope is the whole reason this wrapper exists. Building this dialog was measured asking the preference store what language the interface is in 346 times, through 415 QSettings reads, and none of those answers could differ: nothing runs between them.

Parameters:

parent – parent widget, or None.

Returns:

the dialog, ready to exec.

__new__(parent=None)[source]

Build the dialog with the UI language resolved once.

The scope is the whole reason this wrapper exists. Building this dialog was measured asking the preference store what language the interface is in 346 times, through 415 QSettings reads, and none of those answers could differ: nothing runs between them.

Parameters:

parent – parent widget, or None.

Returns:

the dialog, ready to exec.

spacr.qt.preferences.ambient_default_palette(theme: str) → str[source]

The palette a theme falls back to.

spacr.qt.widgets.ambient.DEFAULT_PALETTE when that theme offers it (spaCR’s own brand colours are the intended default everywhere they exist), otherwise the theme’s first palette. Never raises for an unknown theme — it reports the global default.

Parameters:

theme – an ambient theme name, as offered by spacr.qt.widgets.ambient.AMBIENT_THEMES; an unknown name gives the global default palette.

spacr.qt.preferences.apply_ambient_preferences(app=None) → None[source]

Push the ambient preferences onto every live ambient widget.

The user’s explicit ask was a toggle that works now, so this walks the running widget tree the same way spacr.qt.button_roles.install_button_roles() does and updates the widgets in place instead of waiting for the screens to be rebuilt. Hiding one also stops its timer (the widget stops animating whenever it is not visible), so “off” really is zero frames.

The settings-window backdrop has its own choice and remains active when module animation is off unless its own choice is None.

Turning module animation back on only resumes the widgets that are actually on screen. Every module screen keeps its ambient widget alive while the user is on some other tab, and un-pausing those would spend frames on pixels nobody can see — which is the one thing this animation is not allowed to do. Their own showEvent restarts them when the tab comes back.

Never raises. A widget whose C++ half is already gone, or an ambient module that could not be imported, is a cosmetic problem — not a reason to fail a preferences save.

spacr.qt.preferences.apply_figure_style(kind: str | None = None) → dict[source]

Push the user’s style for kind into matplotlib. Returns it.

The one call a plotting function needs: it reads the preferences, layers them over the defaults and this graph kind’s own, and applies the result.

spacr.qt.preferences.apply_night_theme(name: str) → None[source]

Write the backdrop and sound set a night or data-art preset brings.

A night theme is one choice that moves three things: the colours, the animation behind them and the set of sounds spaCR would play. So this writes the ambient animation, the ambient palette and the sound set that go with the colours.

IT DOES NOT SWITCH ANYTHING ON. The sound master stays exactly where the user left it, which on a fresh install and on every install that has never opened the Sound tab is off; all this decides is which set would play if it were ever switched on. It leaves the animation master alone in the same way: if the backdrop is off, the stored animation is what comes back when it is switched on again, and set_ambient_animation() is not used here for exactly that reason – that setter also switches the backdrop on.

IT IS A PRESET, NOT AN OVERRIDE. The three values are written once, at the moment the theme is chosen, into the same keys the Animation and Sound controls read and write. Nothing re-imposes them, so a user who picks Nocturne and then changes the animation to Bokeh keeps Bokeh.

AND IT NEVER SWITCHES THE BACKDROP BACK ON. “No animation” is stored as the animation NAME (spacr.qt.widgets.ambient.NO_ANIMATION), which get_ambient_enabled() reads, so writing an animation over it would hand a moving backdrop to a user who had turned motion off – through the Animation control, or through Extra Performance, which turns it off the same way. backdrop_is_switched_off() is therefore asked first, and when it says yes the two ambient keys are left exactly as they are. The theme still changes the colours and the sound set; it just does not start anything moving. What that costs is small and worth saying: a user who later switches the backdrop on gets the animation they had before, not the one this theme would have brought, and they can pick it on the same control they just used.

Parameters:

name – a night or data-art preset key.

Raises:

KeyError – if name is unknown.

spacr.qt.preferences.apply_preferences_to_app(app=None) → None[source]

Re-apply language, theme and font scale to QApplication.

Called at startup from spacr.qt.app.launch(), and again whenever the user changes a preference (via PreferencesDialog accepted signal).

Parameters:

app – optional QApplication. Falls back to QApplication.instance().

spacr.qt.preferences.apply_quality_preset(quality: str) → dict[source]

Set the numbers a quality level implies, and return them.

Parameters:

quality – one of FRACTAL_QUALITIES.

Returns:

what was applied; empty for auto or an unknown level.

auto applies nothing on purpose: it means “decide from the machine” and the renderer does that per backend, so writing numbers here would turn a decision that follows the hardware into one frozen at the moment somebody opened Preferences.

spacr.qt.preferences.apply_workspace_preference() → str[source]

Push the stored preference into spacr.workspace. Call at startup.

Without this the journal writes the module default on the first run of every session, whatever the user chose last time.

spacr.qt.preferences.auto_figure_colors() → tuple[source]

What AUTO_FIGURE_COLOR resolves to right now, as (background, text).

Public because a control that offers “Follow the theme” has to SHOW what that currently means without storing it. Storing what this returns is the bug the section header describes; previewing it is the fix.

TRANSPARENT, not the theme’s window colour. “auto” used to resolve to #000000 on a dark theme, which is where the black slab behind every plot came from: an opaque black rectangle sitting on a container that is a translucent SURFACE. bg is the window colour and a figure is not a window (INVARIANTS 2).

Transparent also means the page-opacity preference reaches the plot for free, and one value is right for both themes — baking in a grey would freeze one opacity into every figure while everything around it kept following the preference.

spacr.qt.preferences.backdrop_is_switched_off() → bool[source]

Whether the user has turned the animated backdrop off and left it.

The STORED choice, not the live answer: get_ambient_enabled() also reports False for SPACR_NO_BACKDROP, which spacr.qt.crash_recovery sets for one process after two failed launches. That is a suppression and not a preference, and treating it as one would silently strip the backdrop out of a theme the user chose during that one run.

Returns:

True when the Animation control reads “None”, or when the separate on/off key is off.

spacr.qt.preferences.cell_background_path(width: int = 0, height: int = 0)[source]

Path of the background image for the Cell theme, or None.

None when the masters were stripped from the build; the stylesheet then paints the Cell gradient, which is a dark teal wash rather than anything broken.

spacr.qt.preferences.clear_dashboard_watermark(which: str) → None[source]

Forget which’s watermark, so its panel shows everything again.

Parameters:

which – the Home panel, "runs" or "totals" (the keys of DASHBOARD_WATERMARKS); any other name does nothing.

spacr.qt.preferences.clear_figure_style_default(kind: str) → bool[source]

Forget the default for kind. True if there was one.

The way back, and it is not optional: a default that can only be set is the same trap as a colour that can only be set.

Parameters:

kind – the figure kind, e.g. "volcano", as spacr.style_base.style_kind() derives it; converted to str.

spacr.qt.preferences.color_blind_categorical_palette() → list[source]

Return a list of hex colours safe for the active CB mode.

Uses the Okabe-Ito categorical palette whenever colour-blind mode is enabled.

spacr.qt.preferences.color_blind_continuous_cmap() → str[source]

Return a matplotlib colormap name safe for the active CB mode.

  • Off → the current default ("viridis" is already CB-safe but keeping the app’s default until the user asks otherwise).

  • Any CB mode → "cividis" (viridis’s cousin, tuned for protanopia + deuteranopia + tritanopia).

spacr.qt.preferences.confirm_resource_action(action: str, parent=None) → bool[source]

Ask before doing action, by saying what it will do.

The dialog states the steps in the order they will happen and what the action cannot do (see spacr.qt.resource_cleanup.confirmation_text()), and its accept button is labelled with the action rather than “OK”. “Are you sure?” is not a question anybody can answer: a user cannot consent to an unnamed action, and a button called OK does not name one.

Cancel is the default, so a stray Return key does nothing.

Parameters:
  • action – which clean-up to confirm: "ram", "vram", "cpu" or "disk".

  • parent – the widget the message box is parented to, or None.

Returns:

True only if the user explicitly accepted.

spacr.qt.preferences.effective_pane_alpha() → float[source]

The opacity a user-controlled page surface is painted at.

The user’s request put through spacr.qt.theme.pane_alpha(). One call so the Home page and any test asking “what will it look like” get the same number.

spacr.qt.preferences.enable_safe_mode() → None[source]

Read preferences as defaults for the rest of this process.

Called by the safespacr entry point before any preference is read. Idempotent.

spacr.qt.preferences.explain_a_fractal_number(name: str, value) → str[source]

Why value cannot be used for name, or "" if it can.

Parameters:
  • name – a fractal setting name.

  • value – whatever the field holds.

Returns:

a sentence for the user, empty when the value is fine.

THE FIELD TAKES ANYTHING; this is what decides whether it WORKS. The message names the setting, the value and the reason, because “invalid input” tells a user only that the software disagrees with them.

spacr.qt.preferences.explain_every_row(dialog) → int[source]

Put a tooltip on every Preferences LABEL. Returns how many it set.

Two jobs, and the second is why this walks the finished dialog rather than being written at each call site: it fills in from PREFERENCE_TIPS, and it MOVES a tooltip that was put on the control to the label beside it. A row explained either way ends up explained the same way, and a row added later without a tooltip is reported by the test rather than passing unnoticed.

Parameters:

dialog – the finished Preferences dialog; every QFormLayout inside it is walked, and each row whose label is a QLabel is given a tooltip when one is known.

spacr.qt.preferences.figure_bg_is_transparent(bg: str) → bool[source]

Whether bg means “let whatever is behind show through”.

Parameters:

bg – a background colour token; "none", "transparent" and the empty string (after stripping and lower-casing) mean transparent.

spacr.qt.preferences.figure_color_is_auto(token) → bool[source]

Whether token is the “follow the theme” token rather than a colour.

Matching is case- and space-insensitive because tokens can come from a hand-edited INI file or the dialog.

Parameters:

token – a stored colour token or colour string; converted to str before comparing with AUTO_FIGURE_COLOR.

spacr.qt.preferences.get_ai_on_by_default() → bool[source]

Is the assistant on when spaCR opens?

Returns:

DEFAULT_AI_ON_AT_LAUNCH unless the user has said otherwise. An explicit choice is always written, so an opt-out survives a change to the default rather than being overwritten by it.

spacr.qt.preferences.get_ambient_animation() → str[source]

Which animation the user chose, or NO_ANIMATION for none.

The value the Preferences dropdown shows. Use get_ambient_theme() when you are about to paint something — it never returns "none".

spacr.qt.preferences.get_ambient_blur() → float[source]

Read the retained legacy animation-blur preference.

Current animation widgets do not apply this value, and Settings has no Blur control. Drawing detail is controlled by get_ambient_resolution().

The legacy value is clamped to spacr.qt.widgets.ambient.BLUR_RANGE on read.

spacr.qt.preferences.get_ambient_density() → float[source]

How many elements the animated background draws — blobs, curtains, ripple sources, stars, discs, cells — as a multiplier on each animation’s own count. 1.0 is as designed.

Density determines the population independently of detail. Render sampling and the native screen-pixel budget bound the combined work.

spacr.qt.preferences.get_ambient_drift_direction() → str[source]

Which way spaCR stratified travels.

Validated on read against spacr.qt.widgets.ambient.DRIFT_DIRECTIONS, so a value from a newer build or a hand-edited file falls back to the default rather than reaching an engine that cannot honour it.

spacr.qt.preferences.get_ambient_enabled() → bool[source]

Whether module screens paint the animated background.

Answers False outright when SPACR_NO_BACKDROP is set, whatever is stored. spacr.qt.crash_recovery sets it after spaCR has died on launch twice running: the backdrop is the only thing spaCR asks a driver to do at startup, and the setting that would turn it off is behind the window that never appears. Process-local and never saved, so the next clean run brings it back with nothing for the user to undo.

Default True. When this is False no ambient widget should be installed at all — and any already-installed one is hidden and stopped by apply_ambient_preferences(), so the toggle takes effect the moment Preferences is saved rather than at the next launch.

Two keys answer this one question, and both are honoured. The Animation preference gained a None entry (see spacr.qt.widgets.ambient.NO_ANIMATION), and “no animation” has to mean nothing is constructed rather than “an engine that paints an empty frame sixty times a second”. The three install sites all read this function before they build anything, so answering False for None here is what makes the guarantee true everywhere at once, without a second condition in three other modules that could drift apart.

The separate on/off key stays because it is the programmatic switch — spacr.qt.resource_cleanup uses it, and so does any caller that wants the animation back exactly as the user had it.

spacr.qt.preferences.get_ambient_palette() → str[source]

Which colours the current ambient theme is painted in.

Validated against palettes_for(get_ambient_theme()), so this can never hand a widget a palette its theme does not have — not after a downgrade, not after a hand-edited INI, and not after a theme change that stranded the old palette. Falls back to ambient_default_palette() for the current theme.

spacr.qt.preferences.get_ambient_resolution() → float[source]

The drawing-detail multiplier on each animation’s working grid.

1.0 is as designed. Higher detail increases sampling work within the engine’s screen-pixel limits. get_ambient_density() controls the selected population independently; increasing detail does not reduce that population. Current widgets apply no animation blur.

spacr.qt.preferences.get_ambient_size() → float[source]

How large the animated background’s elements are, as a multiplier on each theme’s own size range. 1.0 is as designed.

spacr.qt.preferences.get_ambient_speed() → float[source]

How fast the animated background moves, as a multiplier on each theme’s own motion. 1.0 is as designed.

spacr.qt.preferences.get_ambient_theme() → str[source]

Which animation screens paint in the active launch mode.

Validated on read: a value written by a newer spaCR (or by hand) that this build does not know about falls back to the default theme rather than propagating an unpaintable name into the widget.

spacr.qt.preferences.get_cache_ceiling_mb() → int[source]

How much cache spaCR may hold at once, in megabytes.

spacr.qt.preferences.get_cell_variant() → str[source]

Which of the user’s micrographs the Cell theme uses.

spacr.qt.preferences.get_color_blind_mode() → str[source]

Return the active colour-vision mode, falling back to off.

spacr.qt.preferences.get_dashboard_watermark(which: str) → str[source]

When Home’s which panel was last cleared, as a UTC ISO string.

A WATERMARK, NOT A DELETION, and that is the whole design. Clear on Recent runs and Reset on Totals sit beside the queue’s Clear, but the queue holds plates waiting to start while these two read the run journal – which is the record of what this installation has actually done, is what the Run History screen searches, and is what a run’s manifest.json is for. Emptying a dashboard panel must not delete that.

So the panels remember a time instead and show only what happened after it. The journal is untouched, Run History still has everything, and a user who clears by accident loses a view rather than a history.

Parameters:

which – runs or totals.

Returns:

the stored ISO string, or "" for never cleared.

spacr.qt.preferences.get_database_write_queue_gib() → float[source]

Return the serialized database queue RAM budget in GiB.

Zero uses disk-only buffering. This is not the total process RAM limit.

spacr.qt.preferences.get_db_browser_editable() → bool[source]

True when the user has allowed the Database Browser to write.

Default False: the browser opens every database with mode=ro. Turning this on only permits edit mode — the user still has to arm it per session, per database, in the browser itself.

spacr.qt.preferences.get_default_graph_type(shape: str) → str[source]

The graph type the user wants drawn first for shape.

Parameters:

shape – a spacr.graph_types data shape.

Returns:

the saved graph type, or "" when none is saved.

Empty rather than the table’s default, so graph_types.default_for can tell “the user chose this” from “nothing was chosen” – the table moves when the package does, and a stored copy of it is a preference that has stopped tracking.

spacr.qt.preferences.get_default_graph_types() → dict[source]

Every saved default graph type, as {shape: graph_type}.

Returns:

the saved mapping, empty when nothing has been chosen.

spacr.qt.preferences.get_dock_mode() → str[source]

How the left app dock behaves — one of VALID_DOCK_MODES.

A withdrawn mode is MIGRATED rather than rejected; see RETIRED_DOCK_MODES.

spacr.qt.preferences.get_dock_width() → int[source]

The width the user dragged the dock to, or 0 for its fitting width.

Stored in logical pixels; the dock clamps it to its drag bounds when it applies it, see spacr.qt.widgets.dock.Dock.column_width().

spacr.qt.preferences.get_field_fade_enabled() → bool[source]

Whether input fields dissolve towards their right edge.

True (the default) means every line edit, combo box and spin box paints its container and outline through spacr.qt.theme.field_fade_alpha() — solid where the value starts, gone at the right edge — and is exempt from pane_opacity. The text inside is never faded.

False restores the flat opaque input styling exactly: spacr.qt.widgets.field_fade.field_fade_qss() emits nothing, so the built-in rules in spacr.qt.theme.stylesheet() are the only thing that styles a field, and the paint hook returns immediately.

spacr.qt.preferences.get_figure_color_tokens() → tuple[source]

The STORED (background, text) tokens, unresolved.

Either half may be AUTO_FIGURE_COLOR. Anything that will write the preference back must seed itself from here rather than from get_figure_colors(), because a resolved pair has already lost the one bit that matters: whether the user chose it.

spacr.qt.preferences.get_figure_colors() → tuple[source]

Return (background, text) hex colours for rendered figures, resolving “auto” against the current theme.

For DRAWING. A caller that will later write the preference back wants get_figure_color_tokens(); see the section header for why.

spacr.qt.preferences.get_figure_dynamic() → bool[source]

Whether an evicted figure is reloaded from its vector page on demand.

With this on, navigating back past the live-cache window and selecting a figure loads its PDF if one exists, so an old figure is shown from the vector page rather than from the display-capped raster and stays sharp at any zoom. Off, it shows the raster it already has, which is faster and touches no disk.

It cannot make an old figure restylable again – a PDF is a finished page, with no legend to toggle. It makes it legible.

spacr.qt.preferences.get_figure_format() → str[source]

Return the saved figure format, falling back to pdf.

Read by spacr.qt.widgets.figure_queue.render_figure_to_png(), which is the single consumer. pdf makes it write a vector page beside the display raster; the queue then rasterises that page for a crisper view and the user has a file that opens as editable art. Scope is worth stating, since the name suggests otherwise: this is the format of the figures spaCR renders for its own Figures panel. Figures a pipeline writes into a results directory are saved by savefig calls in spacr.plot, spacr.submodules, spacr.ml and friends, each of which hard-codes its own format and never reads this preference.

spacr.qt.preferences.get_figure_grid_size() → int[source]

The tile width the user last chose, or the grid’s own default.

A READING preference, not a property of a run: someone who wants big figures wants them on the next run too.

spacr.qt.preferences.get_figure_line_colour() → str[source]

The colour a figure’s LINES are drawn in, “auto” resolved.

Automatic means the same ink as the text, which is what every figure did before there were two controls – so a store that has never been touched renders exactly as it did, and the split costs nobody a changed figure until they choose one.

WHAT THIS REACHES AND WHAT IT DOES NOT. It is the colour of the figure’s CHROME: the axis spines and the tick marks. It is deliberately not pushed over the data’s own lines on every render, because a preference that repainted every series in one ink would flatten every multi-series figure in the package the first time a theme was read. The control that DOES reach the data’s lines is the per-figure one (spacr.qt.widgets.figure_settings.apply_line_colour()), which is a user asking for it about one figure – the same division as the pyqtgraph side, where the theme sets _foreground and set_line_colour is a menu entry.

GRIDLINES ARE LEFT ALONE, and that is the one exclusion. A grid repainted in the ink is a cage over the data; spacr.figure_style.PRINT_GRID already states it for the save path and this agrees with it.

spacr.qt.preferences.get_figure_line_token() → str[source]

The STORED line colour token, unresolved.

Seed a control that will write the preference back from HERE, never from get_figure_line_colour() – the section header says why, and the line half is new enough that it has not yet been frozen by anybody.

spacr.qt.preferences.get_figure_live_cache() → int[source]

How many of the most recent figures keep their live matplotlib Figure.

The Figures panel used to hold a pixmap per figure and a Figure for every one of them, unbounded. The pixmap is what it displayed, so nothing could be restyled from a picture; the Figures were retained but never capped, so a long run accumulated all of them.

This bounds the live set. Figures past it keep their rendered page and stay viewable – see get_figure_dynamic() for what happens when the user navigates back to one.

Larger is more restylable and more memory; a figure with a big imshow panel can hold tens of megabytes.

spacr.qt.preferences.get_figure_png_dpi() → int[source]

Return the saved PNG resolution, or the 300-DPI default.

Two consumers, and they treat it differently on purpose. spacr.qt.widgets.figure_queue.render_figure_to_png() clamps it for the on-screen raster — a 16x12” figure at 300 DPI is a 4800 px PNG that costs more to decode than any screen can show — so a large figure is displayed at a lower DPI than the one chosen here. spacr.qt.widgets.figure_queue._export_vector_pdf() uses the value unclamped, because the PDF is a file rather than a screenful and its embedded rasters really do need the resolution the user asked for.

spacr.qt.preferences.get_figure_save_mode() → str[source]

Return the saved figure appearance mode, defaulting to print.

The environment override belongs to spacr.figure_style.figure_save_mode(), not here. Keeping this getter store-only lets the Preferences dialog show what it will persist even while a command-line or notebook process temporarily overrides it.

Returns:

{‘print’, ‘screen’, ‘transparent’} – Persisted mode, or print when the stored value is invalid.

spacr.qt.preferences.get_figure_style() → dict[source]

The user’s GENERAL figure settings, or an empty dict.

Empty rather than the defaults: spacr.figure_style.resolve() layers the defaults underneath, so storing them here as well would freeze today’s defaults into every user’s settings and make improving them impossible.

spacr.qt.preferences.get_figure_style_default(kind: str) → dict[source]

The saved default for one kind of style, or {}.

Empty rather than “today’s defaults”, for the reason the figure colour section states at length: a stored resolution is a preference that has stopped tracking. A style with no saved default is drawn from the dataclass’s own defaults, which move when the package does.

Parameters:

kind – the figure kind, e.g. "volcano", as spacr.style_base.style_kind() derives it; converted to str.

spacr.qt.preferences.get_figure_style_defaults() → dict[source]

Every saved per-project style default, as {kind: {field: value}}.

spacr.qt.preferences.get_figure_style_per_graph() → dict[source]

Per-graph overrides, {kind: {setting: value}}.

spacr.qt.preferences.get_figure_text_size() → int[source]

Return the saved figure font size; zero leaves Matplotlib unchanged.

spacr.qt.preferences.get_folded_panels() → dict[source]

Which panels the user left folded, {key: True}, or opened, {key: False}.

False is stored only for a panel that starts folded; see set_folded_panel().

Keyed by "<module>/<panel>" so folding the console on Mask does not fold it on Sequencing – the same rule the console/chat splitter already follows, and for the same reason: the modules are used for different work and want different amounts of room.

spacr.qt.preferences.get_font_scale() → float[source]

Return the saved UI font scale, clamped to supported bounds.

spacr.qt.preferences.get_fractal_settings() → dict[source]

Every spaceout fractal setting, ready for Settings/RuntimeControls.

Read through one function so the dialog and the backdrop cannot disagree about a default. Out-of-range stored values are clamped rather than refused – a backdrop must not stop the application from starting.

spacr.qt.preferences.get_gui_scale() → float[source]

Return the saved whole-GUI scale, clamped to supported bounds.

Applied at startup by spacr.qt.gui_scale.apply_saved_gui_scale() and live by spacr.qt.gui_scale.set_gui_scale_live().

spacr.qt.preferences.get_hash_inputs() → bool[source]

Whether a run hashes its inputs and outputs for the manifest.

spacr.qt.preferences.get_headroom_mb() → int[source]

How much memory must stay free for everything else on the machine.

THE FIRST OF THE THREE. The idle timeout and the ceiling say what may be kept; this says when keeping it stops being acceptable, and without it neither of the others has anything to answer to.

spacr.qt.preferences.get_idle_minutes() → float[source]

How long an unused cache entry may sit before it is dropped.

Returns:

minutes; 0 means “as soon as nothing is using it”.

spacr.qt.preferences.get_interface_font_weight() → str[source]

Which Open Sans weight the interface’s body text uses.

Returns:

'light' or 'regular', defaulting to DEFAULT_INTERFACE_FONT_WEIGHT.

spacr.qt.preferences.get_issue_prompt_mode() → str[source]

How to behave when a report could be filed.

Returns:

one of ISSUE_PROMPT_MODES. DEFAULT_ISSUE_PROMPT_MODE ('always') when nothing is stored, and also when the only thing stored is the superseded default 'ask' written by a build that did not mark what the user had chosen (_KEY_ISSUE_PROMPT_CHOSEN). A choice this build or a later one wrote is returned as it stands, ‘ask’ included. A stored value that is not recognised reads as 'ask': it was somebody’s choice, even if this build cannot read it, so it must neither silence the reporter nor start publishing without a preview.

spacr.qt.preferences.get_language() → str[source]

Return the persisted UI language code, falling back to English.

spacr.qt.preferences.get_laptop_mode() → str[source]

Whether laptop constraints apply.

Returns:

"on" at the Laptop level, otherwise "off".

DERIVED, NOT STORED. This was a second control that quietly overrode the mode selector, so a user could choose one posture on one row and have another row undo it – two answers to one question. Laptop is now the most constrained LEVEL of the single selector, and this answers from it so callers that still ask in these words agree with it.

There is no "automatic" any more: it meant “measure the machine and decide”, which is a guess presented as a setting. The five levels say which hardware each is for and let the user pick.

spacr.qt.preferences.get_log_console_levels() → frozenset[source]

Levels echoed to the in-app console, always a subset of the files.

Clamped on read as well as on write: the stored value can predate a change to the file switches made by a different code path, and a console line with no matching entry in the log file is exactly what the subset rule exists to prevent.

spacr.qt.preferences.get_log_file_levels() → frozenset[source]

Levels written to the log files. The master switch of the pair.

Returns:

the levels the file handler admits.

VERBOSE LOGGING ADDS DEBUG, because otherwise the two settings contradict each other and the one the user did not touch wins. With verbose on, spaCR’s loggers emit DEBUG records. Omitting DEBUG from the file handler would build every one of those records and then discard it.

Whatever verbose means, it cannot mean “do the work and write none of it”. It is not stored into the level preference: the user’s own choice of levels is left exactly as they set it, and DEBUG goes away again when they turn verbose off.

spacr.qt.preferences.get_montage_columns() → int[source]

Cells per row in a well’s montage tab.

spacr.qt.preferences.get_news_height() → int[source]

The remembered height of Home’s release-notes list, or 0.

Stored in FONT-SCALE-INDEPENDENT px, so a reader who drags the box tall and then raises the interface zoom gets a box that is still the same size relative to the text in it, rather than one that keeps the pixel count and loses two of its four visible lines.

spacr.qt.preferences.get_pane_opacity() → float[source]

The user’s requested page-panel opacity, 0.0-1.0.

Un-clamped: the floor belongs to the theme, which is the only thing that knows what is behind the panel. Callers want spacr.qt.theme.pane_alpha(), which applies it.

spacr.qt.preferences.get_performance_level() → str[source]

The single performance level, one of PERFORMANCE_LEVELS.

Returns:

the stored level, migrating an older pair of settings on first read.

MIGRATION HAPPENS HERE rather than in a startup step, because every reader of the old settings comes through this function and a migration that only ran at launch would be skipped by a headless run, a test, or a second process. It is idempotent: once a level is stored the old values are never consulted again.

An explicit Laptop mode of on becomes Laptop – that user asked for the most constrained profile and still gets it. With Laptop off or automatic the previous mode is kept as-is, so balanced stays Balanced, and nobody’s choice is silently changed.

spacr.qt.preferences.get_performance_logging() → str[source]

Return the independent process-tree resource logging level.

summary is the default: it records whole-run totals and peaks at roughly one sample per second. detailed additionally retains the bounded process/thread series. This setting never enables verbose logging or installs a profile hook.

Returns:

one of PERFORMANCE_LOGGING_LEVELS.

spacr.qt.preferences.get_popup_backdrop() → str[source]

Which ambient theme drifts behind a settings popup, or 'off'.

spacr.qt.preferences.get_preferred_provider() → str[source]

Return the preferred AI provider name.

An empty string allows the console to select an available provider.

spacr.qt.preferences.get_preload_policy() → str[source]

When to import torch and the rest. ‘on_demand’ or ‘eager’.

spacr.qt.preferences.get_refresh_news() → bool[source]

Whether Home’s News panel may ask GitHub for newer releases.

Read by spacr.qt.app.MainWindow._refresh_news(), which is the one place that starts the fetch. The bundled spacr/resources/release_notes.json is drawn either way.

spacr.qt.preferences.get_rim_alignment() → str[source]

Where the lit run sits relative to the pointer.

centre puts the MIDDLE of the run under the pointer, head puts its leading end there and trails the rest behind.

spacr.qt.preferences.get_rim_lag() → float[source]

How far the accent closes the gap to the pointer each frame.

SMALLER IS SLOWER, and the name is the user’s: what they see is the lag between the pointer arriving and the light catching up. 1.0 would put the light under the pointer with no travel at all, and the travel is the whole effect – so that is the top of the range, not past it.

spacr.qt.preferences.get_rim_length() → int[source]

Pixels of rim the accent lights up.

Clamped on READ as well as on write: the stored value can come from a settings file written by hand or by an older build, and a rim longer than its own perimeter is a border rather than a highlight.

spacr.qt.preferences.get_rim_mode() → str[source]

Which way the rim is coloured – glow, rainbow or beat.

spacr.qt.preferences.get_rim_period() → float[source]

Seconds for one pulse of beat or one hue turn of rainbow.

spacr.qt.preferences.get_runtime_text_scale() → float[source]

The right-hand column’s text size, clamped to its bounds.

One value for every module screen, so the console reads the same size wherever the user goes; see spacr.qt.live_zoom.

spacr.qt.preferences.get_save_workspace() → str[source]

Return how a completed run records its open workspace.

The result is "off", "reference", or "copy"; see spacr.workspace. This application preference applies to every run until changed.

spacr.qt.preferences.get_saved_sound_enabled() → bool[source]

The stored master sound switch, whatever the mode.

Ordinary spaCR ignores it (see get_sound_enabled()) but never erases it, so a user who switched sound on in spaceout finds it on the next time spaceout starts.

Returns:

the stored switch, default False.

spacr.qt.preferences.get_section_layout(panel: str) → dict[source]

What panel looked like when it was last used.

Divider sizes and collapsed sections are remembered per category so the next session restores the user’s working layout.

Parameters:

panel – the stable category or panel key the layout was saved under with set_section_layout(); converted to str.

Returns:

{"folded": [title, ...], "sizes": [int, ...]}, plus "steps" and "boxes" for a panel whose nested sections fold or whose boxes are draggable – see set_section_layout(). An empty dict when the panel has never been arranged. EMPTY, not a default layout – the panel’s own first-run arrangement is the right one, and freezing today’s into every user’s settings would make improving it impossible. Same reasoning as get_figure_style().

spacr.qt.preferences.get_setting_animations_enabled() → bool[source]

Whether setting tooltips show their animation WITHOUT being asked.

Default False: a hover is text only, no GIF is decoded, no frames are cached and no timer runs, and the teal Animation word in the footer is the invitation to see one — for that setting, once. Turning this on starts every tooltip revealed instead, and the word then folds the one in front of the reader away. The meaning is “stop asking me”, not “allow animations”.

The two cannot disagree and neither needs to defer to the other, because they are scoped differently: a press names exactly one setting, so it can never stop this preference reaching the rest. See spacr.qt.widgets.hover_tooltip.HoverTooltip.animations_shown().

Read on every tooltip, not once at startup: spacr.qt.widgets.hover_tooltip.HoverTooltip is a process-wide singleton that outlives the Preferences dialog, so caching this would keep animating until the app was restarted.

spacr.qt.preferences.get_share_diagnostic_logs() → bool[source]

Whether an error report saves a redacted copy of the recent log.

The copy is written to a file on this computer and the report names that file. The log is never posted to GitHub. Whether a report is sent at all is get_issue_prompt_mode().

spacr.qt.preferences.get_show_alpha() → bool[source]

Whether Alpha modules and settings are visible (default: True).

spacr.qt.preferences.get_show_beta() → bool[source]

Whether Beta modules and settings are visible (default: True).

spacr.qt.preferences.get_sound_enabled() → bool[source]

Whether spaCR plays any sound at all. Default False.

Always False outside spaceout mode (sound_is_offered()), whatever is stored: ordinary spaCR has no Sound tab, so a switch the user cannot see must not be able to make a noise.

Returns:

the stored master switch in spaceout mode, else False.

spacr.qt.preferences.get_sound_event_enabled(event: str) → bool[source]

Whether one event’s sound is switched on, apart from the master.

Parameters:

event – a key of SOUND_EVENT_DEFAULTS.

Returns:

the stored switch.

Raises:

KeyError – for an event spaCR has no sound for.

spacr.qt.preferences.get_sound_music_file() → str[source]

A WAV of the user’s own to play as the music bed, or "".

Empty – the default – means spaCR’s own synthesized bed. The file is NOT checked here: this is called on the GUI thread on every settings read, and spacr.qt.sound looks for the file on its audio thread, where a network home directory costs nobody a frame.

Returns:

the stored path, or "".

spacr.qt.preferences.get_sound_theme() → str[source]

Which sound set plays, validated against the sets that exist.

Returns:

a key of spacr.qt.sound_synth.SOUND_THEMES; a stored key that no longer exists reads as the default set.

spacr.qt.preferences.get_sound_volume() → float[source]

The master volume, 0 to 1, clamped on read.

Returns:

the stored fraction, or DEFAULT_SOUND_VOLUME when the store holds something that is not a number.

spacr.qt.preferences.get_spacr_mode() → str[source]

Which resource posture spaCR is in — one of SPACR_MODES.

DERIVED FROM THE PERFORMANCE LEVEL, which is the one stored setting. Kept because the cleanup code speaks in these three words.

spacr.qt.preferences.get_spinner_delay() → float[source]

How long background work must run before the activity spinner shows.

In seconds, default DEFAULT_SPINNER_DELAY. This is a delay before showing, not a prediction: the widget starts a single-shot timer when work begins and only becomes visible if the work is still running when it fires, so a job that finishes at 1.9 s never puts a spinner on screen at all. See spacr.qt.widgets.activity_spinner .ActivitySpinner.

Clamped on read: a hand-edited file must not be able to hide the indicator for the length of a real job.

spacr.qt.preferences.get_theme() → str[source]

Return the saved application theme, or the default when invalid.

A stored "system" counts only when it was chosen (see _follow_system_was_chosen()); otherwise it reads as DEFAULT_THEME, which is dark. An explicit Light, or any other stored theme, is returned as it is.

The first read of a store also removes the retired Space theme’s space_variant and space_seed values from it; see _forget_the_space_theme_keys().

spacr.qt.preferences.get_theme_choice() → str[source]

Return the composite token representing the current visual theme.

spacr.qt.preferences.get_tooltips_bottom_enabled() → bool[source]

Whether a hovered setting’s help also appears in the bottom strip.

The strip already shows CATEGORY help on hover; this puts SETTING help there too, and holds it for ten seconds after the pointer leaves so its API link can be reached. Without that hold the link is unreachable: it appears only while the pointer is on the setting, and moving toward it removes it.

spacr.qt.preferences.get_tooltips_box_enabled() → bool[source]

Whether hovering a setting’s title opens the tooltip box.

The box is spacr.qt.widgets.hover_tooltip.HoverTooltip: a QFrame the pointer can move INTO, which is what lets its API and Animation links be clicked at all. Cleared, no box opens and the bottom strip – if it is on – is the only place a setting explains itself.

spacr.qt.preferences.get_tooltips_enabled() → bool[source]

Whether ordinary tooltips appear anywhere in spaCR. Default True.

The master switch read by spacr.qt.tooltip_policy, the one event filter on QApplication that decides when every tooltip appears and goes. Cleared, no tooltip is shown at all; the two settings surfaces – get_tooltips_box_enabled() and get_tooltips_bottom_enabled() – are separate and unaffected.

spacr.qt.preferences.get_verbose_logging() → bool[source]

Return True when the user has opted into the verbose diagnostic logger. Toggled via the Preferences dialog; consulted at startup by apply_preferences_to_app().

The wording of that first paragraph is deliberate: a reviewed Korean translation of it is held in docs/i18n/reviewed/api, and the localisation audit refuses a source block that no longer matches what was reviewed. Changing it discards a human translation, so it is left exactly as it was and anything new goes below.

Defaults to DEFAULT_VERBOSE_LOGGING, which is on. Opening every module took the same time with it on as with it off, measured.

spacr.qt.preferences.get_workspace_copy_limit_mb() → float[source]

The per-file ceiling on what copy mode brings in, in megabytes.

spacr.qt.preferences.image_display_primaries() → str[source]

How images should be drawn for this user, everywhere.

The global half of the colour-blind mode. A user who needs the substitution needs it in Annotate, in every live view and in every crop grid, in every session – not as a toggle they re-find on each screen. A view may still override it, because a figure being prepared for publication wants cmy whatever the author’s vision, but this is what every view starts from.

Returns:

one of spacr.crops.DISPLAY_PRIMARIES.

spacr.qt.preferences.in_safe_mode() → bool[source]

Whether this process is running in safe mode.

Returns:

True after enable_safe_mode().

spacr.qt.preferences.laptop_mode_note(choice: str) → str[source]

What the chosen setting will do on THIS machine, said before saving.

Automatic is the case that needs saying: the label cannot state the outcome, because the outcome depends on the machine reading it.

Parameters:

choice – one of LAPTOP_MODE_CHOICES: "automatic" reports what this machine’s measurement decides, "on" lists what is turned down, and anything else is described as off.

spacr.qt.preferences.live_figure_allowance(level: str = '') → int[source]

How many figures stay editable at this level.

Parameters:

level – a performance level; the current one when omitted.

Returns:

a count of at least one.

A live Figure is what makes a figure restylable – it still has a legend to toggle and series to recolour – and each holds its own data arrays, so this is the clearest thing the level scales. At least one, always: a level that kept none would make the right-click menu useless rather than cheap.

spacr.qt.preferences.maturity_is_visible(stage: str) → bool[source]

Return whether a maturity stage should be present in the UI.

Unknown stages are treated as stable. Stable features cannot be hidden; the two preferences are deliberately scoped to unfinished features.

Parameters:

stage – the maturity stage, e.g. "alpha" or "beta"; matched case-insensitively, and an empty value or any other stage counts as stable.

spacr.qt.preferences.mode_label(mode: str) → str[source]

The name the dropdown shows for mode — e.g. "Extra Performance".

Parameters:

mode – One of SPACR_MODES.

Returns:

The human-readable label from MODE_LABELS, falling back to mode itself when the name is not one this module knows, so a stored value from a newer build still renders as text rather than as a blank row.

spacr.qt.preferences.mode_note(mode: str) → str[source]

What mode does, as the standing description under the dropdown.

The note says what is freed, when it is freed, and whether the visual settings are touched. It is not the warning — mode_warning() carries what switching to the mode costs you, and is shown on selection.

Parameters:

mode – One of SPACR_MODES.

Returns:

The prose from MODE_NOTES, or "" for a mode this module does not know, so the caller can render it unconditionally.

spacr.qt.preferences.mode_warning(mode: str) → str[source]

What choosing mode will cost, or "" when it costs nothing.

Parameters:

mode – one of SPACR_MODES; a mode with no entry in MODE_WARNINGS gives "".

spacr.qt.preferences.resolve_effective_theme() → str[source]

Return the theme to render — one of PALETTE_THEMES.

Resolves an explicitly chosen "system" to the operating system’s colour scheme as Qt reports it (QStyleHints.colorScheme), and to dark when Qt can’t tell. It does not read the application palette: that is spaCR’s own once a theme has been applied, so it would answer with whatever was applied last. Every other value passes through, so callers that only understand light/dark should compare against "light" and treat everything else as dark (Space and Cell are dark themes).

spacr.qt.preferences.retention_scale(level: str = '') → float[source]

How much reusable state this level allows, relative to Balanced.

Parameters:

level – a performance level; the current one when omitted.

Returns:

a positive multiplier.

spacr.qt.preferences.run_resource_action(action: str, parent=None)[source]

Confirm action, run it, and report the measured result.

Parameters:
  • action – which clean-up to run: "ram", "vram", "cpu" or "disk".

  • parent – the widget the confirmation and result dialogs are parented to, or None.

Returns:

the Reclaim for “ram”, “vram” and “cpu”, or None when the user declined — in which case nothing ran. The confirmation is asked before any work is started, not after, which is the whole point of asking.

None for “disk” as well, and that one is not a refusal: the disk readout stats folders the user chose, so it goes to a worker thread (_start_disk_report()) and its result arrives in the same message box a moment later rather than in this return value. The other three free memory and threads and touch no path, so they stay inline where their before/after measurements are taken.

spacr.qt.preferences.scale_group_values(scale: float) → dict[source]

What one Scale means for every setting that follows it.

Parameters:

scale – the single user-facing number.

Returns:

{setting: value} for the whole group.

spacr.qt.preferences.scaled_px(base_px: int) → int[source]

Return base_px scaled by the current user font scale.

Widget sizes set from Python (setMinimumWidth etc.) don’t grow when the stylesheet’s font size grows, so any control tuned to match a text width goes wrong at large font scales. Route those calls through this helper so they track the preference.

Rounds to the nearest int; caps to at least 1 px so a very small scale doesn’t collapse things to zero.

Parameters:

base_px – a size in pixels as designed for a font scale of 1.0.

spacr.qt.preferences.set_ai_on_by_default(enabled: bool) → None[source]

Persist whether the assistant starts enabled.

Parameters:

enabled – True to have it on at launch.

spacr.qt.preferences.set_ambient_animation(name: str) → None[source]

Persist an entry of ANIMATION_CHOICES, "none" included.

Choosing an animation turns the backdrop on, and choosing None turns it off, so the dropdown is the whole control: a user who picks Blobs after something switched the backdrop off gets Blobs, not silence.

Picking None does not disturb the stored theme’s palette, so switching back later restores exactly the animation that was there.

Parameters:

name – an entry of ANIMATION_CHOICES from spacr.qt.widgets.ambient; its NO_ANIMATION entry ("none") switches the backdrop off, and any other value raises ValueError.

spacr.qt.preferences.set_ambient_blur(value: float) → None[source]

Store the legacy animation-blur preference. Current widgets ignore it.

Parameters:

value – the retained legacy blur value; clamped to BLUR_RANGE from spacr.qt.widgets.ambient. An unparseable value or NaN stores DEFAULT_BLUR.

spacr.qt.preferences.set_ambient_density(value: float) → None[source]

Set the element-count multiplier. Clamped.

Parameters:

value – the multiplier on each animation’s own element count (1.0 is as designed); clamped to DENSITY_RANGE from spacr.qt.widgets.ambient, and an unparseable value or NaN stores DEFAULT_DENSITY.

spacr.qt.preferences.set_ambient_drift_direction(name: str) → None[source]

Persist one of spacr.qt.widgets.ambient.DRIFT_DIRECTIONS.

Parameters:

name – the starfield drift direction, one of DRIFT_DIRECTIONS ("up", "down" or "random" when the widget module cannot be imported).

Raises:

ValueError – if name is not one of them.

spacr.qt.preferences.set_ambient_enabled(on: bool) → None[source]

Turn the animated background on or off.

Flushed immediately: module screens re-read this key when they are built, and a stale read right after the user cleared the checkbox would put the animation back on the very next screen they open.

Parameters:

on – true to turn it on, false to turn it off; stored as a bool.

spacr.qt.preferences.set_ambient_palette(name: str) → None[source]

Persist a palette offered by the current ambient theme.

Parameters:

name – a palette name offered by the current ambient theme.

Raises:

ValueError – if name is not one of palettes_for(get_ambient_theme()). Set the theme first: a palette is only meaningful next to the theme that draws it.

spacr.qt.preferences.set_ambient_resolution(value: float) → None[source]

Set the detail multiplier. Clamped.

Parameters:

value – the multiplier on each animation’s own shading buffer (1.0 is as designed); clamped to RESOLUTION_RANGE from spacr.qt.widgets.ambient, and an unparseable value or NaN stores DEFAULT_RESOLUTION.

spacr.qt.preferences.set_ambient_size(value: float) → None[source]

Set the element-size multiplier. Clamped.

Parameters:

value – the multiplier on each animation’s own element size (1.0 is as designed); clamped to SIZE_RANGE from spacr.qt.widgets.ambient, and an unparseable value or NaN stores DEFAULT_SIZE.

spacr.qt.preferences.set_ambient_speed(value: float) → None[source]

Set the motion multiplier. Clamped.

Parameters:

value – the multiplier on each theme’s own motion (1.0 is as designed); clamped to SPEED_RANGE from spacr.qt.widgets.ambient, and an unparseable value or NaN stores DEFAULT_SPEED.

spacr.qt.preferences.set_ambient_theme(name: str) → None[source]

Persist an animation offered in the active launch mode.

Palettes belong to a theme, so switching themes can strand the stored palette. Rather than raise — the user picked a theme, not a broken pair — the stored palette is repaired in the same write: it is kept if the new theme also offers it, and otherwise replaced with that theme’s default (see ambient_default_palette()).

Parameters:

name – an animation offered in the current launcher’s menu.

Raises:

ValueError – if name is not a known ambient theme.

spacr.qt.preferences.set_cache_ceiling_mb(megabytes: int) → None[source]

Persist the cache ceiling.

Parameters:

megabytes – the most cache spaCR may hold at once, in megabytes; stored as an int.

spacr.qt.preferences.set_cell_variant(variant: str) → None[source]

Persist one of the bundled Cell-theme microscopy variants.

Parameters:

variant – one of spacr.qt.imagery.CELL_VARIANTS; any other value raises ValueError.

spacr.qt.preferences.set_color_blind_mode(mode: str) → None[source]

Persist a supported colour-vision mode.

Parameters:

mode – one of VALID_CB_MODES; any other value raises ValueError.

spacr.qt.preferences.set_dashboard_watermark(which: str, when: str = '') → str[source]

Move which’s watermark to when, or to now when empty.

Parameters:
  • which – runs or totals. An unknown name is ignored.

  • when – a UTC ISO-8601 string. Empty means “now”.

Returns:

what was stored, or "" when nothing was.

spacr.qt.preferences.set_database_write_queue_gib(gib: float) → None[source]

Persist the database queue payload budget for subsequent runs.

Parameters:

gib – serialized queued-data RAM allowance in GiB, from zero to 64. Zero stores queued payloads on disk.

Raises:

ValueError – if the value is nonfinite or outside the valid range.

spacr.qt.preferences.set_db_browser_editable(on: bool) → None[source]

Allow (or forbid) edit mode in the Database Browser.

Flushed immediately. QSettings writes back lazily, and the Database Browser re-reads this key on every UI refresh — a stale read right after the user ticked the box would tell them editing is still off. One tiny INI write is worth not having to explain that.

Parameters:

on – true to allow edit mode, false to forbid it; stored as a bool.

spacr.qt.preferences.set_default_graph_type(shape: str, graph_type: str) → None[source]

Persist which graph is drawn first for shape.

Parameters:
  • shape – a spacr.graph_types data shape.

  • graph_type – a graph type, or "" to go back to the default.

spacr.qt.preferences.set_dock_mode(mode: str) → None[source]

Persist a valid left-navigation dock mode.

A withdrawn mode is accepted and stored as its replacement, so code that still names one is migrated rather than made to raise.

Parameters:

mode – one of VALID_DOCK_MODES, or a retired mode from RETIRED_DOCK_MODES, which is stored as its replacement; anything else raises ValueError.

spacr.qt.preferences.set_dock_width(width: int) → None[source]

Persist the dock’s dragged width; 0 goes back to the fitting width.

Parameters:

width – logical pixels.

spacr.qt.preferences.set_field_fade_enabled(on: bool) → None[source]

Turn the field fade on or off.

Flushed immediately and the paint hook’s cache dropped, so the very next repaint honours it. Re-applying the stylesheet (apply_preferences_to_app()) is what makes it land on fields that are already on screen.

Parameters:

on – true to turn it on, false to turn it off; stored as a bool.

spacr.qt.preferences.set_figure_colors(bg: str, fg: str) → None[source]

Persist background and text colour TOKENS for generated figures.

Pass AUTO_FIGURE_COLOR for a half the user has not chosen — NEVER what auto_figure_colors() returned for it. See the section header.

Writing also marks the store as migrated: a value set here is a decision taken under the current scheme, so _migrate_frozen_figure_colors() must not second-guess it afterwards.

Parameters:
  • bg – the background colour token, or AUTO_FIGURE_COLOR.

  • fg – the text colour token, or AUTO_FIGURE_COLOR.

spacr.qt.preferences.set_figure_colors_auto() → None[source]

Put both halves back to “follow the theme”.

The explicit way out. A user who has been frozen — by the old dialog or by their own click — otherwise has no route back to automatic at all, and a preference you can only ever set is a trap.

spacr.qt.preferences.set_figure_dynamic(enabled: bool) → None[source]

Persist whether evicted figures reload from their vector page.

Parameters:

enabled – true to reload an evicted figure from its vector page, false to keep showing its raster; stored as a bool.

spacr.qt.preferences.set_figure_format(fmt: str) → None[source]

Persist a supported figure format.

Parameters:

fmt – the figure file format, one of VALID_FIG_FORMATS.

Raises:

ValueError – if fmt is not png or pdf.

spacr.qt.preferences.set_figure_grid_size(pixels: int) → None[source]

Remember the tile width, clamped to what the grid will accept.

Parameters:

pixels – the tile width in pixels; converted to int and clamped between MIN_CELL_PX and MAX_CELL_PX of spacr.qt.widgets.figure_grid_view.

spacr.qt.preferences.set_figure_line_colour(token: str) → None[source]

Persist the line colour TOKEN. Pass AUTO_FIGURE_COLOR for “follow the text”, never what it resolved to.

Parameters:

token – the line colour token, or AUTO_FIGURE_COLOR to follow the text colour.

spacr.qt.preferences.set_figure_live_cache(count: int) → None[source]

Persist how many figures keep their live Figure.

Parameters:

count – how many of the most recent figures keep their live Figure; converted to int.

Raises:

ValueError – outside MIN_FIG_LIVE_CACHE..MAX_FIG_LIVE_CACHE.

spacr.qt.preferences.set_figure_png_dpi(dpi: int) → None[source]

Persist one of VALID_PNG_DPIS.

Parameters:

dpi – the PNG resolution in dots per inch; converted to int and checked against VALID_PNG_DPIS.

Raises:

ValueError – if dpi is not a supported resolution.

spacr.qt.preferences.set_figure_save_mode(mode: str) → None[source]

Persist the saved-figure appearance mode.

Parameters:

mode ({'print', 'screen', 'transparent'}) – print writes a light page with dark figure elements, screen preserves the displayed appearance, and transparent removes the page background.

Raises:

ValueError – If mode is not a supported figure save mode.

spacr.qt.preferences.set_figure_style(style: dict) → None[source]

Store the general figure settings.

Parameters:

style – the general figure settings, {setting: value}; stored as JSON, and None stores an empty dict.

spacr.qt.preferences.set_figure_style_default(kind: str, values) → None[source]

Make values the default for every future figure of kind.

The design: “a per-project default so a lab’s house style is applied to every figure of that type without re-setting it each time”.

Parameters:
  • kind – the figure kind, e.g. "volcano", as spacr.style_base.style_kind() derives it; converted to str.

  • values – the {field: value} style to save for that kind, replacing any previous default; None saves an empty dict.

spacr.qt.preferences.set_figure_style_per_graph(overrides: dict) → None[source]

Store the per-graph overrides.

Parameters:

overrides – per-graph overrides, {kind: {setting: value}}; entries whose value is not a non-empty dict are dropped before storing.

spacr.qt.preferences.set_figure_text_size(size: int) → None[source]

Persist a figure font size; zero delegates sizing to Matplotlib.

Parameters:

size – the figure font size; converted to int, and 0 leaves sizing to Matplotlib.

spacr.qt.preferences.set_folded_panel(key: str, shut: bool, *, default_shut: bool = False) → None[source]

Remember that key is folded, or is not.

A PANEL IN ITS DEFAULT STATE IS REMOVED rather than stored. Most panels default to open, so storing that would grow the dict by one entry for every panel the user has ever touched and never shrink it. A panel that starts folded (the advanced PSF, restoration and CLAHE rows) passes default_shut=True, so opening it is what gets stored, as False, and folding it again forgets it.

Parameters:
  • key – the panel key, "<module>/<panel>"; stripped, and an empty key does nothing.

  • shut – true to record the panel as folded, false as open.

  • default_shut – the panel’s state when nothing is stored.

spacr.qt.preferences.set_font_scale(scale: float) → None[source]

Persist a UI font scale after clamping it to supported bounds.

Parameters:

scale – the UI font scale, 1.0 for the designed size; converted to float and clamped between FONT_SCALE_MIN and FONT_SCALE_MAX.

spacr.qt.preferences.set_fractal_settings(**values) → None[source]

Persist any subset of the fractal settings.

Raises:

ValueError – on an unknown name, or a backend/quality outside its set. A number is stored as given; only one that cannot work at all is moved, and explain_a_fractal_number says so in words before it reaches here. What follows describes the old behaviour, kept because the reasoning about a slider still applies to the two sliders left produce one and a hand-edited file should still start.

spacr.qt.preferences.set_gui_scale(scale: float) → None[source]

Persist a whole-GUI scale after clamping it to supported bounds.

Parameters:

scale – the factor, 1.0 = 100 %. Only stored; drawing it is spacr.qt.gui_scale.set_gui_scale_live()’s job.

spacr.qt.preferences.set_hash_inputs(on: bool) → None[source]

Persist the input-hashing choice.

Parameters:

on – true to hash a run’s inputs and outputs for the manifest, false not to; stored as a bool.

spacr.qt.preferences.set_headroom_mb(megabytes: int) → None[source]

Persist the headroom floor.

Parameters:

megabytes – the memory that must stay free for everything else on the machine, in megabytes; stored as an int.

spacr.qt.preferences.set_idle_minutes(minutes: float) → None[source]

Persist the idle timeout.

Parameters:

minutes – how long an unused cache entry may sit before it is dropped, in minutes; 0 drops it as soon as nothing uses it. Stored as a float.

spacr.qt.preferences.set_interface_font_weight(weight: str) → None[source]

Persist the weight and apply it to the running application.

Parameters:

weight – one of INTERFACE_FONT_WEIGHTS, matched after stripping and lower-casing.

Raises:

ValueError – on anything but ‘regular’ or ‘light’.

spacr.qt.preferences.set_issue_prompt_mode(mode: str) → None[source]

Persist the auto-issue behaviour, and that it was chosen.

The marker is what makes a later ‘ask’ stick: from here on, ‘ask’ in the store is an answer somebody gave, not the default of the day written into every profile that opened first-run setup. Every writer goes through this function — the setup slides, the Preferences dialog, the AI Console and the installer’s consent page — so all four count as choosing.

Parameters:

mode – one of ISSUE_PROMPT_MODES.

Raises:

ValueError – for anything else. Silently storing an unknown mode would read back as ‘ask’ and look like the setting was ignored.

spacr.qt.preferences.set_language(language: str) → None[source]

Persist one of the bundled UI languages.

Parameters:

language – a UI language code from spacr.qt.i18n.VALID_LANGUAGE_CODES; stripped, with - read as _.

Raises:

ValueError – if language is not a supported language code.

spacr.qt.preferences.set_laptop_mode(choice: str) → None[source]

Persist the laptop-mode preference and apply it now.

Parameters:

choice – one of LAPTOP_MODE_CHOICES: "on" selects the Laptop performance level, "off" moves a Laptop level back to the default level, and "automatic" changes nothing.

Raises:

ValueError – on an unknown choice.

Applied immediately rather than at the next launch, because the two animation it changes is visible in the window behind the dialog. A performance setting that needs a restart to show its effect cannot be judged by the person setting it.

spacr.qt.preferences.set_log_levels(file_levels, console_levels) → tuple[source]

Persist both switch sets, then apply them to the live handlers.

Parameters:
  • file_levels – the logging level numbers the log files record; anything other than DEBUG, INFO, WARNING, ERROR and CRITICAL is discarded.

  • console_levels – the logging level numbers shown on the console; a level the log files do not keep is dropped.

Returns:

(file_levels, console_levels) as actually stored, which is not necessarily what was asked for – a console level whose file level is off is dropped rather than saved and silently ignored.

file_levels is the user’s own choice, and it is stored as given. While verbose logging is on, the log files keep DEBUG as well, so a console DEBUG switch is kept and the live handlers are given DEBUG. The DEBUG that verbose adds is not written into the stored file levels.

spacr.qt.preferences.set_montage_columns(columns) → int[source]

Store the cells-per-row count. Returns the value actually stored.

Parameters:

columns – cells per row; converted to int and clamped to MONTAGE_COLUMNS_RANGE, and an unparseable value stores DEFAULT_MONTAGE_COLUMNS.

spacr.qt.preferences.set_news_height(px: int) → int[source]

Remember how tall Home’s release-notes list was dragged.

Parameters:

px – the list height in font-scale-independent pixels; negative values store 0, and an unparseable value stores nothing and returns 0.

spacr.qt.preferences.set_pane_opacity(fraction: float) → None[source]

Store the requested opacity. Accepts 0.0-1.0; clamped, then rounded.

Parameters:

fraction – the opacity from 0.0 to 1.0, stored as a whole percentage; an unparseable value stores DEFAULT_PANE_OPACITY_PCT.

spacr.qt.preferences.set_performance_level(level: str) → None[source]

Persist the performance level.

Parameters:

level – one of PERFORMANCE_LEVELS.

Raises:

ValueError – on an unknown level.

spacr.qt.preferences.set_performance_logging(level: str) → None[source]

Persist the process-tree resource logging level.

Parameters:

level – off, summary or detailed.

Raises:

ValueError – when level names no supported mode.

spacr.qt.preferences.set_popup_backdrop(name: str) → str[source]

Store the popup backdrop. An unknown name stores the default.

Parameters:

name – one of POPUP_BACKDROPS, matched after stripping and lower-casing.

spacr.qt.preferences.set_preferred_provider(name: str) → None[source]

Store the preferred AI provider name.

Parameters:

name (str) – Provider name. An empty string clears the preference.

spacr.qt.preferences.set_preload_policy(policy: str) → None[source]

Persist it. Takes effect at the next launch, and says so.

Parameters:

policy – one of PRELOAD_POLICIES, matched after stripping and lower-casing.

Raises:

ValueError – on anything but the two policies.

spacr.qt.preferences.set_refresh_news(on: bool) → None[source]

Persist the News panel’s release-refresh opt-out.

Parameters:

on – true to let the News panel ask GitHub for newer releases, false to opt out; stored as a bool.

spacr.qt.preferences.set_rim_alignment(name: str) → str[source]

Store the alignment. An unknown name stores the default instead.

Parameters:

name – one of RIM_ALIGNMENTS, matched after stripping and lower-casing.

spacr.qt.preferences.set_rim_lag(fraction) → float[source]

Store the chase fraction. Returns the value actually stored.

Parameters:

fraction – how far the accent closes the gap to the pointer each frame; clamped to RIM_LAG_RANGE, and an unparseable value stores DEFAULT_RIM_LAG.

spacr.qt.preferences.set_rim_length(pixels) → int[source]

Store the rim length. Returns the value actually stored.

Parameters:

pixels – how far the lit run reaches along the rim, in pixels; clamped to RIM_LENGTH_RANGE, and an unparseable value stores DEFAULT_RIM_LENGTH.

spacr.qt.preferences.set_rim_mode(name: str) → str[source]

Store the rim mode. An unknown name stores the default instead.

Parameters:

name – one of RIM_MODES, matched after stripping and lower-casing.

spacr.qt.preferences.set_rim_period(seconds) → float[source]

Store the pulse period. Returns the value actually stored.

Parameters:

seconds – seconds for one pulse of beat or one hue turn of rainbow; clamped to RIM_PERIOD_RANGE, and an unparseable value stores DEFAULT_RIM_PERIOD.

spacr.qt.preferences.set_runtime_text_scale(scale: float) → float[source]

Persist the right-hand column’s text size, clamped to its bounds.

Parameters:

scale – 1.0 for the size the rest of the interface has.

Returns:

the value stored.

spacr.qt.preferences.set_save_workspace(mode) → str[source]

Store the workspace mode and update the process-wide default.

Updating both values makes the change available immediately to pipeline code that cannot read Qt settings directly.

Parameters:

mode – "off", "reference" or "copy", or anything spacr.workspace.resolve_mode() accepts (booleans and yes/no aliases); unrecognised values select the default mode.

spacr.qt.preferences.set_section_layout(panel: str, folded=(), sizes=(), steps=None, boxes=None) → None[source]

Remember which sections of panel are folded, and the divider sizes.

Parameters:
  • panel – stable category or panel name under which this layout is stored, independently of every other panel’s arrangement.

  • folded – the titles that are folded away.

  • sizes – the splitter’s sizes, in its own order.

  • steps – the SUB-subsections – {"1": False} for a numbered workflow step folded away. A panel’s nested sections collapse too, and a collapse that is forgotten on the way out of the module is a collapse the user does again every visit.

  • boxes – dragged heights, {name: px at 100 % font scale}. STORED UNSCALED on purpose: a user who drags the merge report to eleven lines and then doubles the font wants eleven lines, not half of them, so the number that comes back is re-scaled rather than replayed.

Both new mappings are written only when they hold something, so a panel that has neither goes on producing exactly the record it always did.

spacr.qt.preferences.set_setting_animations_enabled(on: bool) → None[source]

Turn the animation inside setting tooltips on or off.

Flushed immediately so the very next hover honours it — see get_setting_animations_enabled() for why nothing caches it.

Parameters:

on – true to turn it on, false to turn it off; stored as a bool.

spacr.qt.preferences.set_share_diagnostic_logs(on: bool) → None[source]

Persist the revocable diagnostic-log preview opt-in.

Parameters:

on – true to let an error report save a redacted copy of the recent log, false not to; stored as a bool.

spacr.qt.preferences.set_show_alpha(on: bool) → None[source]

Show or hide modules and settings classified as Alpha.

Parameters:

on – true to show Alpha modules and settings, false to hide them; stored as a bool.

spacr.qt.preferences.set_show_beta(on: bool) → None[source]

Show or hide modules and settings classified as Beta.

Parameters:

on – true to show Beta modules and settings, false to hide them; stored as a bool.

spacr.qt.preferences.set_sound_enabled(on: bool) → None[source]

Persist the master sound switch.

Parameters:

on – play sounds when True.

spacr.qt.preferences.set_sound_event_enabled(event: str, on: bool) → None[source]

Persist one event’s switch.

Parameters:
  • event – a key of SOUND_EVENT_DEFAULTS.

  • on – play that event’s sound when the master switch is on.

Raises:

KeyError – for an event spaCR has no sound for.

spacr.qt.preferences.set_sound_music_file(path) → str[source]

Persist the music file the bed plays.

Parameters:

path – a path, or anything empty for spaCR’s own music.

Returns:

the value stored.

spacr.qt.preferences.set_sound_theme(key: str) → None[source]

Persist the chosen sound set.

Parameters:

key – a key of spacr.qt.sound_synth.SOUND_THEMES.

Raises:

ValueError – for a key no sound set has.

spacr.qt.preferences.set_sound_volume(fraction: float) → float[source]

Persist the master volume.

Parameters:

fraction – 0 to 1; values outside are clamped.

Returns:

the value stored.

spacr.qt.preferences.set_spacr_mode(mode: str) → None[source]

Persist the mode, and move the visual settings with it.

Entering Extra Performance stashes the five visual settings it overrides and writes their minimums; leaving it puts the stashed values back. Nothing else about a mode change is retroactive — the launch cleanup has already happened or not happened by the time anyone can reach this dialog.

Parameters:

mode – one of SPACR_MODES.

Raises:

ValueError – on an unknown mode.

spacr.qt.preferences.set_spinner_delay(seconds: float) → None[source]

Set the spinner’s appearance delay, in seconds. Clamped, not refused.

Parameters:

seconds – how long background work must run before the spinner shows; clamped between SPINNER_DELAY_MIN and SPINNER_DELAY_MAX, and an unparseable value or NaN stores DEFAULT_SPINNER_DELAY.

spacr.qt.preferences.set_theme(theme: str) → None[source]

Persist a supported application theme.

Choosing "system" also records that it was chosen, so get_theme() honours it instead of reading it as the default.

Parameters:

theme – one of VALID_THEMES.

Raises:

ValueError – if theme is not in VALID_THEMES.

spacr.qt.preferences.set_theme_choice(choice: str) → None[source]

Persist one token from theme_choices().

Choosing a night or data-art preset also writes its backdrop and its sound set — see apply_night_theme(), which is where the reasoning for doing so lives.

Parameters:

choice – a token from theme_choices(); a "cell:<variant>" token sets the Cell theme and that variant. Any other value raises ValueError.

spacr.qt.preferences.set_tooltips_bottom_enabled(on: bool) → None[source]

Turn the bottom tooltip strip on or off, effective at the next hover.

Parameters:

on – true to turn it on, false to turn it off; stored as a bool.

spacr.qt.preferences.set_tooltips_box_enabled(on: bool) → None[source]

Turn the hover tooltip box on or off, effective at the next hover.

Parameters:

on – true to turn it on, false to turn it off; stored as a bool.

spacr.qt.preferences.set_tooltips_enabled(on: bool) → None[source]

Turn every tooltip on or off, effective immediately.

Drops spacr.qt.tooltip_policy’s cached answer and takes down any tooltip already on screen, so clearing the switch is not followed by one last popup nobody asked for.

Parameters:

on – true to turn it on, false to turn it off; stored as a bool.

spacr.qt.preferences.set_verbose_logging(on: bool) → None[source]

Persist whether package-wide diagnostic tracing is enabled.

Parameters:

on – true to turn it on, false to turn it off; stored as a bool.

spacr.qt.preferences.set_workspace_copy_limit_mb(limit) → float[source]

Remember the per-file copy limit, and push it down with the mode.

Parameters:

limit – the largest file copy mode brings in, in megabytes; negative values store 0.0, and an unparseable value stores the workspace default.

spacr.qt.preferences.sound_bed_rests() → bool[source]

Whether the current performance level silences the music bed.

Returns:

True at the levels named in SOUND_BED_RESTS_AT.

spacr.qt.preferences.sound_is_offered() → bool[source]

Whether this process offers sound at all: only in spaceout mode.

Ordinary spaCR leaves sound off and hides its preferences tab. Spaceout is process-local (spacr.qt.theme.enable_spaceout(), called only by the spaceout launcher), so this is read live and never stored.

Does not import spacr.qt.theme: a process that has not imported it cannot have enabled spaceout, and this is asked on paths that must stay free of QtGui.

Returns:

True in spaceout mode, False in ordinary spaCR.

spacr.qt.preferences.spacr_mode_for_level(level: str) → str[source]

The resource posture a level implies, in the old three-mode words.

Parameters:

level – one of PERFORMANCE_LEVELS.

Returns:

one of SPACR_MODES.

Laptop is more constrained than Extra Performance and Workstation is less constrained than Balanced, but neither has its own posture in the cleanup code – they differ in what is RETAINED, not in how launch cleanup runs. Mapping them onto the nearest existing posture keeps one answer to “how hard does spaCR try to stay out of the way”.

spacr.qt.preferences.speed_group_values(speed: float) → dict[source]

What one Speed means for every setting that follows it.

Parameters:

speed – the single user-facing number.

Returns:

{setting: value} for the whole group.

spacr.qt.preferences.theme_background_path(theme: str, width: int = 0, height: int = 0)[source]

Background image for theme, or None if it does not use one.

One place for the “which theme wants which picture” question, so apply_preferences_to_app() and anything else that re-applies the stylesheet cannot drift apart.

Parameters:
  • theme – an application theme name; only "cell" has a background image.

  • width – the wanted image width in pixels; 0 or less means the screen size.

  • height – the wanted image height in pixels; 0 or less means the screen size.

spacr.qt.preferences.theme_choices() → tuple[source]

Return (label, token) choices for the single Theme control.

Image variants are represented as composite tokens in the UI while the persisted keys remain backward compatible.

The ten night themes follow the older palettes, in spacr.qt.night_themes.NIGHT_THEMES order, so the four the application has always had stay where a returning user looks for them and read as one family. Five data-art presets follow them in a separate block. Their tokens are plain keys with no variant, so there is nothing to compose into the token the way Cell does.

spacr.qt.preferences.theme_description(token: str) → str[source]

Return the one-sentence explanation of a theme_choices() token.

Night and data-art themes each carry a sentence saying what colours, backdrop and sound set come with them; that sentence is what the Theme control shows as the entry’s tooltip, the way the Sound set control shows spacr.qt.sound_synth.SoundTheme.description.

Parameters:

token – a token from theme_choices().

Returns:

the theme’s sentence (the high-contrast theme has one too), or "" for the four themes that predate the family and for any token without one. The caller passes the result through tr() and sets no tooltip when it is empty.

Nested helpers

PreferencesDialog._build_the_dialog._apply()

Preview the edits and ask separately, keeping this dialog open.

Only keys changed by this application are rolled back. New notification secrets are written only after Keep, so Revert cannot leave a replacement password in an external keyring. Edited controls remain available as a draft after Revert.

spacr/qt/preferences.py:10433

PreferencesDialog._build_the_dialog._apply._answered(_result)

Keep or revert once, then release the question and enable another Apply.

spacr/qt/preferences.py:10527

PreferencesDialog._build_the_dialog._apply._network_bytes()

Read the network configuration bytes, or None when no file exists.

spacr/qt/preferences.py:10454

PreferencesDialog._build_the_dialog._apply._restore()

Restore this preview’s changed keys, network configuration and live appearance.

spacr/qt/preferences.py:10465

PreferencesDialog._build_the_dialog._apply._snapshot()

Copy persisted preference values, bypassing any temporary store shadow.

spacr/qt/preferences.py:10446

PreferencesDialog._build_the_dialog._apply_the_scales_live() → None

Apply the two scales now and ask whether to keep them.

spacr/qt/preferences.py:8794

Keep the logarithmic slider aligned with an exact percentage.

spacr/qt/preferences.py:8508

PreferencesDialog._build_the_dialog._category(title: str, object_name: str)

Add a folded category to Appearance and return its form.

The category is the same widget the module screens group their settings with, so it folds and looks the way every other settings category does. Its rows sit in a holder named object_name, which is what the Help search opens the dialog on; the navigation unfolds the category on the way to a row.

spacr/qt/preferences.py:8116

PreferencesDialog._build_the_dialog._debug_follows_verbose(on) → None

Hold the DEBUG file switch on while verbose is on.

Verbose adds DEBUG to the log files whatever the switch says, so the switch shows that and cannot be changed. When verbose goes off, the switch is given back with the user’s own choice.

spacr/qt/preferences.py:9088

PreferencesDialog._build_the_dialog._magnifier_says(percent)

Show the lens size the slider is at, as a percentage.

spacr/qt/preferences.py:9883

PreferencesDialog._build_the_dialog._open_providers()

Open the install/login dialog, then re-list the providers.

spacr/qt/preferences.py:9238

PreferencesDialog._build_the_dialog._page(title: str, object_name: str) → 'QFormLayout'

Add a tab and return the form to fill it with.

Each page scrolls on its own so that a small screen shortens the tallest tab instead of the whole dialog, and every tab is still reachable at any window height.

spacr/qt/preferences.py:8090

PreferencesDialog._build_the_dialog._percent_row(name, label_text, low, high, current, tip, designed=1.0, target=None)

Build one labelled percentage slider and return its parts.

spacr/qt/preferences.py:8428

PreferencesDialog._build_the_dialog._percent_row._update(v)

Show the percentage, saying when it is the designed value.

“100%” alone does not tell a reader that it is the one to come back to.

spacr/qt/preferences.py:8442

PreferencesDialog._build_the_dialog._pick_ambient_background()

Keep the candidate fill local until the dialog is saved.

spacr/qt/preferences.py:8358

PreferencesDialog._build_the_dialog._pick_ambient_color(index)

Select a local colour and activate the custom palette on save.

spacr/qt/preferences.py:8346

PreferencesDialog._build_the_dialog._put_the_sliders_back(kept: bool) → None

After a Revert, show the values that are in force again.

spacr/qt/preferences.py:8779

PreferencesDialog._build_the_dialog._quit_spacr(parent) → None

Ask how, then either stop cooperatively or leave outright.

The graceful path is the same one closeEvent takes – cancel_all with a short budget – and then closes the window, so a normal quit still runs every shutdown hook. What this adds is the five-minute re-prompt, for the case closeEvent cannot handle: a worker wedged in a C extension that will never see the cancel flag, which leaves the window refusing to close with no way out from inside the application.

spacr/qt/preferences.py:9911

PreferencesDialog._build_the_dialog._refresh_custom_colors()

Show the pending colour pair while preserving dialog cancellation.

spacr/qt/preferences.py:8328

PreferencesDialog._build_the_dialog._reload_ambient_palettes(preferred=None)

Refill the palette list for the selected animation.

Palettes are per theme, so the two controls cannot be filled independently. The current choice is carried across when the new theme also offers it; otherwise that theme’s default is selected, which is exactly what the stored keys do.

spacr/qt/preferences.py:8269

PreferencesDialog._build_the_dialog._remember_the_debug_choice(checked) → None

Record the DEBUG file switch only while the user holds it.

spacr/qt/preferences.py:8205

PreferencesDialog._build_the_dialog._reset_to_defaults() → None

Put every control back to what a fresh install would show.

Read through the real getters against an EMPTY store rather than from a second copy of the default values. A hand-written table here would be a second place to update every time a preference gains a default, and the failure mode of getting it wrong is silent: a Reset that quietly sets something to a value no code path ever chose.

Only the controls change. Nothing is persisted until Save, so Cancel still walks away from a reset the user did not mean – which is why this does not write the empty store back.

spacr/qt/preferences.py:10132

PreferencesDialog._build_the_dialog._resource_button(action, label_text, row_label)

Build one labelled action button for the resources row.

spacr/qt/preferences.py:9953

PreferencesDialog._build_the_dialog._rim_lag_says(percent)

Show the rim chase as a percentage.

spacr/qt/preferences.py:8931

PreferencesDialog._build_the_dialog._rim_length_says(percent)

Show the rim length as a percentage of the perimeter.

spacr/qt/preferences.py:8905

PreferencesDialog._build_the_dialog._rim_period_says(tenths)

Show the rim period in seconds.

spacr/qt/preferences.py:8982

PreferencesDialog._build_the_dialog._save(*, close=True, save_secrets=True)

Write every preference this dialog owns, rim first.

THE RIM GOES FIRST because every open card rereads it: doing it before the theme work means one repaint rather than two.

spacr/qt/preferences.py:10249

PreferencesDialog._build_the_dialog._select(combo, value) → None

Point combo at the entry whose data is value.

spacr/qt/preferences.py:10124

PreferencesDialog._build_the_dialog._settle_unless_dragging(slider) → None

A drag applies on release; a click or key applies at once.

spacr/qt/preferences.py:8807

PreferencesDialog._build_the_dialog._steering_only_matters_when_guided(*_args)

Grey Steering on the fixed path, where it does nothing.

Shown rather than hidden, so it is clear that choosing the other path is what makes it live – a control that vanishes is one the user has to rediscover.

spacr/qt/preferences.py:9821

PreferencesDialog._build_the_dialog._suggestions(index: int) → str

What each level suggests for this row, as one sentence.

spacr/qt/preferences.py:9489

PreferencesDialog._build_the_dialog._sync_ambient_enabled(*_args)

Grey out the shaping controls when there is nothing to paint.

Driven by the Animation row itself now that None lives in it. The controls stay visible rather than disappearing, so the reader can see what choosing an animation would give them back; they are simply not settings that mean anything while nothing is being drawn.

spacr/qt/preferences.py:8584

PreferencesDialog._build_the_dialog._sync_console_enabled(level_value) → None

A console switch is only live while its file switch is.

spacr/qt/preferences.py:8158

PreferencesDialog._build_the_dialog._sync_custom_colors(*_args)

Offer custom colours for the retained procedural data-art scenes.

spacr/qt/preferences.py:8382

PreferencesDialog._build_the_dialog._sync_direction_row(*_args)

Show the drift direction only for the theme that travels.

spacr/qt/preferences.py:8410

PreferencesDialog._build_the_dialog._sync_fractal_note(*_args)

Say which renderer ‘auto’ will actually pick HERE.

The label cannot state it: it depends on whether vispy is importable on this machine, and the honest answer is the one the user will get.

spacr/qt/preferences.py:9650

PreferencesDialog._build_the_dialog._sync_mode_note(*_args)

Say which hardware the selected mode is for.

A selector whose levels do not name their hardware makes the user guess which one their machine is.

spacr/qt/preferences.py:9463

PreferencesDialog._build_the_dialog._sync_popup_motion(_index=0)

Offer these controls only to the compatible Qt paint engines.

spacr/qt/preferences.py:9020

PreferencesDialog._build_the_dialog._tenths(name, value, low=None, high=None)

A NUMBER FIELD, not a capped slider.

A spin box whose maximum is 2 turns a typed 40 into 2 without explaining the change. These settings accept the typed number and let validation report clearly when it cannot be used.

The range is opened to the widest a QDoubleSpinBox has, so the widget refuses nothing; explain_a_fractal_number is what decides whether a value can be used, and says why when it cannot.

spacr/qt/preferences.py:9705

PreferencesDialog._build_the_dialog._the_theme_brings_its_backdrop_and_its_sound(_index=0) → None

Move the other three controls when a night theme is picked.

THE BINDING HAS TO HAPPEN HERE AND NOT ONLY IN set_theme_choice. Save writes the Theme control and then writes the Animation, palette and Sound set controls straight after it, so a preset applied inside set_theme_choice would be overwritten three lines later by whatever the untouched combos still held. Moving the controls instead means the two paths agree and, more to the point, that the user SEES what the theme brought with it and can put any of it back before pressing Save.

The four themes that are not night themes change nothing else, which is why this returns early rather than reaching for a default: Dark has never carried an opinion about the backdrop and is not being given one now.

AND IT LEAVES THE ANIMATION ALONE WHEN THE CONTROL SAYS NONE, for the reason apply_night_theme() gives: a theme must not start something moving for a user who has turned motion off. The Sound set still moves, because that control decides WHICH sounds would play and not WHETHER any do.

spacr/qt/preferences.py:10057

PreferencesDialog._build_the_dialog._update_opacity_lbl(v)

Show what was asked for, and what the theme will allow.

The floor is the whole design of this control: on Space it is 78 %, so “20 %” would otherwise be a number the user set and the app quietly ignored.

spacr/qt/preferences.py:8845

PreferencesDialog._build_the_dialog._update_scale_lbl(v)

Show the font scale as a percentage.

spacr/qt/preferences.py:8741

PreferencesDialog._build_the_dialog._update_spinner_lbl(v)

Show the spinner delay in seconds, or “show immediately” at zero.

spacr/qt/preferences.py:8717

PreferencesDialog._build_the_dialog._update_tooltip_delay_lbl(v)

Show the tooltip delay in seconds, or “show immediately” at zero.

spacr/qt/preferences.py:8636

PreferencesDialog._build_the_dialog._warn_when_both_are_off() → None

Say what turning both off costs, on the rows themselves.

Not a refusal: both off is legal and the request says so. But on several forms the API link inside a setting’s tooltip is the only route from that control to its documentation, so a reader who clears both loses that route with nothing on screen to say why. The warning is on the switches because that is where the choice is made.

spacr/qt/preferences.py:8674

PreferencesDialog._build_the_dialog._whole(name, value)

A whole-number field, equally uncapped.

spacr/qt/preferences.py:9726

PreferencesDialog._build_the_dialog._workspace_copying(mode: str) → None

The limit only means anything when files are being copied.

spacr/qt/preferences.py:10015

_NotificationsPage.__init__.line(tip, placeholder='', secret=False)

A text field with its tooltip and placeholder.

spacr/qt/preferences.py:5788

_install_run_notifier._RunFinishedRelay.__init__(self, parent) → None

Listen for messages on the thread this object lives in.

spacr/qt/preferences.py:7131

_install_run_notifier._RunFinishedRelay._show(self, title: str, body: str, failed: bool) → None

Show one message from the tray, or without Qt when none.

spacr/qt/preferences.py:7139

_install_run_notifier._without_qt(title: str, body: str) → None

The operating system’s notification, any failure logged.

spacr/qt/preferences.py:7119

_page_stand_in_class._PageStandIn.sizeHint(self)

Larger than any scroll area lets a page ask to be.

spacr/qt/preferences.py:7797

_preferences_window_class._PreferencesWindow.__init__(self, parent=None)

An empty Preferences window; the builder fills it.

Parameters:

parent – the owning window, or None.

spacr/qt/preferences.py:7851

_preferences_window_class._PreferencesWindow._bring_the_page_back(self, index) → bool

Put a waiting page back in its tab as the tab is chosen.

Parameters:

index – the tab just chosen.

Returns:

True when this call put a page back.

spacr/qt/preferences.py:7966

_preferences_window_class._PreferencesWindow._send_the_unseen_pages_away(self) → int

Take every page but the current tab’s out of the window.

Returns:

how many widgets left the window.

spacr/qt/preferences.py:7939

_preferences_window_class._PreferencesWindow._show_only_the_open_page_at_first(self, tabs) → None

Have the first show style only the page of the current tab.

Called once the build is finished. The pages stay where they are until the show, so the navigation that picks the tab to open on finds each control on its tab.

Parameters:

tabs – the dialog’s QTabWidget; every page is a scroll area holding the page.

spacr/qt/preferences.py:7862

_preferences_window_class._PreferencesWindow.findChild(self, *args, **kwargs)

QObject.findChild, finding a control whose page is waiting.

A control looked up by its object name is the dialog’s wherever its page is, so what the builder, Save and a test find by name does not depend on which tabs have been chosen. The page it is on comes back into its tab, hidden unless its tab is current, as it was before pages waited: a caller that goes on to click or read the geometry of what it found is holding a widget in the window.

Returns:

the first match, or None.

spacr/qt/preferences.py:7899

_preferences_window_class._PreferencesWindow.findChildren(self, *args, **kwargs)

QObject.findChildren over every page, waiting or not.

A walk of the dialog from Python – a test’s, or code that looks at every control – sees the dialog it saw before pages waited, so every waiting page comes back first. Not during the first show: the window sheet, the glass and the resize filter walk the dialog then, and bringing the pages back for them is the cost the waiting exists to save. Nor while a page is coming back, whose glass asks the dialog for its card.

Returns:

every match.

spacr/qt/preferences.py:7921

_preferences_window_class._PreferencesWindow.setVisible(self, visible)

Send the unseen pages away just before the first show.

HERE, AND NOT ON THE FIRST Polish. The window sheet, the glass and the resize filter all act on that event from the application, which hears it before the window does, and the resize filter polishes every child as it does. Qt’s own show begins in this call, so the pages are gone before any of them runs.

Parameters:

visible – as for QWidget.setVisible.

spacr/qt/preferences.py:7876

_start_disk_report.done(report) → None

On the GUI thread, with whatever the worker came back with.

spacr/qt/preferences.py:7533

_start_disk_report.read()

On the worker thread. Returns the report, or the exception.

Returned rather than raised so the callback below is reached either way; see the failure paragraph above. disk_report is looked up here, not captured, so a caller that replaces it still gets its own.

spacr/qt/preferences.py:7511

_start_disk_report.restore() → None

Give the button back. The C++ half may be gone; that is fine.

spacr/qt/preferences.py:7523

get_fractal_settings._number(key, default, low, high)

A stored number, with only the bounds that are real.

None for a bound means there is none: the settings are FIELDS, and a value the user typed is not quietly reduced on the way back out. Only a value that cannot work at all is refused, and explain_a_fractal_number is what says so, in words, at the point it is entered.

spacr/qt/preferences.py:3035

get_fractal_settings._text(key, default, allowed)

One stored string, or the default when it is not an allowed value.

Falls back rather than raising: a stale preference naming a theme that no longer exists must not stop the settings loading.

spacr/qt/preferences.py:3026

get_fractal_settings._truth(key, default)

A stored boolean, however QSettings gave it back.

An INI file hands every value back as a string, so bool("false") is True and a switch the user turned off comes back on.

spacr/qt/preferences.py:3056