Commit Graph
273 Commits
Author SHA1 Message Date
Brandon Thomas ea3e0ce0c5 Merge pull request #355 from LloydNicholson/fix/journal-redact-passwords
Journal: sheet protection passwords aren't recorded in plain text

# Conflicts:
#	crates/engine/src/tests.rs
2026-10-11 12:04:12 -04:00
Brandon ThomasandClaude Opus 5.5 2f6c2cd486 Fix-up: Spanish and German strings for Interface size (#294 met #242/#271); rustfmt after merges
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 11:59:24 -04:00
Brandon Thomas 4f7144d753 Merge pull request #295 from vangel76/feat/view-formula-bar-zoom100
View: Formula Bar and Zoom 100% as engine commands (#289)

# Conflicts:
#	ROADMAP.md
#	crates/ui-egui/src/control.rs
#	crates/ui-egui/src/lib.rs
#	docs/target-app-parity.md
2026-10-11 11:45:32 -04:00
Brandon Thomas 8f3d13a115 Merge pull request #294 from vangel76/fix/interface-scale
View: Interface size preference scales the whole window (#230)

# Conflicts:
#	ROADMAP.md
2026-10-11 11:45:01 -04:00
Brandon Thomas 505d001ad4 Merge pull request #293 from vangel76/fix/name-manager-new
Name Manager: New… and Edit… open the name dialog and return to the manager (#238)

# Conflicts:
#	crates/engine/src/tests.rs
2026-10-11 11:45:00 -04:00
Brandon Thomas fb9266f479 Merge pull request #271 from arekown/german-translation
Add German (de) interface language

# Conflicts:
#	ROADMAP.md
#	crates/ui-egui/src/i18n.rs
2026-10-11 11:44:58 -04:00
Brandon Thomas ea0e971e27 Merge pull request #228 from webdevtodayjason/fix/200-formula-helpers
Keep formula helpers inside the worksheet when scrolling (#200)

# Conflicts:
#	contributors/people.toml
#	docs/ui-parity.md
2026-10-11 11:44:56 -04:00
Brandon Thomas a1f97c2f06 Merge pull request #218 from MarekSpodBiedry/issue-190
Resize charts from the corner handle and the Size fields, keep typed chart and table names (#190)
2026-10-11 11:44:55 -04:00
Brandon Thomas 0a65ffc31a Merge pull request #219 from Zarvinx/fix-keyboard-chart-delete
Delete selected charts with the keyboard

# Conflicts:
#	ROADMAP.md
2026-10-11 11:44:53 -04:00
Brandon Thomas ad8aeca851 Merge pull request #217 from MarekSpodBiedry/issue-198
Do not draw the selection over the frozen pane when it lies only in the scrolling pane (#198)
2026-10-11 11:44:51 -04:00
Brandon Thomas 90dcc2b329 Merge pull request #297 from vangel76/feat/trimrange
Functions: TRIMRANGE (#296)

# Conflicts:
#	README.md
#	ROADMAP.md
#	crates/xlsx/src/tables.rs
#	docs/function-parity.md
#	docs/gaps.md
#	docs/target-app-parity.md
2026-10-11 11:44:50 -04:00
Brandon Thomas c2c381d55d Merge pull request #292 from vangel76/feat/bahttext
Functions: BAHTTEXT (#291)

# Conflicts:
#	README.md
#	ROADMAP.md
#	docs/function-parity.md
#	docs/gaps.md
#	docs/target-app-parity.md
2026-10-11 11:44:48 -04:00
Brandon Thomas fa4d2e5741 Merge pull request #280 from vangel76/feat/percentof-euroconvert
Functions: PERCENTOF and EUROCONVERT (#279)

# Conflicts:
#	README.md
#	ROADMAP.md
#	crates/functions/src/financial.rs
#	docs/function-parity.md
#	docs/gaps.md
#	docs/target-app-parity.md
2026-10-11 11:44:46 -04:00
Brandon Thomas f91f7bc154 Merge pull request #276 from vangel76/feat/odd-bond-functions
Functions: ODDFPRICE, ODDFYIELD, ODDLPRICE, ODDLYIELD (#275)

# Conflicts:
#	ROADMAP.md
2026-10-11 11:43:49 -04:00
Brandon Thomas 59deadc4c3 Merge pull request #285 from vangel76/fix/currency-paste
Clipboard: pasted currency cells keep the number from the clipboard HTML (#257)
2026-10-11 11:43:48 -04:00
Brandon Thomas 96703b79d4 Merge pull request #278 from vangel76/fix/fill-handle-ctrl-series
Fill handle: Ctrl+drag swaps copying and extending a series (#264)

# Conflicts:
#	ROADMAP.md
2026-10-11 11:43:47 -04:00
Brandon Thomas 4ea12e967b Merge pull request #242 from diegozpy/i18n/es-interfaz
i18n: Spanish interface translation (the Español option only localized formulas)
2026-10-11 11:42:40 -04:00
Brandon Thomas f6628954fc Merge pull request #263 from alexanderalber/fix/201-filter-header-row
AutoFilter: a selected header row filters the data below it; search box in the filter menu (#201)
2026-10-11 11:42:38 -04:00
Brandon Thomas 3b0da1d760 Merge pull request #254 from nihilist-narwhal/fix-typed-dates-and-times
Typed dates before 1900 stay text; typed times past 24 hours keep their hours
2026-10-11 11:42:37 -04:00
Brandon Thomas 77e6a4a46d Merge pull request #251 from nihilist-narwhal/fix-conditional-format-layers
Conditional formatting: apply every matching rule; Cell Value rules as in Excel
2026-10-11 11:42:36 -04:00
Brandon Thomas 47dcd84e04 Merge pull request #282 from vangel76/fix/name-box-enter
UI: Name Box Enter goes to the typed cell, not the one below (#247)
2026-10-11 11:24:39 -04:00
Brandon Thomas 331a535d3c Merge pull request #277 from vangel76/fix/linux-font-panic
UI: skip system fonts egui can't parse instead of panicking at startup (#226)
2026-10-11 11:24:38 -04:00
Brandon Thomas c97f025459 Merge pull request #248 from MacJedi42/fix/excel-15-digit-display
Accuracy: round an exact tie at the 16th significant digit toward zero
2026-10-11 11:24:37 -04:00
Brandon Thomas 85f0320f5c Merge pull request #267 from alexanderalber/fix/64-write-at-as-single
XLSX: write `@` as `_xlfn.SINGLE` in a dynamic-array formula (#64)

# Conflicts:
#	crates/xlsx/src/tests/roundtrip.rs
2026-10-11 11:24:36 -04:00
Brandon Thomas 1eb7796724 Merge pull request #262 from alexanderalber/fix/235-icon-set-cfvo
XLSX: write one cfvo per icon in icon-set rules (#235)

# Conflicts:
#	contributors/people.toml
2026-10-11 11:24:22 -04:00
Brandon Thomas aa7c97adb9 Merge pull request #255 from nihilist-narwhal/fix-sort-and-duplicates
Sort and Remove Duplicates: compare text the way Excel does
2026-10-11 11:24:00 -04:00
Brandon Thomas d059a5b5a4 Merge pull request #252 from nihilist-narwhal/fix-choose-array-index
CHOOSE: pick element by element when the index is an array
2026-10-11 11:23:59 -04:00
Brandon Thomas 46cd4d7b72 Merge pull request #250 from nihilist-narwhal/fix-criteria-blank-cells
Criteria: text patterns don't match blank cells
2026-10-11 11:23:58 -04:00
Brandon Thomas e1939aac68 Merge pull request #272 from ttrudging/fix/paste-deadlock
Fix Paste button deadlock in ribbon
2026-10-11 11:23:32 -04:00
Brandon Thomas 96af804cb5 Merge pull request #223 from Dejan-Port/fix-web-edit-loss
fix: Save toolbar button and saveChanges dialog discard an in-progress cell edit
2026-10-11 11:23:30 -04:00
Brandon Thomas 1cd3d4af5d Merge pull request #231 from pkibiego/security/quick-xml-0.41
XLSX: bump quick-xml 0.38 -> 0.41 (RUSTSEC-2026-0195 namespace-declaration DoS)
2026-10-11 11:23:29 -04:00
lloydandClaude Opus 5.5 c1a500c5b9 Journal: leave sheet protection passwords out
Protect Sheet and Unprotect Sheet were journaled with their `password`
param, so the password showed in plain text in the journal dialog and
`engine.journal`, and a recorded script (Automate > Record Actions)
saved it in the workbook's hidden `_sc_scripts` name.

Session::execute now journals the params without secret ones
(`password`, or a name ending in `Password`). A replayed entry runs
without that param: Protect Sheet protects with the same options but no
password, and the matching Unprotect Sheet still succeeds.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 17:17:30 +02:00
vangel76andClaude Opus 5.5 52921512c7 Functions: TRIMRANGE (#296)
Evaluator special form returning the range (or array) without its blank
outer rows and columns; trim codes 0-3 as documented; written as
_xlfn.TRIMRANGE. The trim-reference operators are not parsed yet.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 12:11:25 +02:00
vangel76andClaude Opus 5.5 be028cc6cc View: Formula Bar and Zoom 100% as engine commands (#289)
- view.zoom100 sets the active sheet's zoom to 100% (the ribbon's 100%
  button runs it).
- view.formulaBar {on?} toggles a formulaBar preference (Prefs, saved in
  prefs.json on desktop; an application option, not in the file). The UI
  shows the formula bar from it; the ribbon checkbox, native menu and
  ui.set {formulaBar} go through the command.
- The UI-only interceptions and their entries in engine.commands are gone,
  so the CLI and MCP can run both. Parity checklist regenerated (260 / 290).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 12:09:30 +02:00
vangel76andClaude Opus 5.5 14ad23044a View: Interface size preference scales the whole window (#230)
UiState gains interfaceScale (percent, 100 = Auto, 75–200), saved in
ui.json and applied as egui's zoom factor on top of the desktop scale.
New UI command view.interfaceScale {percent | "auto"} clamps hostile
values; a malformed saved value reads as 100. View tab gets an
"Interface size" picker. egui's built-in keyboard zoom is turned off so the
preference owns the zoom.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 12:09:29 +02:00
vangel76andClaude Opus 5.5 a11446f2f0 Name Manager: New… and Edit… open the name dialog and return to the manager (#238)
dialogs::show put the Name Manager back into app.dialog after its body
had opened the New Name dialog, so New… did nothing. A dialog opened from
another one now takes over and the opener waits behind it (back), coming
back when the child closes; Go To still hands over to Go To Special.

The Name Manager gets Excel's New…/Edit…/Delete buttons over a selectable
list. formulas.defineName takes oldName/oldScope to edit a name in place;
a renamed name is renamed in cell formulas and other names' definitions.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 12:09:19 +02:00
vangel76andClaude Opus 5.5 35d6c23fd1 Functions: BAHTTEXT (#291)
Thai number words with บาท / สตางค์ / ถ้วน, rounded to satang, ล้าน
repeating per six digits, ลบ for negatives.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 12:07:41 +02:00
vangel76andClaude Opus 5.5 b6618aee8e Clipboard: pasted currency cells keep the number from the clipboard HTML (#257)
Spreadsheets put an HTML table next to the tab-separated text; Excel
(x:num) and LibreOffice Calc (sdval) record each cell's number there.
Paste now reads the HTML flavour (new paste_html host service, arboard on
desktop) and edit.paste takes an optional html param: a field that would
paste as text becomes the recorded number when the HTML cell shows the
same text, with an inferred format ("Rp"#,##0.00) that renders it back
identically.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 12:03:46 +02:00
vangel76andClaude Opus 5.5 5c614fca48 UI: Name Box Enter goes to the typed cell, not the one below (#247)
The Enter that commits the Name Box stayed in the frame's input; the grid,
drawn after the formula bar and focused again, read it as its own Enter
and moved the active cell down. The Name Box now consumes it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 11:57:26 +02:00
vangel76andClaude Opus 5.5 a2894eff83 Functions: PERCENTOF and EUROCONVERT (#279)
PERCENTOF = SUM(subset) / SUM(all), written as _xlfn.PERCENTOF.
EUROCONVERT uses the fixed EU conversion rates for the currencies the
function documents, with currency rounding and triangulation precision.
New Add-in category for EUROCONVERT.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 11:56:18 +02:00
vangel76andClaude Opus 5.5 1b9751ed82 Fill handle: Ctrl+drag swaps copying and extending a series (#264)
A plain drag copies a lone number and extends every other series; Ctrl+drag
(Cmd on macOS) now does the opposite, as in Excel: a lone number counts up
by 1, and numbers, dates, lists and `Item 1`-style text are copied.
edit.autoFill gains mode "alternate" for this.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 11:55:45 +02:00
vangel76andClaude Opus 5.5 573cf92745 UI: skip system fonts egui can't parse instead of panicking at startup (#226)
epaint panics in set_fonts on a face skrifa can't open. Every system font
file is now checked with the same skrifa call (plus a readable cmap)
before it reaches FontDefinitions; a bad candidate is skipped with a
warning and the next one is tried, and a final pass drops any remaining
unparseable face from the definitions and every family.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 11:55:32 +02:00
vangel76andClaude Opus 5.5 fed3996944 Functions: ODDFPRICE, ODDFYIELD, ODDLPRICE, ODDLYIELD (#275)
Odd first and last coupon periods via quasi-coupon periods, from the
formulas on Microsoft's public function pages. ODDLYIELD is closed form;
ODDFYIELD bisects ODDFPRICE (bounded). Financial is now 55 / 55.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 11:51:34 +02:00
mbi 17211dcb65 Fix Paste button deadlock in ribbon popup 2026-10-11 12:00:07 +03:00
arekown a44cc8540d Add German (de) interface language
New catalog crates/ui-egui/src/i18n/de.rs (266 entries) mirroring the ru.rs
key set exactly; original translations written from the meaning of the
English UI strings, MIT OR Apache-2.0.

- Language::De registered (code de, name Deutsch); de/de-DE/de_AT/de-CH
  resolve via from_tag
- Tests: German coverage in the i18n coverage loop, de/de-AT/de-CH locale
  tags, ribbon round-trip case, default CJK font-order assertion
- Docs: localization-parity.md row, ROADMAP.md languages section

cargo test -p gridcraft-ui-egui i18n: 5 passed; --lib: 21 passed;
interaction + formula_locale: 13 + 8 passed.
2026-10-11 10:57:27 +02:00
Alexander Alber 92adfea27c XLSX: write @ as _xlfn.SINGLE in a dynamic-array formula (#64)
The file format has no `@` operator, but formulas with an explicit
implicit intersection were written with a literal `@`
(`<f>@A1:A3*2</f>`). Excel writes `@x` as `_xlfn.SINGLE(x)`, which only
dynamic-array formulas carry. The writer now does the same and marks such
formulas cm="1"; the parser reads `SINGLE(x)` back as `@x`, as it already
does for `ANCHORARRAY` and `#`.

Two cases in the #83 metadata test expected a redundant `@` (`SQRT(@A1:A3)`,
`@A1:A3*2`) to be written as an ordinary formula. Dropping the `@` there is
only lossless if the reader puts it back on legacy formulas, which it
doesn't yet (the read side of #64), so they now expect cm.

generated with Claude Code
2026-10-11 10:04:09 +02:00
Alexander Alber 4e6e0d6c31 AutoFilter: a selected header row filters the data below it; search box in the filter menu (#201)
Turning the filter on with a multi-cell selection used the selection as the
filter range. With only the header row selected, the filter had no data rows:
the dropdown list was empty and filtering hid nothing. A one-row selection
now extends down over the current region below it. An explicit `range`
parameter is still taken as given.

The filter menu gets a search box, as asked for in the issue. It narrows
the value list; Select All then reads "(Select All Search Results)" and
covers only the matches, and Apply keeps only the checked matches. The box
takes focus when the menu opens, so typing no longer lands in the active
cell.

generated with Claude Code
2026-10-11 09:49:46 +02:00
Alexander Alber 32d0a866f9 XLSX: write one cfvo per icon in icon-set rules (#235)
An icon-set rule without stored thresholds (every rule made by
home.conditionalFormat, and the sales sample) was written as an empty
<iconSet>, which CT_IconSet forbids (cfvo minOccurs 2); openpyxl drops it.
The writer now always emits one cfvo per icon: the stored thresholds when
there is one per icon, the lower bound prepended when it is missing, else
Excel's defaults (percent 0/33/67, 0/25/50/75, 0/20/40/60/80).

Evaluation read the thresholds as one fewer than the icons, but files
carry one per icon (the first is the lower bound), so thresholds read from
a file were ignored. Both now share icon_count and default_icon_thresholds
in gridcraft-model; icon_count is clamped to 3..=5 so a set name like
"0Foo" can't underflow k - 1.

generated with Claude Code
2026-10-11 09:26:00 +02:00
nihilist-narwhal 6e31ad9ea8 Typed times of 24 hours or more keep their hours
Typing 25:00 or 36:30:15 gave the right value but the h:mm format, so
the cell showed 1:00 and 12:30:15. Excel formats such entries as
[h]:mm:ss (25:00:00).
2026-10-10 22:52:59 -05:00
nihilist-narwhal ce83871f2b Remove Duplicates: compare the text cells show
Excel decides duplicates by what a cell displays, not the value stored:
the same date shown as 3/8/2006 and as Mar 8, 2006 is two values, while
1.01 and 1.02 both shown as 1.0 are duplicates. Remove Duplicates
compared stored values, so it did the opposite in both cases.
2026-10-10 22:52:59 -05:00