Explorer tab:
- New block explorer tab with search, chain stats, mempool info,
recent blocks table, block detail modal with tx expansion
- Sidebar nav entry, i18n strings, ui.toml layout values
Bootstrap fixes:
- Move wizard Done handler into render() — was dead code, preventing
startEmbeddedDaemon() and tryConnect() from firing post-wizard
- Stop deleting BDB database/ dir during cleanup — caused LSN mismatch
that salvaged wallet.dat into wallet.{timestamp}.bak
- Add banlist.dat, db.log, .lock to cleanup file list
- Fatal extraction failure for blocks/ and chainstate/ files
- Verification progress: split SHA-256 (0-50%) and MD5 (50-100%)
Theme system:
- Expand overlay merge to apply ALL sections (tabs, dialogs, components,
screens, flat sections), not just theme+backdrop+effects
- Add screens and security section parsing to UISchema
- Build-time theme expansion via expand_themes.py (CMake + build.sh)
Other:
- Version bump to 1.1.0
- WalletState::clear() resets all fields (sync, daemon info, etc.)
- Sidebar item-height 42 → 36
123 lines
3.9 KiB
Python
123 lines
3.9 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Build-time theme expander — merges layout sections from ui.toml into skin files.
|
|
|
|
Called by CMake during build. Reads source skin files + ui.toml, writes merged
|
|
output files to the build directory. Source files are never modified.
|
|
|
|
Usage:
|
|
python3 expand_themes.py <source_themes_dir> <output_themes_dir>
|
|
|
|
For each .toml file in source_themes_dir (except ui.toml), the script:
|
|
1. Copies the skin file contents (theme/palette/backdrop/effects)
|
|
2. Appends all layout sections from ui.toml (fonts, tabs, components, etc.)
|
|
3. Writes the merged result to output_themes_dir/<filename>
|
|
|
|
ui.toml itself is copied unchanged.
|
|
"""
|
|
|
|
import re
|
|
import sys
|
|
import os
|
|
|
|
# Sections to SKIP when extracting from ui.toml (theme-specific, already in skins)
|
|
SKIP_SECTIONS = {"theme", "theme.palette", "backdrop", "effects"}
|
|
|
|
|
|
def extract_layout_sections(ui_toml_path):
|
|
"""Extract non-theme sections from ui.toml as a string."""
|
|
sections = []
|
|
current_section = None
|
|
current_lines = []
|
|
section_re = re.compile(r'^\[{1,2}([^\]]+)\]{1,2}\s*$')
|
|
|
|
with open(ui_toml_path, 'r') as f:
|
|
for line in f:
|
|
m = section_re.match(line.strip())
|
|
if m:
|
|
if current_section is not None or current_lines:
|
|
sections.append((current_section, current_lines))
|
|
current_section = m.group(1).strip()
|
|
current_lines = [line]
|
|
else:
|
|
current_lines.append(line)
|
|
if current_section is not None or current_lines:
|
|
sections.append((current_section, current_lines))
|
|
|
|
layout_parts = []
|
|
for section_name, lines in sections:
|
|
if section_name is None:
|
|
# Preamble: only include top-level key=value lines
|
|
kv_lines = [l for l in lines
|
|
if l.strip() and not l.strip().startswith('#') and '=' in l]
|
|
if kv_lines:
|
|
layout_parts.append(''.join(kv_lines))
|
|
continue
|
|
if section_name in SKIP_SECTIONS:
|
|
continue
|
|
layout_parts.append(''.join(lines))
|
|
|
|
return '\n'.join(layout_parts)
|
|
|
|
|
|
def main():
|
|
if len(sys.argv) != 3:
|
|
print(f"Usage: {sys.argv[0]} <source_themes_dir> <output_themes_dir>")
|
|
sys.exit(1)
|
|
|
|
src_dir = sys.argv[1]
|
|
out_dir = sys.argv[2]
|
|
ui_toml = os.path.join(src_dir, "ui.toml")
|
|
|
|
if not os.path.exists(ui_toml):
|
|
print(f"ERROR: ui.toml not found at {ui_toml}")
|
|
sys.exit(1)
|
|
|
|
os.makedirs(out_dir, exist_ok=True)
|
|
|
|
layout_content = extract_layout_sections(ui_toml)
|
|
|
|
separator = (
|
|
"\n# ===========================================================================\n"
|
|
"# Layout & Component Properties\n"
|
|
"# All values below can be customized per-theme. Edit and save to see\n"
|
|
"# changes reflected in the app in real time via hot-reload.\n"
|
|
"# ===========================================================================\n\n"
|
|
)
|
|
|
|
for fname in sorted(os.listdir(src_dir)):
|
|
if not fname.endswith('.toml'):
|
|
continue
|
|
src_path = os.path.join(src_dir, fname)
|
|
dst_path = os.path.join(out_dir, fname)
|
|
|
|
if fname == "ui.toml":
|
|
# Copy ui.toml unchanged
|
|
with open(src_path, 'r') as f:
|
|
content = f.read()
|
|
with open(dst_path, 'w') as f:
|
|
f.write(content)
|
|
print(f" COPY {fname}")
|
|
continue
|
|
|
|
# Skin file — append layout sections
|
|
with open(src_path, 'r') as f:
|
|
skin = f.read()
|
|
if not skin.endswith('\n'):
|
|
skin += '\n'
|
|
|
|
merged = skin + separator + layout_content
|
|
if not merged.endswith('\n'):
|
|
merged += '\n'
|
|
|
|
with open(dst_path, 'w') as f:
|
|
f.write(merged)
|
|
lines = merged.count('\n')
|
|
print(f" MERGE {fname} → {lines} lines")
|
|
|
|
print("Done.")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|