Commit Graph
1496 Commits
Author SHA1 Message Date
Viorel ToaderandClaude Opus 5.5 43e64c50a2 Romanian: print settings and status, five form labels; Page Setup… matches its dialog
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JadgGo4G2GHaAMNb3qyygk
2026-10-21 10:57:20 +03:00
Viorel ToaderandClaude Opus 5.5 8e38fc21fa Romanian: feminine stângă/dreaptă for the margin labels
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JadgGo4G2GHaAMNb3qyygk
2026-10-21 10:57:20 +03:00
Viorel ToaderandClaude Opus 5.5 028a02ba72 Romanian (ro) interface language
Adds Romanian as an interface language: crates/ui-egui/src/i18n/ro.rs with 970 labels covering
every key of the other catalogs, registered in Language (switcher, app.language.set, ro-* system
locales). Context keys translate without their prefix; the File › Options kittest covers ro.
English formulas and formats; no proofing.

The catalog is an AI-assisted draft written from the meaning of the English labels; a native
speaker has not yet reviewed it line by line.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JadgGo4G2GHaAMNb3qyygk
2026-10-21 10:57:20 +03:00
Viorel ToaderandClaude Opus 5.5 29adb19872 Translate form-dialog field labels, choices and notes
Page Setup, Insert and the other form dialogs drew their field labels in
English in every interface language, though their titles and OK/Cancel
were translated and most catalogs already carry the labels.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JadgGo4G2GHaAMNb3qyygk
2026-10-21 10:57:10 +03:00
Gert Pellin a35d241caf XLSX: a note keeps its box's place and size through open and save (#1608)
The reader took only <x:Visible/> from a note's VML shape and vml_xml
wrote every note with a fixed anchor (two columns right of the cell,
four rows tall) and a 108 x 59.25 pt style, so a plain open and save
moved and resized every note box Excel had stored.

