Commit Graph
446 Commits
Author SHA1 Message Date
Marco Arnulfo 0033dfcdeb Keyboard: Ctrl+Shift+A after a function name inserts its argument names 2026-10-16 06:24:36 +02:00
Marco Arnulfo f3398ee218 Grid: a scrolled Table's header names and filter buttons in the column headings (#1423) 2026-10-16 04:27:49 +02:00
Marco Arnulfo 706127402a XLSX: keep header and footer pictures on save (part of #1257) 2026-10-16 02:48:25 +02:00
Marco Arnulfo 79e8973c30 Web: keep preferences such as dark mode between visits (fixes #1562) 2026-10-16 01:35:02 +02:00
NetterSilverandClaude Haiku 5.5 d50e32bf25 Docs: put the new sentence in the Fidelity / notes column
Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-15 21:27:55 +00:00
NetterSilver 9f6bd5848c Docs: update the progress docs for this change 2026-10-15 20:17:42 +00:00
Nihilist NarwhalandClaude Opus 5.5 82ee02aac4 Formula parser: Excel's 8,192-character limit and postfix nesting (never crash) (#1330)
A hostile file could abort any process that opens it: a cell formula of a
million `%` (`1%%%…`) or a 200,000-term sum parsed into trees deep enough to
overflow the stack when printed, saved, evaluated or dropped, even in release
builds. Postfix operators (`%`, invoking a result) built their nesting in a
loop that the 256-level limit did not see.

- `parse` refuses formula text longer than Excel's 8,192 characters
  (`MAX_FORMULA_LEN`, counted in characters, the leading `=` excluded). This
  also bounds the depth of the left-deep trees long operator chains build.
- Each postfix `%` and each call of a result counts towards the nesting limit.
- A file's formula that is refused keeps its text and cached value, as other
  unparsable formulas do.

Regression tests: formula (small-stack thread: long `%`, invoke and operator
chains are errors; the limit counts characters, not bytes) and xlsx
(`hostile_formula_text_does_not_overflow_the_stack`: open, save and drop a
workbook with such formulas and a defined name on a 1 MiB stack). Both abort
with a stack overflow without the fix.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 13:39:28 -06:00
Harrison O'Connor-Hoover 79e85c1b80 fix(edit): recalculate every cell changed by large clears (#1032) (#1128) 2026-10-15 13:38:13 -06:00
quantmind-br 47268a42af UI: function help follows the interface language
The argument hint, autocomplete, Insert Function and the Formulas-tab menus
read per-language tables of function descriptions and argument names
(i18n/<lang>_functions.rs), keyed by the catalog's English text and
binary-searched. The hint is assembled from the formula syntax's function
name and separator plus the language's argument names, all of them or none,
so it never mixes two languages. Insert Function searches the translated
descriptions and shows readable category names. SPANISH_HELP moves to
es_functions.rs with its 10 functions.
2026-10-15 10:49:13 -03:00
justinjohn0306 b930d60bc3 #1505: keep scalar INDEX MATCH formulas scalar 2026-10-15 18:32:00 +05:30
adrdsouza 7f9f73d6ba fix(numfmt): share legacy colors across grid and PDF rendering 2026-10-15 16:10:07 +05:30
derechopiano 9097170b08 XLSX: preserve carriage returns in saved text 2026-10-15 10:33:57 +01:00
wstock 45644d3f43 Control channel: ui.dialog.confirm sends what OK sends (#1459)
OK runs a dialog's command with build_params(&d), which reshapes the
field values for several dialogs (the rule wrapper of cfQuick, the
delimiters list of Text to Columns, the columns of Remove Duplicates and
Subtotal, Data Validation's unused fields, Zoom presets, Series, Define
Name). ui.dialog.confirm passed the raw field values instead, so a
Highlight Cells rule confirmed over the control channel added nothing
and Text to Columns ignored the ticked delimiter.

Make build_params pub(crate) and use it from ui.dialog.confirm, say so
in the control protocol doc, and add tests driving the Greater Than and
Text to Columns dialogs over the control channel.
2026-10-15 07:06:31 +00:00
icsimpiantiandClaude Opus 5.5 2d4a537c6a i18n: add Italian (it) UI translation
Adds Language::It ("it", native name "Italiano") with a new per-language
module crates/ui-egui/src/i18n/it.rs, following the existing pattern
(translate(text) -> Option<&'static str>). The catalog has 971 entries:
every key the most complete catalog (pt) translates, plus the PivotTable
Fields pane strings (from es) and Options|Editing. Labels follow Excel's
Italian terminology (Foglio, Cartella di lavoro, Blocca riquadri, Unisci e
allinea al centro, Somma automatica...). Function names are not touched.

Also: it / it-IT / it_CH tags resolve to Italian (system-language default),
Language::ALL and the coverage/tag/age tests include Italian, and
docs/localization-parity.md lists the new language.

Not compiled locally (no Rust toolchain on the author's machine); relying on CI.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 08:52:36 +02:00
euisuhandOpenAI Codex 370b220834 fix(solver): commit solutions and reports atomically
Prepare report data before editing so refused reports cannot leave solution cells or the saved model changed. Commit accepted reports with the optional solution and model, retaining array/protection checks and row autofit after sheet insertion.

Closes #1050

Co-Authored-By: OpenAI Codex <noreply@openai.com>
2026-10-15 15:23:19 +09:00
Camthalion77 4d68300bc2 Add Greek (el) localization 2026-10-15 08:31:40 +03:00
derechopiano be20ca163d UI: keep PivotTable field-list scrollbar at pane edge 2026-10-15 04:13:02 +01:00
Harrison BoothandClaude Opus 5.5 7ee11fe137 XLSX: keep dynamic-array cell metadata (cm) on save
A formula read with `cm` (Excel's XLDAPR dynamic-array record in
xl/metadata.xml) now carries `Formula::dynamic`, and the writer keeps the
`cm` and the metadata part for it even when the formula returns one value
and the export shape analysis would not need array evaluation. Before, such
formulas were saved as legacy formulas, so Excel recalculated some of them
with implicit intersection (SUMPRODUCT(IFERROR(range/range,0)) changed
value), and workbooks whose every dynamic formula was scalar lost
xl/metadata.xml altogether.

The mark survives moves, row and column insertion or deletion, sheet and
name renames and LAMBDA call-case fixes; retyping a formula drops it and
the writer decides from the formula's shape, as before. It is serialized
only when set, so saved documents without it are unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 19:05:03 -05:00
Harrison BoothandClaude Opus 5.5 ced7243234 calc: bounded references up to 1,048,576 cells keep their full shape (#1010)
A reference over 16,384 cells was cut to the sheet's used range when it was
read into an array. Next to a full-size operand the two no longer lined up:
SUMPRODUCT(D3:AZ400*B3:B400,(A3:A400=1)*(D1:AZ1=2)) gave #VALUE!,
D3:AZ400*B3:B400 filled with #N/A, and ROWS, COUNTBLANK and --(r="") lost
the blanks past the data. Excel keeps the reference's size.

Bounded references now keep their full shape up to one column's worth of
cells (1,048,576). References that run to the edge of the sheet (A:A,
A2:A1048576, several whole rows) and larger blocks still stop at the used
range, so whole-column formulas stay fast.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 17:36:36 -05:00
Pranav Chandra 3177fbe03f ui: show spill-cell formula as greyed out 2026-10-14 20:23:44 +05:30
derechopiano 78ffd3b4c3 fix(pdf): preserve exported links and allow CLI PDF conversion (#954) 2026-10-14 13:40:16 +01:00
derechopiano 72db972de3 fix(engine): bound Undo history by retained cell storage (#1227) 2026-10-14 08:23:57 +01:00
Marco Arnulfo 89439636d8 Dialogs move by their title bar instead of staying pinned to the centre (fixes #1250) 2026-10-14 08:08:41 +02:00
allenyllee 938097f5b6 I1231: load Flatpak host fonts for native CJK fallback 2026-10-14 11:44:01 +08:00
Marco Arnulfo 9f11e26e78 Journal: cap by serialized size and keep a recording's start through trims (part of #1228) 2026-10-14 05:10:19 +02:00
jonathanwxh-cell 18092672ee #701: integrate hidden-sheet navigation with current main 2026-10-14 00:01:18 +08:00
ZaxaerithandCodex 2b53301092 fix(grid): keep cursor stable during cell dragging (#936)
Co-Authored-By: Codex <noreply@openai.com>
2026-10-13 23:14:56 +08:00
Lexx143andClaude Fable 5.1 209d2447d9 Charts: multi-level category axes, read, drawn and written back
A category range two or more columns wide beside a column of values (year beside month, Excel's
multiLvlStrRef) was read as one flat list: 36 rows in two columns became 72 categories, the
series sat in the left half of the plot and the years and months shared one row of labels.
Saving wrote the range as a plain strRef, so Excel lost the two-level axis too.

- gridcraft_core::category_levels: the shape of a category range beside its values (levels are
  columns when the points run down the rows, rows when they run along the columns; up to three
  outer levels), shared by the chart and xlsx crates.
- ChartData.category_levels: the outer levels, nearest the labels first, one entry per category,
  non-empty where a group starts. resolve fills it; a single column is unchanged.
- render: the outer levels in rows under the labels, a group's name centred under its categories
  with a separator at each boundary; in bar charts in columns beside the labels.
- xlsx: <c:cat> written as multiLvlStrRef with the level caches (innermost first), so the axis
  survives a round trip.

Tests in core (shapes), chart (resolve and layout for columns, bars and a row of values) and
xlsx (written XML, read-back, stability, a single column stays strRef). chart-parity, gaps § 4
and the ROADMAP progress log updated.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-13 17:30:01 +03:00
NetterSilver dcef8f12b2 Docs: update the progress docs for this change 2026-10-13 16:02:06 +02:00
quantmind-br 482c3e9481 Engine: formulas.evaluate refuses what cell entry refuses, saying why
`formulas.evaluate` (behind `gridcraft-cli eval` and MCP's `evaluate_formula`) turned any
formula that didn't parse into #NAME?, so `=SUM(1;2)` looked like an unknown function. It now
parses the way `cell.set` does (missing closing parentheses are added) and returns the same
errors: "There's a problem with this formula: expected `,` or `)`, found Semicolon", or the
wrong-argument-count message. An unknown function still evaluates to #NAME?, as in Excel.
2026-10-13 09:38:41 -03:00
pourie-he c05285e181 UI: support Command and Shift clicks in formula pointing 2026-10-13 23:12:38 +11:00
Marco Arnulfo 4d5360fd90 Sheet tabs: Ctrl-drag (Cmd or Option on macOS) drops a copy of the sheet (fixes #971) 2026-10-13 12:21:52 +02:00
Marco Arnulfo 3272097e15 Control: Go To and Select over the control channel scroll the active cell into view (fixes #966) 2026-10-13 12:02:55 +02:00
Anirudh Sharma 8f9338a5ec fix(fill): respect workbook date system in monthly autofill 2026-10-13 14:21:00 +05:30
Marco Arnulfo f644004cc6 Sheet tabs: New sheet (+) right after the last tab, the strip capped at 60% (part of #943) 2026-10-13 10:35:14 +02:00
Brandon ThomasandClaude Opus 5.5 589b59defc Docs: one Last updated line per doc after the merges
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 02:02:41 -04:00
Brandon ThomasandClaude Opus 5.5 a8cd6f4b63 Drop the planning notes from the PR
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 01:52:12 -04:00
Brandon Thomas ebe0138d30 Merge main into #855
# Conflicts:
#	ROADMAP.md
#	docs/gaps.md
#	docs/target-app-parity.md
2026-10-13 01:52:08 -04:00
Brandon Thomas 08cbb69585 Merge main into #463
# Conflicts:
#	docs/ui-parity.md
2026-10-13 01:40:00 -04:00
Brandon Thomas 80d282e7a5 Merge pull request #752 from marcoarnulfo:fix/function-excel-diffs-738 2026-10-13 01:39:44 -04:00
Marco Arnulfo d0d4d26c74 UI: File › Account shows the version, platform and licence, with an About GridCraft button (fixes #896) 2026-10-13 07:12:34 +02:00
Brandon Thomas 4536bc7fc8 Merge main into #849
# Conflicts:
#	crates/ui-egui/src/grid.rs
#	crates/ui-egui/src/tabs.rs
#	docs/ui-parity.md
2026-10-13 01:07:17 -04:00
Brandon Thomas 3c4556bb04 Merge main into #856
# Conflicts:
#	ROADMAP.md
#	crates/model/src/lib.rs
#	crates/xlsx/src/tests/passthrough_tests.rs
#	docs/file-format-parity.md
2026-10-13 00:52:57 -04:00
Bryan MarkandClaude Opus 5.5 b112b56424 Merge branch 'main' into recent-modified
Brings the branch up to upstream's main (180 more commits). One conflict,
and one thing the merge needed that was no conflict:

- docs/ui-parity.md: every line of both sides is kept, as upstream's own
  merges keep them (its heading has three lines now); this change's
  heading line and history row come first.
- crates/ui-egui/src/i18n/pt.rs: upstream's Portuguese catalog gained a
  "Yesterday" of its own, with the same word ("Ontem"). The one this change
  added is left out: a second arm for the same text is unreachable.

Gate: all eight steps, 1548 tests.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 13:50:13 +09:00
Brandon Thomas fe26486eb5 Merge main into #690
# Conflicts:
#	crates/ui-egui/src/grid.rs
#	docs/ui-parity.md
2026-10-13 00:48:41 -04:00
Marco Arnulfo ca8fc73281 Merge remote-tracking branch 'origin/main' into fix/function-excel-diffs-738
# Conflicts:
#	crates/calc/src/eval.rs
2026-10-13 06:29:34 +02:00
Brandon Thomas 2174db2006 Merge main into #871
# Conflicts:
#	docs/cli.md
2026-10-13 00:09:07 -04:00
Brandon Thomas 94ee7efdf9 Merge main into #853
# Conflicts:
#	ROADMAP.md
#	docs/file-format-parity.md
2026-10-13 00:08:58 -04:00
Brandon Thomas a67b5d2960 Merge main into #794
# Conflicts:
#	ROADMAP.md
#	docs/gaps.md
#	docs/ui-parity.md
2026-10-13 00:08:22 -04:00
Brandon Thomas 167ba9b370 Merge main into #788
# Conflicts:
#	docs/localization-parity.md
2026-10-13 00:08:18 -04:00