Commit Graph
438 Commits
Author SHA1 Message Date
Brandon Thomas a96f19f02b Merge pull request #409 from shrshk/fix/formula-arg-count-363
Refuse formulas with the wrong argument count on entry (#363)
2026-10-11 18:05:18 -04:00
Brandon Thomas e2bcb712fd Merge pull request #418 from neilcawse/fix/numfmt-text
Numfmt: fraction literals and zero fractions, `?` pads thousands separator, TEXT booleans through text section
2026-10-11 18:05:17 -04:00
Brandon Thomas 936c6a055a Merge pull request #423 from neilcawse/fix/xlsx-names-xlpm
XLSX: strip _xlpm. from LET/LAMBDA parameters on read, keep line breaks in table columns, allow leading backslash in table names

# Conflicts:
#	docs/file-format-parity.md
2026-10-11 18:05:16 -04:00
Brandon Thomas 5432419cd5 Merge pull request #427 from vedran-dobos/csv-keep-delimiter
CSV: saving keeps the separator the file was opened with (#426)
2026-10-11 18:05:14 -04:00
Vedran DobosandClaude Opus 5.5 b13ea3e2f3 CSV: saving keeps the separator the file was opened with (#426)
A `;`-separated CSV (the usual CSV where `,` is the decimal separator) was
rewritten with `,` on save: read_csv sniffed the delimiter but the result was
dropped, and save_bytes passed a hard-coded b','. file.save, Save As .csv,
file.exportCsv, file.saveBytes and gridcraft-cli convert all went through it.

The workbook now remembers the separator it was read with
(Workbook::csv_delimiter, set by read_csv) and a CSV save writes it back.
Workbooks not read from CSV, and .tsv/.txt sources saved as .csv, keep `,`.

Regression tests: `;`, `,` and tab .csv round trips byte for byte, new and
.xlsx-origin workbooks save with `,`, and open-by-path + edit + file.save on a
`;` file keeps `;` (also through exportCsv and saveBytes).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 23:46:27 -07:00
Brandon Thomas e6773dac3c Merge pull request #433 from derechopiano/fix/autofit-filter-button-spacing
Fix AutoFit width for table and AutoFilter dropdowns
2026-10-11 18:05:13 -04:00
Brandon Thomas 1841658978 Merge pull request #439 from itrycodinganditsbad/rotated-text-align
Rotated text follows the cell's alignment
2026-10-11 18:05:12 -04:00
Fabio LussiandClaude Opus 5.5 dbc04ddae0 Rotated text follows the cell's alignment (Fixes #435)
Text turned by an angle was drawn at a fixed anchor (bottom-left for upward,
top-left for downward text) and ignored the horizontal and vertical alignment,
so upright text with Middle Align in a tall merged cell sat at the bottom.

rotated_text_pos places the turned galley's bounding box in the cell per the
alignment, then derives the TextShape anchor from it. General/Bottom keep the
old placement for upright text.

Fixes #435

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 00:00:56 +02:00
MarekSpodBiedry 88df1670ba Scatter charts of two unlabelled columns plot the first as X for one series (#428) 2026-10-11 23:38:27 +02:00
Shirish Veerabattini 3936f3b79c engine: correct which functions the entry check skips
IF, IFERROR, CHOOSE, SWITCH and INDEX are in the registry and are checked; the comment listed IF as skipped.

Claude-Session: https://claude.ai/code/session_01BGBBGBC2gRpQ7GDuwQ6WPt
2026-10-11 16:10:04 -05:00
derechopiano 1a6c864235 home.autofitColumnWidth: reserve filter dropdown space 2026-10-11 22:09:51 +01:00
Shirish Veerabattini 478f01d236 functions: keep DATEDIF's original description, add the units
Restores "Counts whole years, months or days between two dates." and
appends the units, in the multi-line form rustfmt gives a long entry.

Drops the 256-argument test case: the parser already refuses more than
255 arguments, so it never reached the entry check. (993c108's message
says entry "also refuses" them; it already did.)

Claude-Session: https://claude.ai/code/session_01BGBBGBC2gRpQ7GDuwQ6WPt
2026-10-11 15:57:33 -05:00
neilcawseandClaude Opus 5.5 13afa8c773 XLSX: read cell formulas via file→model conversion (_xlpm), keep line breaks in table columns, allow leading backslash in table names
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 16:39:31 -04:00
neilcawseandClaude Opus 5.5 737999f182 Numfmt: fraction literals and zero fractions, ? pads thousands separator, TEXT booleans through text section
Checked against Excel-cached TEXT() results in number- and text-format test workbooks: 226 of 352 TEXT cells mismatched before, 0 after.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 16:39:30 -04:00
Shirish Veerabattini 1d1d27f9a4 ui: argument hint shows the function's description
Inside DATEDIF( the hint showed only the signature, so the values unit
takes weren't visible while typing it (#363). The hint now adds the
function's description under the signature, wrapped to the hint's
width, the same text the autocomplete list shows (translated where a
Spanish entry exists).

Claude-Session: https://claude.ai/code/session_01BGBBGBC2gRpQ7GDuwQ6WPt
2026-10-11 15:37:09 -05:00
Shirish Veerabattini 993c108660 functions: share the argument-count rule between call and entry
FnSpec::accepts holds the arity check (including Excel's 255-argument
limit) that functions::call and the entry check both use, so entry also
refuses 256 arguments to a variadic function. The evaluator's own check
in calc is unchanged.

Claude-Session: https://claude.ai/code/session_01BGBBGBC2gRpQ7GDuwQ6WPt
2026-10-11 15:37:09 -05:00
Shirish Veerabattini 9b59966cc9 Merge upstream main into fix/formula-arg-count-363
Claude-Session: https://claude.ai/code/session_01BGBBGBC2gRpQ7GDuwQ6WPt
2026-10-11 15:20:56 -05:00
Brandon ThomasandClaude Opus 5.5 3054babe0e Text boxes: their typefaces count as used workbook fonts, so an installed one is bound; restore image_ext's doc comment (review fix-up for #401)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 16:14:41 -04:00
Brandon Thomas 1c3beb2a95 Merge branch 'land' into fix-401
# Conflicts:
#	ROADMAP.md
2026-10-11 16:09:03 -04:00
Brandon Thomas 4a23b9cf4b Merge pull request #404 from vangel76/fix/header-footer-variants
Headers and footers: first-page and even-page variants, Insert › Header & Footer edits in place (#344)

# Conflicts:
#	ROADMAP.md
2026-10-11 16:08:56 -04:00
Brandon Thomas 7cd96b945f Merge pull request #402 from vangel76/fix/ui-font-hebrew-fallback
UI fonts: formula bar falls back to the cell font, so Hebrew isn't boxes (#349)

# Conflicts:
#	ROADMAP.md
2026-10-11 16:08:55 -04:00
Brandon Thomas b2101947ca Merge branch 'land' into fix-388
# Conflicts:
#	docs/ui-parity.md
2026-10-11 16:01:53 -04:00
Brandon Thomas 6cc69494ca Merge branch 'land' into fix-394
# Conflicts:
#	ROADMAP.md
2026-10-11 15:55:10 -04:00
Brandon ThomasandClaude Opus 5.5 6d59233e62 XLOOKUP reference path: an empty match_mode keeps the search_mode after it (review fix-up for #396)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 15:49:32 -04:00
Brandon Thomas c7bd7deebb Merge branch 'land' into fix-396 2026-10-11 15:49:00 -04:00
vangel76andClaude Opus 5.5 cdd71b4d5d Headers and footers: first-page and even-page variants, Insert › Header & Footer edits in place (#344)
XLSX headerFooter kept only oddHeader/oddFooter: a workbook whose header is on a
different first page (differentFirst + firstHeader) or on even pages showed no
header, and saving dropped it. The model now keeps the first/even headers and
footers and the differentFirst / differentOddEven / scaleWithDoc / alignWithMargins
flags; XLSX reads and writes them; the PDF and the Page Layout view use the right
pair per page; in-place editing edits the page's own pair, and the Header & Footer
tab has Different First Page and Different Odd & Even Pages. pageLayout.headerFooter
takes the variants and a page: odd|even|first for one-section edits.

Insert › Header & Footer now switches to Page Layout view and edits the first
page's centre header, as in Excel, instead of opening the codes dialog.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 21:44:49 +02:00
Brandon Thomas f173d6733d Merge pull request #387 from vangel76/fix/sheet-protection-password
Review: Protect Sheet passwords use Excel-compatible hashes, kept in XLSX (#346)

# Conflicts:
#	ROADMAP.md
2026-10-11 15:43:46 -04:00
Brandon Thomas 283b06453e Merge pull request #383 from vangel76/fix/sheetview-top-left-cell
View: restore and save the scroll position (topLeftCell) (#378)

# Conflicts:
#	ROADMAP.md
2026-10-11 15:43:45 -04:00
Brandon Thomas 12b46e6bbe Merge pull request #395 from vangel76/fix/space-selection-shortcuts
Keyboard: Shift+Space and Ctrl+Space select without starting an edit (#338)

# Conflicts:
#	ROADMAP.md
#	crates/ui-egui/src/grid.rs
2026-10-11 15:43:44 -04:00
Brandon Thomas 8498dedb7d Merge pull request #381 from vangel76/fix/shrink-to-fit
Grid: render Shrink to fit (#375)

# Conflicts:
#	ROADMAP.md
#	crates/ui-egui/src/grid.rs
2026-10-11 15:43:32 -04:00
Brandon Thomas d90a072d90 Merge pull request #380 from vangel76/fix/merged-range-borders
Grid: merged ranges draw their right and bottom borders (#376)

# Conflicts:
#	ROADMAP.md
2026-10-11 15:43:31 -04:00
Brandon ThomasandClaude Opus 5.5 fca801c17e INDEX: compare the result size with saturating u64 math, so it can't overflow on 32-bit targets (review fix-up for #400)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 15:43:11 -04:00
Brandon Thomas fbb2285532 Merge branch 'land' into fix-400 2026-10-11 15:42:32 -04:00
Brandon Thomas 437881f53a Merge pull request #399 from nihilist-narwhal/fix-future-function-prefixes
XLSX: write the _xlfn. prefix for GROUPBY, PIVOTBY, ENCODEURL and the REGEX functions
2026-10-11 15:42:27 -04:00
Brandon Thomas d821aa1409 Merge pull request #398 from nihilist-narwhal/fix-relative-names
Defined names: relative references follow the cell that uses the name
2026-10-11 15:42:26 -04:00
Brandon Thomas 2657cb2fa6 Merge pull request #397 from nihilist-narwhal/fix-validation-formulas
Data validation: relative formulas, checked with the value being entered
2026-10-11 15:42:25 -04:00
vangel76andClaude Opus 5.5 88bb5677a8 UI fonts: interface text falls back to the cell font (#349)
On macOS the UI font (SF) has no Hebrew and no Hebrew fallback face was
found, while cells in Arial drew it: the formula bar showed boxes. The
interface families now carry the cell face ahead of the script fallbacks,
and the macOS Hebrew candidates include ArialHB.ttc / SFHebrew.ttf /
LucidaGrande.ttc.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 21:42:24 +02:00
vangel76andClaude Opus 5.5 da1d291d93 Drawing: text box run formatting, alignment, anchor and no-outline (#377)
Text boxes ignored a:rPr (size, bold, italic, typeface, fill, outline),
a:pPr algn, a:bodyPr anchor and spPr/a:ln/a:noFill. They are now read into
Shape::format, drawn on screen and in PDF, and written back.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 21:39:53 +02:00
Brandon ThomasandClaude Opus 5.5 e211f666a6 Merge main into installed-fonts: workbook fonts bind on top of main's per-language font set and fallback faces; only families that survive drop_unparseable_fonts count as bound; a language switch rebinds them (review fix-up for #9)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 15:38:42 -04:00
vangel76andClaude Opus 5.5 8587c2ba14 Review: Protect Sheet can't replace a sheet's password without unprotecting it
Re-protecting a password-protected sheet would drop its hash and let a
plain Unprotect succeed; it is now refused. The sheet tab menu offers
Unprotect Sheet on a protected sheet, like the ribbon.

Refs #346

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 21:36:05 +02:00
vangel76andClaude Sonnet 5.5 6290bf123a Keyboard: Shift+Space and Ctrl+Space select without starting an edit (#338)
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-11 21:32:57 +02:00
vangel76andClaude Opus 5.5 ad48f1e3e1 File: desktop Print opens the system PDF viewer, Save As offers PDF/CSV/HTML (#370, #343)
Since #209, printing from the UI hands the print PDF to Services::print, which only
the web build set: on the desktop, Ctrl+P, More › Print, the macOS menu and the
Backstage Print button produced the PDF and dropped it. The desktop app now writes
it to the temporary folder and opens it in the system PDF viewer, whose Print
reaches the printer dialog.

Save As has a Save as type chooser (xlsx, csv, html, pdf); file.save and
file.saveAs with a .pdf path write a PDF of the sheet (they wrote XLSX bytes into
the .pdf and made it the workbook's file). The desktop save picker honours the
suggested type instead of always proposing .xlsx. The macOS Properties item opens
File › Info instead of running file.properties with no fields.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 21:32:38 +02:00
vangel76andClaude Opus 5.5 22978a7e62 Review: Protect Sheet passwords use Excel-compatible hashes, kept in XLSX
Sheet protection stored an internal FNV hash that was never written to
XLSX, and an Excel sheet password was dropped on import, so imported
protected sheets could be unprotected without it. Protect Sheet now
stores a salted SHA-512 hash (spin count 100000) via PasswordHash; the
XLSX sheetProtection password (iterated or legacy) is read and written,
and Unprotect Sheet really verifies it. Hashes from older GridCraft JSON
workbooks are still read and verified.

Refs #346

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 21:29:10 +02:00
Fabio LussiandClaude Opus 5.5 535c502fe7 Draw the outline band for grouped rows and columns
Grouped rows and columns now get Excel's outline band beside the headers:
a bracket per group, a -/+ button on the summary line and level buttons
in the corner. The buttons run data.hideDetail / data.showDetail and the
new data.showLevels, so they undo. Hide Detail marks the summary line
collapsed, Show Detail keeps inner groups that were collapsed on their
own, and Group / Ungroup take by: rows|cols. Show Detail and Hide Detail
are on the Data tab and in the Data menu, the group shortcuts are listed
as Alt+Shift+Right / Left, and shortcut lookup reads navigation keys by
their logical key so the numpad arrows work.

Fixes #373

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 21:29:03 +02:00
Brandon ThomasandClaude Opus 5.5 9bf5ecaf04 Merge main into VBA preservation; save macros only into .xlsm (an .xlsx never carries a VBA project); drop the shell round-trip script (review fix-up for #19)
The Rust round-trip test covers what scripts/check-vba-roundtrip.sh checked.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 15:20:45 -04:00
vangel76andClaude Opus 5.5 fbabac15d4 Review: Protect Workbook dialog with an Excel-compatible password (#345)
The ribbon button toggled structure protection silently. It now opens a
Protect Structure and Windows dialog with an optional password; when a
password was set, unprotecting asks for it and really verifies it
(SHA-512, spin count 100000, salted). The password hash is read from and
written to XLSX workbookProtection (workbookAlgorithmName/HashValue/
SaltValue/SpinCount or the legacy workbookPassword); an unreadable one
stays locked. File › Info uses the same flow.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 21:12:24 +02:00
vangel76andClaude Opus 5.5 04001fd943 View: restore and save the scroll position (sheetView topLeftCell) (#378)
The model read topLeftCell but the grid always opened at A1 and never wrote
the current scroll back. Sheets now open scrolled to their saved first
visible cell; saves record the current one (and the active cell) without
dirtying the workbook. Frozen panes use the pane's topLeftCell.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 21:11:23 +02:00
Brandon ThomasandClaude Opus 5.5 55d41eb13c Desktop theme watcher starts only in the desktop app, not in every SheetApp (tests, embedders) (review fix-up for #203)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 15:09:43 -04:00
Brandon Thomas 0bea7178a2 Merge branch 'land' into fix-203 2026-10-11 15:04:30 -04:00
Brandon ThomasandClaude Opus 5.5 04fb60ea5d Printing from the UI (Backstage, Ctrl+P, menu) goes through print_now, so the web build opens the browser's print dialog (review fix-up for #209)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 15:04:09 -04:00