Comment gets an optional NoteBox: the <x:Anchor> corners relative to the
note's cell (so the box follows the note when rows or columns move) and
the shape's width and height. The writer puts it back, clamped to the
sheet; notes made here, and boxes equal to the default, keep the
default box.
2026-10-21 09:20:06 +02:00
chessiveandClaude Opus 5.5 a4a36e8460 Fonts: a cell font named in another language matches its installed font (fixes #1898)
Korean Excel saves a cell's font under its Korean name (맑은 고딕 for
Malgun Gothic), but the font scan kept one family name per face, the
English one, so those cells were drawn in the default face. Each face now
keeps its typographic and legacy family names in every language, and a
workbook font is bound under the name the workbook uses, which is the
name cell_family looks up. A name two families share goes to the family
whose English name it is, else to the first face by path, so the scan's
directory order no longer decides it. Names bound under two spellings
share one copy of the font data.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-21 14:45:39 +09:00
dantebertuzziandClaude Opus 5.5 68f956a410 Number Stored as Text: green indicator, warning button and Convert to Number (#1994)
Numbers stored as text are skipped by SUM and friends, and GridCraft gave
no hint. Like Excel's background error checking, a constant whose text
would be a number if typed now gets a green triangle in its top-left
corner; with such a cell active, a warning button beside it opens a menu
naming the problem with Convert to Number, which converts every flagged
cell in the selection as one undo step.

- core: `parse::number_stored_as_text` (signs, thousands separators,
  currency, percent, exponent, one parenthesised negative). Dates, times
  and fractions kept as text are not flagged, as in Excel.
- engine: `cmd::formulas::number_stored_as_text(cell)` (constants only,
  not formula results) and `formulas.convertToNumber {range?}`, which
  keeps each cell's format.
- ui: the triangle in the grid and the warning button with its menu;
  pt-BR and German strings.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 21:39:30 -03:00
dantebertuzziandClaude Opus 5.5 bdc0552a92 Dialogs: OK and Cancel in a row, so form dialogs fit their content
`ok_cancel` put the buttons in a right-to-left layout straight in the
window. That layout takes all the height it is offered, so every form
dialog (Greater Than…, New Name, Remove Duplicates, …) grew to the
screen's height with OK and Cancel floating halfway down. The buttons
now sit in a horizontal row as tall as they are.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 21:38:34 -03:00
dantebertuzziandClaude Opus 5.5 cacb620fec Paste Special: Excel's two-column layout, translated, Paste Link button
The dialog was a generic form: one column of fifteen radio buttons and
three check boxes, taller than the window, with English labels (the form
didn't run them through `tr`). It is now laid out as Excel's: Paste and
Operation each in two columns inside a frame, Skip blanks and Transpose
side by side under them, and Paste Link as a button that pastes
references to the copied cells at once. The letter shortcuts keep
working: the options still come from the dialog's fields.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 21:38:17 -03:00
Vedran DobosandClaude Opus 5.5 226c055fb7 fix(ui): Esc and Enter close a data validation alert, and the keyboard goes back to the entry (#2089)
A data validation alert is the general message box, drawn over the cell
editor, which stays open so the entry can be fixed. The editor read Enter and
Esc first: the first Esc cancelled the edit behind the alert and only the
second closed it, and Enter tried the entry again so the alert came back. The
editor now skips its own key handling while a message is open over it, so Esc
and Enter close the alert (like its OK button). The message box also had the
keyboard focus and didn't give it back, so typing went nowhere until the cell
was clicked; closing it now asks the open editor for focus again.

Tests: ui-egui tests/validation_alert.rs
esc_closes_a_validation_alert_and_leaves_the_entry and
enter_closes_a_validation_alert_and_leaves_the_entry (both fail on main, and
without the focus change).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-21 00:51:17 +02:00
dantebertuzziandClaude Opus 5.5 1788c5a771 Grid: paint the scrollbar's column beside the column headings
The vertical scrollbar's track starts below the column headings (and any
frozen rows), and nothing painted the bar's column above it, so dark mode
showed a white square at the top-right corner of the grid. The whole
column now takes the track colour.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 19:12:20 -03:00
dantebertuzziandClaude Opus 5.5 83a41dcd68 Right-click on a chart opens the chart's menu, not the cell's (fixes #2067)
The grid's right-click handler never hit-tested objects, so right-clicking
a chart opened the menu of the cell underneath it. And since any button's
drag start grabbed an object, a right press that moved a little started
dragging the chart and no menu opened at all.

Right-clicking a chart, picture, shape or slicer now selects it and opens
its own menu (Delete; for charts also Select Data… and Format Chart
Area…). Only the primary button moves objects.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 18:56:04 -03:00
Eduardo GarciaandClaude Sonnet 5.5 41cb19fd6d Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> 2026-10-20 18:39:49 -03:00
Eduardo GarciaandClaude Sonnet 5.5 eb30ab8f3f Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> 2026-10-20 18:39:49 -03:00
Mirza Bilal feac1679a1 HTML export: place pictures and charts at their anchors
Save as Web Page wrote only the cell table, so pictures and charts on a sheet
were dropped. A sheet that has either now keeps its own geometry and draws them:

- The table gets the sheet's column widths and row heights (`table-layout:fixed`,
  a `<colgroup>`, a height per row); hidden columns and rows take no room and
  merged-cell spans count only visible lines.
- A picture is an `<img>` with a `data:` URI, a chart is inline SVG built from
  the chart crate's drawing primitives (titles, axes, legends and data labels
  included), each absolutely positioned at its anchor cell plus offset.
- Sheets without pictures or charts write byte-identical HTML.

Adds contributors/people.toml entry for bilalmughal.
2026-10-21 01:35:58 +05:00
NetterSilverandClaude Haiku 5.5 f29ac7d9ef Use scientific notation when number_to_text rounds up to 1e15
Found while testing crates/core/src/value.rs:354-367

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-20 18:16:31 +00:00
Stefan FransenandClaude Fable 5.1 45c91ede21 i18n: Dutch (nl) interface language
Unify the Freeze family on "blokkeren" (Excel's Dutch wording).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-20 18:16:28 +02:00
Stefan FransenandClaude Fable 5.1 60e113bcd7 i18n: Dutch (nl) interface language
Adds a Dutch catalog (`i18n/nl.rs`, 518 labels) covering every key the
other catalogs translate: ribbon, context menus, File view, dialog
titles and the Options page. `nl-NL` and `nl-BE` locale tags resolve
to Dutch. Updates localization parity and the roadmap.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-20 18:10:09 +02:00
Harrison BoothandClaude Sonnet 5.5 ed48389c46 Formulas: compare right operands only after the left spine of a chain matches
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-20 08:38:12 -05:00
bfentyandClaude ad0ce61b8a fix(engine): strip one leading = when validating CF formulas
Co-Authored-By: Claude <noreply@anthropic.com>
2026-10-20 12:15:27 +00:00
bfentyandClaude 24ee1e4db7 fix(engine): count word-wrapped lines for automatic row height
Closes #1969

Co-Authored-By: Claude <noreply@anthropic.com>
2026-10-20 11:36:12 +00:00
quantmind-br bc58b2773a Document the functions this PR touches 2026-10-20 08:25:18 -03:00
RedBearAKandClaude Opus 5.5 4faa3ff098 Row auto-fit: count line breaks only in cells that wrap
auto_row_height grew a row for every line break in a cell's text whether
or not the cell wrapped. Excel counts breaks only when Wrap Text is on:
with it off a multi-line value displays on one line and AutoFit gives a
one-line row. A file whose unwrapped cells hold pasted multi-line text
(the shape generating libraries write) opened with tall rows and nothing
visibly tall in them.

The fast path no longer treats a line break as a reason to measure, and
the measuring path lays text out over lines only for a wrapping cell.
Typing a break still turns wrap on (the Alt+Enter rule in cell entry) and
grows the row, as before.

Test: an unwrapped multi-line cell from a file keeps the default height
on open; wrap on grows the row; wrap off returns it; a typed break wraps
and grows. The open-time fit tests from #833 are unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 22:45:22 -08:00
icsimpiantiandClaude Opus 5.5 4e17be1929 Merge upstream main into italian-translation
Resolve the docs/localization-parity.md conflict: upstream header, both history rows kept.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 08:39:09 +02:00
kezmdorandClaude Opus 5.5 cfb0e186ed Formula entry: an incomplete formula's error describes what was typed (fixes #2030)
`=1+` reported "unexpected `)`", although no `)` was typed: entry closes
missing parentheses by appending up to eight `)`, and when every retry
failed it reported the last retry's error. It now reports the error of
the formula as typed ("unexpected end of formula").

`gridcraft_formula::parse_closing_parens` holds the convenience and takes
the parse function, so cell entry and the UI's Spanish formula path share
it instead of each having its own loop.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 07:44:09 +02:00
Mouhand-Kaddo 189eb7ae52 M12.AR14: keep the theme's per-script typefaces (<a:font script="Arab">) on save 2026-10-20 09:21:42 +04:00
bmh129andClaude Opus 5.5 132e887efa Linux: time out the desktop theme's portal read
The theme watcher (DesktopTheme) reads the desktop's light/dark choice
from the XDG Desktop Portal over a blocking D-Bus call with no timeout.
zbus waits forever by default, so a portal that accepts the call and
never answers stalled the watcher's thread on its first read, and "Use
system setting" stopped following the desktop for the rest of the
session, even after the portal recovered.

The session connection is now built with a 2 s method timeout (REPLY,
shorter than the 4 s POLL). A timed-out call returns InputOutput, which
read() already handles by dropping the connection, so the next poll
asks again on a fresh one.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0115HyvML9WnuFRdmtMcLP5t
2026-10-19 23:45:59 -05:00
midasdf ad32e6a847 i18n(ja): translate every dialog, message and menu string the pt-BR catalog covers
The Japanese catalog still lived inline in i18n.rs with its ribbon and widget
labels, so with the interface set to 日本語 the dialog titles and labels, message
boxes, Backstage/File-view items, template names and native menus showed in
English. This moves it to i18n/ja.rs and adds the 545 keys the Brazilian
Portuguese catalog translates beyond it: 943 keys, the coverage pt-BR has
(~43% of ~2,200 strings), in Excel for Mac 日本語版 wording.

CORE keeps the shared reference set every catalog covers, verbatim and in the
same order (the cross-catalog coverage test still points at it); DIALOGS holds
the new strings, and the lookup checks it first. One test parses pt.rs's source
so the two catalogs cannot drift apart again, one checks that every key is
unique across the two lists and every value is translated, and one spot-checks
the high-value strings.

Docs: the Japanese row and the "Where we are" bullet in
docs/localization-parity.md (943, ~43%), a revision row, the ROADMAP Languages
paragraph and progress log, and gaps.md §11.
2026-10-20 13:45:17 +09:00
midasdf 40803e6aca XLSX: keep Japanese phonetic runs (ふりがな) on open and save
xl/sharedStrings.xml can carry phonetic runs (<rPh sb="0" eb="2"><t>ふりがな</t></rPh>)
and a <phoneticPr> beside a string item. GridCraft read only the text and wrote every
string back as <si><t>…</t></si>, so a plain open + save deleted a Japanese workbook's
furigana.

Both are now read — offsets validated against the base text, runs with bad or missing
offsets, sb >= eb or no reading dropped with a warning, and never used to index — and
kept on the workbook as Workbook::phonetics, one entry per string text. The writer
emits them next to the <si> of the same text. The saved table holds each text once, so
two identical texts cannot keep two different readings: the reader keeps the first and
warns. Strings without phonetic data are written byte for byte as before.

Behaviour reference: ISO/IEC 29500-1 §18.4.6 rPh and §18.4.7 phoneticPr (Microsoft
Learn PhoneticRun/PhoneticProperties). Tests: crates/xlsx/src/tests/phonetic_tests.rs
(round trip, plain string, hostile offsets, shared text, unused data, comments and
inline strings). Docs: file-format-parity.md, localization-parity.md.
2026-10-20 13:39:48 +09:00
midasdf 2c6ffe489c XLSX theme: keep the major/minor ea and cs typefaces through open + save
A theme's <a:fontScheme> carries latin, ea (East Asian) and cs (complex
script) typefaces for each of the major and minor fonts. The model held
only the latin ones and the writer emitted <a:ea typeface=""/> and
<a:cs typeface=""/> unconditionally, so a Japanese workbook's theme fonts
(e.g. 游ゴシック, MS Pゴシック) were silently deleted on open + save.

Theme gains major_font_ea, minor_font_ea, major_font_cs and
minor_font_cs (#[serde(default)], so older GridCraft JSON still loads;
empty means the file did not set one). The XLSX reader and writer
round-trip them escaped, and a theme without them writes exactly the
empty attributes it wrote before.

Rendering and font resolution are unchanged: the UI does not consume ea
yet, and wiring it in is a follow-up.
2026-10-20 13:35:52 +09:00
bfentyandClaude 8ff06e215e fix(engine): reject unparseable conditional-format formulas at creation
Closes #1999

Co-Authored-By: Claude <noreply@anthropic.com>
2026-10-20 02:48:58 +00:00
jonathanwxh-cell fc1d629cc5 fix: merge current main into hidden-sheet navigation repair 2026-10-20 10:44:49 +08:00
bmh129andClaude Opus 5.5 27760812de i18n: test that translations keep the shape of their English
The French catalog once shipped with over a hundred translations sitting
on their neighbours' keys ("Close" read "Société"); main has since fixed
them. A catalog shifted that way still covers every key, so the existing
coverage tests don't catch it.

A new test checks every language's translations keep the shape of their
English: the same {placeholders}, and no line break in a one-line label
(the two big ribbon buttons that wrap are exempt). Plus spot checks of
French labels that were once misplaced.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 21:38:08 -05:00
Lord-Taw 479d1b4b66 Update i18n.rs
´cargo fmt --check´ OK
2026-10-19 23:20:02 -03:00
Harrison BoothandClaude Sonnet 5.5 199e5f8e05 Formulas: test the order walk and map visit nodes; date ROADMAP like the parity doc
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-19 20:56:26 -05:00
Lord-Taw edd6e0cbe8 Atualizar o i18n.rs 2026-10-19 22:27:15 -03:00
Eduardo GarciaandClaude Sonnet 5.5 52ab0e6bfb #1458: formula round-trip test for Excel's sheet-name quoting
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-19 20:55:52 -03:00
Harrison BoothandClaude Sonnet 5.5 b3e0a7e8d3 Formulas: count the leftmost operand of a chain at the same depth
The left end of a flat operator chain is not nesting, so (((...1)))+1 is
accepted whenever (((...1))) is, in Spanish entry and display.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-19 18:54:30 -05:00
Harrison BoothandClaude Opus 5.5 2aeb21d4d3 Formulas: flat operator chains as long as Excel allows (#916)
along: =1+1+... with 4,096 operands (8,192 characters, exactly Excel's
limit, which Excel accepts and calculates) overflowed the stack when
entered, because the derived Clone of Expr recursed once per operand
down the chain's left spine. Saving hit the same in the XLSX writer.

- Expr: Clone, PartialEq, walk and map follow the left spine in a loop
  and recurse only into right operands and real nesting.
- XLSX: _xlpm. prefixing and the implicit-intersection scan follow the
  spine too. The scan's depth limit of 64 wrote any chain of more than
  about 64 operands as a dynamic-array formula; such sums are plain
  formulas again (ranges in the chain still get array evaluation).
- Evaluate Formula borrows sub-expressions instead of cloning each
  operator's subtree (quadratic memory on a long chain).
- Spanish formula entry and display no longer refuse chains of more
  than 256 operands; the left spine does not count as nesting.

Tests run on a 1 MiB stack (the Windows main thread) with Excel's
observed results: formula (clone/eq/walk/map/adjust at 4,096), calc
(401 and 4,096 operands, -, *, /, ^, &, %, comparisons, 1,500 refs),
xlsx (long chains written as scalar formulas), engine (cell.set, fill,
copy/paste, insert rows/columns, undo/redo, Evaluate Formula, XLSX save
and reopen), Spanish entry. Each fails without the fix.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 18:54:30 -05:00
vangel76 d9d4d64645 PR1372: merge main and preserve quote-prefix and CSV regression tests 2026-10-20 00:56:41 +02:00
Eduardo GarciaandClaude Sonnet 5.5 0b4cc5618f fix #1458: one Excel sheet-name quoting rule for formulas, pivot sources and ADDRESS
Sheet names starting with '.' or reading as R1C1 (R, C, RC, R1C1...) were saved
unquoted, so Excel could not open the file; PivotTable sources and ADDRESS left
cell-like names (A1) bare. The quoting rule, unquoting and sheet splitting now
live once in gridcraft_core::addr and replace the copies in the formula printer,
pivot, ADDRESS, chart, xlsx, Solver, Go To and the Name Box (which now reads ''
as ').

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-19 17:36:40 -03:00
MarekSpodBiedry 026239458a Formula editing: arrow pointing restarts from the edited cell after typing (#1949) 2026-10-19 22:27:34 +02:00
Maciej Malinowski a74e82ac93 formula: same_name folds case without merging ı and i
Lower-casing then upper-casing made dotless ı equal to i (both become I),
which Unicode's default case folding keeps apart; LET(i,1,ı,2,i) could
return the ı binding. same_name now lower-cases and adds the folds lower
case misses (ß/ẞ -> ss, ſ -> s, ς -> σ). Tests cover ı/i and the Greek
final sigma.
2026-10-19 22:27:21 +02:00
bfentyandClaude 122d3d9a31 feat(formula): Spanish aliases for financial functions (VNA, TIR, PAGO, VA, VF)
Closes #1986

Co-Authored-By: Claude <noreply@anthropic.com>
2026-10-19 20:14:24 +00:00
Maciej Malinowski 553b0bd9f2 ui: language command docs and error list every language
app.language.set's engine.commands docs and its unknown-language error
were written by hand and had fallen behind: the docs missed es, fr and
sr, the error missed de, fr and sr. Both are now built from
Language::ALL (Language::code_list), and tests check every language is
listed in each.
2026-10-19 21:49:23 +02:00
bfentyandClaude 871c4e6c8f perf(engine): scan only the precedent area's stored cells
iter_range walks the sparse store's bands for the area's row range
only, so a chain of N formulas no longer rescans every stored cell of
the sheet per area.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-10-19 19:47:07 +00:00
Maciej Malinowski e9bcb8dfbb calc: one shared same_name for LET/LAMBDA names, with case folding
- gridcraft_formula::same_name lower-cases then upper-cases each
  character, so ß matches ẞ (to_uppercase alone maps ß to SS).
- Formula-bar input uses it too, so a binding such as ſi is not
  translated to IF while the evaluator binds it.
- Tests: ISOMITTED with a case variant, ß/ẞ, and the Spanish input case.
2026-10-19 21:46:10 +02:00
bfentyandClaude 9f13434972 fix(ui): label sort columns from the region start, seed unused level columns
- The region already starts at the header row when headers are on, so
  the dropdown label reads start.row for both cases (was showing the
  first data value, e.g. B: 30 instead of B: Revenue).
- + Add Level picks the first region column no level uses yet instead
  of columns.get(levels.len()), which re-seeded an already-used column.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-10-19 19:40:46 +00:00
Maciej Malinowski ac371be50d calc: LET and LAMBDA names ignore case in any script
Excel matches LET and LAMBDA names case-insensitively in every script,
so =LET(dług,100,DŁUG*2) is 200. The evaluator compared them ASCII-only
and returned #NAME?. The three lookups (name evaluation, ISOMITTED, a
LET variable shadowing a function name) now fold Unicode case.
2026-10-19 21:15:00 +02:00
bfentyandClaude e34b0aa345 fix(ui): persist the AutoSave preference across restarts
Closes #1901

Co-Authored-By: Claude <noreply@anthropic.com>
2026-10-19 19:07:18 +00:00