A save without a recent user gesture (e.g. over the control channel) is refused with SecurityError and would otherwise fail silently.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Clean-room import of Excel 97-2003 workbooks from the public [MS-CFB] and
[MS-XLS] specifications: compound-file streams (FAT, mini FAT, directory
tree), the BIFF8 Workbook stream with Continue records, shared strings,
all cell records, formulas decoded from Ptg tokens (shared and array
formulas, 3-D refs, names, add-in/newer functions by name) with cached
results, number formats, the 1904 date system, merges, column widths, row
heights, defined names and print areas/titles. Encrypted (FILEPASS) and
BIFF5 files are refused with a clear message; everything else is skipped
with a warning. .xls opens as a new unsaved workbook (Save As .xlsx).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The web build had no way to actually print — Ctrl+P (Cmd+P, declared on
file.print's shortcut) did nothing at all, and the ribbon's "Print…" menu
item ran file.print and silently discarded the result. file.print already
builds a PDF and returns it as base64 specifically "for the UI to hand to
the system print dialog" per its own doc comment — this wires that up.
- ui-egui: new Services::print hook (web: hand PDF bytes to the browser's
print flow directly, no download); SheetApp::print_now runs file.print,
decodes the base64 result, and calls the hook.
- ui-egui: Key::P now dispatches to print_now (was unbound); the ribbon's
"Print…" menu item calls print_now instead of discarding file.print's
result.
- gridcraft-web: implements the hook (Blob -> object URL -> hidden iframe
-> iframe.contentWindow.print() on load).
Desktop builds are unaffected (no Services::print set there; print_now
falls back to the existing alert-on-error behaviour with no UI action on
success, same as before this change).
Add static pictures inside cells with XLSX roundtrip
Rebased onto main (conflicts with #83/#98 and main resolved by maintainer); the contributor's branch does not allow maintainer edits.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Merge the fixed#31 branch (which carries #38's font fallback) and resolve:
- theme.rs: build on #38's fallback_faces/load_fallback instead of the old
load_cjk. The interface language only reorders the two Han entries
(sys-cjk-han-ja / sys-cjk-han-zh; Japanese first for ja, Chinese first
otherwise); Hangul, Thai and Hebrew keep their place. The region-merged
Noto Sans CJK .ttc is loaded once, with the leading language's face index.
- Fonts are rebuilt on a language switch only when the Han order changes
(HanOrder), not on every switch. font_definitions()/setup_context() use
the default order and never read the host locale.
- Tests stay locale-independent (UiState defaults to English; the desktop
app applies the system language). The web build follows the browser
language except CJK, which would render as tofu without system fonts.
- app.language.set error/params list all five codes; engine.commands lists
it. zh/ko/ru gain the keys #31 added (Page Layout|Orientation, display
theme). The Page Layout screen checkbox keeps English "View" via a
"Sheet Options|View" key (was shown as "Screen").
- Coverage test checks zh/ja/ko/Thai/Hebrew/Cyrillic in both the UI and
cell families by comparing glyphs with the tofu glyph.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Blank cell and row repeats that run past 16384 columns / 1048576 rows
(padding from writers with larger sheets) are clipped instead of
rejecting the file; any data or merge past the edge is still an error.
convert() builds its Cell with ..Cell::value(value) so new Cell fields
take their defaults.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Resolves the shared integration points for both formats: combined sniff,
file.open spec, file filters, MCP description, docs. open_bytes now lets
sniffed content (ODS or XLSB) win over the extension.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>