Commit Graph

204 Commits

Author SHA1 Message Date
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