* [Fonts] Retire max font size setting into theme CardText min/max range
The per-card text size lives in the theme now, so a theme can pick the size
it was designed for instead of every user overriding it globally.
- CardText stores family + max point size; CardTextMinSize stores the
overlay shrink-to-fit floor (omitted from fonts.toml when 1).
- ThemeManager::cardTextMaxSize()/cardTextMinSize() resolve the range with
the retired defaults (12 max, 1 min), and cardTextMaxSize() falls back to
the CardText role size that #7541 made live.
- The overlay widget starts at the explicit size when one is set (deck
preview), else the theme max, and shrinks down to the theme floor.
- The appearance page's "Maximum font size" spin is gone; the range is
edited in the theme's font grid, whose min/max spins now keep the saved
range consistent with each other.
- Migration: appearance/maxFontSize is seeded into every user theme folder
and into the active theme's folder (created when the theme is a shipped
one that only exists in the system directory). The retired
game/maxfontsize -> appearance/maxFontSize mapping stays, so users still
on global.ini keep their value through the chain.
* [Fonts] Resolve CardText sizes against the shipped theme
Seeding themes/<name>/fonts.toml made getAvailableThemes() resolve the user dir, which shadowed the shipped theme.cfg and stylesheet: styleName came back empty and QSS was cleared. Fall back to the shipped theme dir for theme.cfg and QSS when the user dir exists, and resolve CardText sizes through FontConfig's 6..72 range so a migrated 80..100 renders at the size the editor shows. Insert CardTextMaxSize inside [Fonts] when another section follows.
---------
Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
* [GameSelector] Persist quick-filter toolbar edits and repair filter settings migration
- Save game-filter parameters on toolbar changes, debounced with flush on close
- Repair pre-camelCase gamefilters.ini keys in place on startup
- Map the legacy creator-name filter to hostNameFilter
- Balance begin/endFilterChange in GamesProxyModel::refresh
- Align the hideIgnoredUserGames default between model and settings
- Cover the migration with regression tests
* [Review] Address RickyRister comments on filter persistence
- Rename game-type prefix constants to SCREAMING_SNAKE to match
MIGRATION_SENTINEL_KEY and project style
- Document why GameSelector destructor flushes a pending debounced
filter save (toolbar path has no other writer)
---------
Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
* [Settings] Back up the settings folder before migrating
The per-file settings migration only preserved global.ini, as
global.ini.old. Everything else the migrations write was overwritten in
place with no way back: the legacy migration and the 17 per-domain
migrateXxxSettings functions all write straight into the per-domain .ini
files, so any of them that got a key mapping wrong silently replaced a
working file. The re-migration path is the sharpest case, because
migrateSettingsFromGlobalIni() runs again whenever an older build wrote
non-sentinel keys back into global.ini, and those values then land on
top of per-domain files the user had already edited.
Snapshot the whole settings folder before either migration runs, into a
timestamped sibling settings-backup-<yyyyMMdd-HHmmss>. A sibling rather
than a child, so a backup is never copied into the next backup and the
"Open Settings Folder" action keeps showing only live files. Keep every
snapshot; settings files are kilobytes, so growth is not a concern.
SettingsMigration::isMigrationPending() gates the copy so a normal start
creates nothing. It reuses the same condition migrateSettingsFromGlobalIni()
uses to decide whether it has work, factored into a shared helper so the
two cannot drift, and it ignores the legacy migration on an empty profile
where that migration only writes its sentinel. The backup itself skips a
folder whose files are all empty, which covers a fresh profile whose
global.ini was created but never written.
A failed copy logs a warning and returns an empty path rather than
aborting the migration, since a full disk or an unwritable data folder
must not leave the client unable to start. global.ini.old still works as
the single-file escape hatch.
Document the folder layout, the automatic backups, and the fact that
migrations only run forwards, so users know to copy the settings folder
before downgrading to a version that cannot read the per-group files.
* [Client] Match the desktop file name case for the portal app ID
QGuiApplication::setDesktopFileName() was given "Cockatrice"/"Oracle"
while the installed desktop entries are cockatrice.desktop and
oracle.desktop. Linux paths are case-sensitive, so xdg-desktop-portal
failed the app-info lookup for "Cockatrice" and Qt warned on every
QDesktopServices call that it could not register with the host portal.
The same string becomes the xdg-shell appId, so the window icon lookup
failed on Wayland for the same reason.
---------
Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
* [Settings] Split cache_settings into multiple files
Took 9 minutes
Took 4 minutes
* [Settings] Fwd declare settings classes in cache_settings
Took 15 minutes
* Fix oracle includes.
Took 8 minutes
* Address comments, fix windows CI
Took 8 minutes
* fix copy constructor visibility
Took 3 minutes
* lint
Took 2 minutes
* Fix native format tests.
Took 5 minutes
* Remove test header guard
Took 4 seconds
* Remove tests invalid in CI environ
Took 24 seconds
* Adjust to rebase.
Took 11 minutes
* Change settings file name.
Took 8 minutes
---------
Co-authored-by: Lukas Brübach <lukas.bruebach@bdosecurity.de>
Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>