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
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
vangel76
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
vangel76
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
Brandon Thomas
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
vangel76
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
vangel76
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 Thomas
8aa9cad703
Slicers: the anchor uses #206 's checked cell_param and stays on the sheet; drop the personal macOS workflow (review fix-up for #193 )
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 14:58:29 -04:00
nihilist-narwhal
686501c7de
Data validation: relative formulas, checked with the value being entered
...
Validation formulas were evaluated as written, at every cell of the
range, and against the cell's old value. A Custom rule =A1>10 on A1:A9
rejected 20 typed into A1 (A1 was still empty) and checked A1, not A5,
when typing into A5; a Whole number rule "<= B1" on C1:C9 compared C2
with B1. As in Excel, the formulas are now relative to the first cell
of the range and see the value being entered.
2026-10-11 13:54:43 -05:00
nihilist-narwhal
683ff6003c
Defined names with relative references
...
A name whose references have no $ was evaluated as if they were
absolute. In Excel such references are relative: defined from B2,
=Sheet1!A2 means "the cell to the left", and the file stores it
relative to A1 (Sheet1!XFD1, wrapping around the sheet's edge).
Name formulas with relative references are now moved by the using
cell's offset from A1, wrapping at the edges, and formulas.defineName
takes relative references as relative to the active cell, as Excel's
Name Manager does, and stores them relative to A1.
2026-10-11 13:53:26 -05:00
Brandon Thomas
205981a52a
Merge branch 'land' into fix-193
...
# Conflicts:
# crates/engine/src/cmd/mod.rs
# crates/ui-egui/src/chartview.rs
2026-10-11 14:48:14 -04:00
Brandon Thomas
506320b548
Merge branch 'land' into fix-211
...
# Conflicts:
# crates/engine/src/tests.rs
# docs/ui-parity.md
2026-10-11 14:39:47 -04:00
Brandon Thomas
743ca809cc
Fix-up: Insert Copied Cells target and PivotChart anchor use #206 's checked cell_param
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 14:34:37 -04:00
Brandon Thomas
57ab1790ad
Merge pull request #364 from MarekSpodBiedry/issue-362
...
Edit date cells as dates, not serial numbers (#362 )
2026-10-11 14:34:16 -04:00
Brandon Thomas
76f3a29c79
Merge branch 'land' into fix-206
2026-10-11 14:23:51 -04:00
Brandon Thomas
7a34692a0d
Merge pull request #325 from vangel76/feat/forecast-sheet
...
Data: Forecast Sheet (data.forecastSheet) (#322 )
# Conflicts:
# ROADMAP.md
# docs/gaps.md
# docs/parity-checklist.md
# docs/ui-parity.md
2026-10-11 13:52:00 -04:00
Brandon Thomas
fda7f5bc14
Merge pull request #333 from vangel76/feat/xlsx-passthrough
...
XLSX: keep unmodelled parts on save (#330 )
# Conflicts:
# ROADMAP.md
# crates/model/src/lib.rs
# crates/model/src/sheet.rs
# docs/file-format-parity.md
# docs/gaps.md
2026-10-11 13:51:59 -04:00
Brandon Thomas
c379da6ac9
Merge pull request #332 from vangel76/feat/xls-read
...
XLSX/IO: read legacy .xls (BIFF8) workbooks (#121 )
# Conflicts:
# docs/gaps.md
2026-10-11 13:51:48 -04:00
Brandon Thomas
4a55aa3e34
Merge main into page-layout-view: pages keep the gliding selection ( #266 ), frozen-pane clipping ( #217 ), right-to-left mirroring and freeze handles ( #310 , #309 ); es/de/cs strings for headers and footers
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 13:39:07 -04:00
Brandon Thomas
baffd3c78d
Fix-up #325 : cap Forecast Sheet history and forecast rows
...
The default periods (a third of the history, up to ~33k) bypassed
MAX_PERIODS, and each forecast row's three ETS formulas refit over the whole
history, so 100k history rows x 10k periods froze the app. History is now at
most 10,000 rows, periods at most 10,000, and history x periods at most
500,000 (about 3 us per history point per fit: a few seconds of recalc at
the cap). The default is clamped to the cap; explicit periods or an end past
it are refused.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 13:30:47 -04:00
Brandon Thomas
b3908bf81e
Key tips HAT/HAM/HAB run Align Top/Middle/Bottom, with a test (review fix-up for #261 )
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 13:20:22 -04:00
MarekSpodBiedry
ea2e2a5bba
Edit date cells as dates, not serial numbers ( #362 )
2026-10-11 19:18:27 +02:00
Brandon Thomas
5360a77505
Merge remote-tracking branch 'origin/main' into fix-325
...
# Conflicts:
# ROADMAP.md
# crates/engine/src/cmd/mod.rs
# crates/ui-egui/src/dialogs.rs
# docs/gaps.md
# docs/parity-checklist.md
# docs/ui-parity.md
2026-10-11 13:12:41 -04:00
Brandon Thomas
9cb6cb2384
Merge branch 'land' into fix-288
...
# Conflicts:
# ROADMAP.md
# crates/engine/src/cmd/edit.rs
# docs/target-app-parity.md
2026-10-11 13:01:23 -04:00
Brandon Thomas
79fce91359
Merge remote-tracking branch 'origin/main' into fix-333
...
# Conflicts:
# ROADMAP.md
# crates/model/src/lib.rs
# crates/xlsx/src/sheet_read.rs
# docs/file-format-parity.md
# docs/gaps.md
2026-10-11 12:56:45 -04:00
Brandon Thomas
141fef26e8
Merge remote-tracking branch 'origin/main' into fix-286
...
# Conflicts:
# ROADMAP.md
# crates/engine/src/cmd/review.rs
# docs/gaps.md
# docs/parity-checklist.md
# docs/target-app-parity.md
2026-10-11 12:52:12 -04:00
Brandon Thomas
30312e7546
Merge remote-tracking branch 'origin/main' into fix-332
...
# Conflicts:
# ROADMAP.md
# docs/file-format-parity.md
# docs/gaps.md
2026-10-11 12:51:12 -04:00
Brandon Thomas
9d3b3a6074
Merge pull request #207 from mikl0s/fix/cell-set-requires-input-v2
...
Cell: cell.set without an input is an error
2026-10-11 12:46:03 -04:00
Brandon Thomas
29660e8c4d
Merge pull request #331 from vangel76/feat/file-backstage
...
UI: File tab Backstage view (#174 )
# Conflicts:
# ROADMAP.md
# crates/engine/src/tests.rs
# crates/ui-egui/src/control.rs
# crates/ui-egui/src/lib.rs
# crates/ui-egui/src/ribbon.rs
# docs/parity-checklist.md
# docs/ui-parity.md
2026-10-11 12:08:56 -04:00
Brandon Thomas
839072c6dd
Merge pull request #327 from vangel76/feat/solver
...
Data: Solver with Simplex LP, integer branch and bound and a nonlinear method (#326 )
# Conflicts:
# crates/ui-egui/src/dialogs.rs
# crates/ui-egui/src/i18n.rs
# crates/ui-egui/src/i18n/ko.rs
# crates/ui-egui/src/i18n/pt.rs
# crates/ui-egui/src/i18n/ru.rs
# crates/ui-egui/src/i18n/zh.rs
# crates/ui-egui/src/ribbon.rs
# crates/ui-egui/tests/interaction.rs
# docs/gaps.md
# docs/parity-checklist.md
# docs/target-app-parity.md
# docs/ui-parity.md
2026-10-11 12:07:34 -04:00
Brandon Thomas
1dbad7768d
Merge pull request #320 from vangel76/feat/analysis-toolpak
...
Data: Analysis ToolPak with 13 tools and the Data Analysis dialog (#312 )
# Conflicts:
# crates/ui-egui/src/dialogs.rs
# docs/gaps.md
# docs/parity-checklist.md
2026-10-11 12:06:42 -04:00
Brandon Thomas
95660dc132
Merge pull request #319 from vangel76/fix/excel-shortcuts
...
Keyboard: Excel shortcut audit, add the missing ones (#110 )
# Conflicts:
# docs/ui-parity.md
2026-10-11 12:06:40 -04:00
Brandon Thomas
925ff53122
Merge pull request #303 from vangel76/fix/chart-category-axis
...
Charts: Select Data edits the category axis labels; blank corner makes column 1 the categories (#287 )
# Conflicts:
# crates/engine/src/tests.rs
# crates/ui-egui/src/dialogs.rs
# crates/ui-egui/tests/interaction.rs
# docs/chart-parity.md
2026-10-11 12:06:39 -04:00
Brandon Thomas
fe9e3163f0
Merge pull request #301 from vangel76/fix/recommended-charts
...
Charts: Recommended Charts opens a dialog of chart types with previews (#215 )
# Conflicts:
# crates/engine/src/tests.rs
# crates/ui-egui/tests/interaction.rs
# docs/chart-parity.md
2026-10-11 12:06:37 -04:00
Brandon Thomas
97bad77ef4
Merge pull request #313 from vangel76/feat/pivot-chart
...
Charts: PivotCharts (insert.pivotChart) (#311 )
# Conflicts:
# ROADMAP.md
# crates/engine/src/cmd/pivot.rs
# docs/gaps.md
# docs/parity-checklist.md
# docs/target-app-parity.md
2026-10-11 12:05:54 -04:00
Brandon Thomas
685802ee9f
Merge pull request #306 from vangel76/feat/pivot-calculated-field
...
PivotTables: calculated fields (pivot.calculatedField) (#304 )
# Conflicts:
# ROADMAP.md
# docs/gaps.md
# docs/parity-checklist.md
# docs/target-app-parity.md
2026-10-11 12:05:52 -04:00
Brandon Thomas
2af0984af0
Merge pull request #308 from vangel76/feat/review-allow-edit-ranges
...
Review: Allow Edit Ranges with Excel-compatible password hashes (#307 )
# Conflicts:
# ROADMAP.md
# crates/xlsx/src/sheet_write.rs
# crates/xlsx/src/tests/malformed.rs
# docs/file-format-parity.md
# docs/gaps.md
# docs/parity-checklist.md
# docs/target-app-parity.md
2026-10-11 12:05:30 -04:00
Brandon Thomas
4dce1181e1
Merge pull request #305 from vangel76/feat/cell-checkbox
...
Checkboxes: ribbon button, Excel's value and Delete rules, XLSX cell controls (#196 )
# Conflicts:
# ROADMAP.md
2026-10-11 12:05:28 -04:00
Brandon Thomas
1f99931dd3
Merge pull request #302 from vangel76/feat/xlsx-threaded-comments
...
XLSX: write threaded comments and persons parts, read note visibility (#300 )
# Conflicts:
# ROADMAP.md
# crates/xlsx/src/tests/roundtrip.rs
2026-10-11 12:05:27 -04:00
Brandon Thomas
f8903c9e98
Merge pull request #353 from LloydNicholson/fix/copy-multiple-ranges
...
Issue #348 : copying multiple selections works when the areas line up, and explains when it can't
# Conflicts:
# crates/engine/src/tests.rs
# crates/ui-egui/tests/clipboard.rs
2026-10-11 12:04:15 -04:00
Brandon Thomas
9da7acf846
Merge pull request #350 from LloydNicholson/fix/multi-select-resize
...
Issue #341 : resizing Ctrl-selected rows or columns resizes all of them
# Conflicts:
# crates/engine/src/tests.rs
2026-10-11 12:04:14 -04:00
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 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
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
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
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
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