Commit Graph

25 Commits

Author SHA1 Message Date
Brandon Thomas cc0b7c18d1 Merge main into #600
# Conflicts:
#	crates/calc/src/eval.rs
2026-10-13 00:49:39 -04:00
Brandon Thomas 8d3e440a8b Merge pull request #599 from MarekSpodBiedry:issue-565 2026-10-12 23:35:48 -04:00
Brandon Thomas 86f83f4ccf Merge pull request #598 from MarekSpodBiedry:issue-566 2026-10-12 23:35:47 -04:00
MarekSpodBiedry eec3353e83 Read date text in the workbook date system in arithmetic and VALUE (#564) 2026-10-12 08:35:55 +02:00
MarekSpodBiedry ff14224ff9 Convert TODAY and NOW to the workbook date system in 1904 workbooks (#578) 2026-10-12 08:34:40 +02:00
MarekSpodBiedry 2586ec22df Treat serials past 9999-12-31 as out of range in the 1904 date system (#565) 2026-10-12 08:34:19 +02:00
MarekSpodBiedry afd61a7c4a Parse two-digit years in spaced month-name dates (#566) 2026-10-12 08:27:32 +02:00
Brandon Thomas 336deb87de Merge pull request #216 from MarekSpodBiedry/issue-202
Read the browser clock for NOW(), TODAY() and year-less dates on wasm (#202)
2026-10-11 12:46:33 -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
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 6fd41d626b Typed dates before 1900 stay text
7/4/1776 was entered as 7/4/3676 and DATEVALUE("12/31/1899") gave
693962: the text parser built dates with DATE()'s rule that adds 1900 to
years below 1900. Excel keeps such entries as text, and DATEVALUE gives
#VALUE!.
2026-10-10 22:52:59 -05:00
webdevtodayjason fae90c8e4a selection.move: clamp extreme dr/dc to the sheet edge instead of overflowing 2026-10-10 21:05:58 -05:00
MarekSpodBiedry 27be1753c2 Read the browser clock for NOW(), TODAY() and year-less dates on wasm (#202) 2026-10-10 23:43:32 +02:00
Brandon Thomas 960c79a328 Merge pull request #187 from MarekSpodBiedry/issue-57
Compare numbers at 15 significant digits like Excel (#57)
2026-10-10 15:46:33 -04:00
Brandon Thomas 11ef0e6b04 Maintainer fix-up: compare clearly different numbers directly, skipping the 15-digit text round trip on the sort/lookup hot path
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 15:35:13 -04:00
Brandon Thomas 6e935a3c8c Merge origin/main into feat/i18n-language
# Conflicts:
#	crates/engine/src/cmd/file.rs
#	crates/ui-egui/src/lib.rs
#	crates/ui-egui/src/ribbon.rs
2026-10-10 13:15:10 -04:00
MarekSpodBiedry 0f21244e9e Compare numbers at 15 significant digits like Excel (#57) 2026-10-10 19:08:16 +02:00
Brandon Thomas 277f01265b Merge fixed #38 (font fallback) into feat/i18n-language
# Conflicts:
#	crates/ui-egui/src/grid.rs
#	crates/ui-egui/src/ribbon.rs
#	crates/ui-egui/src/widgets.rs
2026-10-10 12:31:57 -04:00
Brandon Thomas 15e0f0b6be Merge remote-tracking branch 'origin/main' into pr125 2026-10-10 12:04:21 -04:00
lloyd e893621d76 Web app: committing a cell no longer traps on the clock
Every edit goes through cmd::commit, which read std::time::Instant::now()
up front for GRIDCRAFT_PROFILE timing, whether profiling was on or not.
wasm32-unknown-unknown has no clock: Instant::now panics there, and with
panic=abort the browser reports `RuntimeError: unreachable`. So in the
web app, typing 1 into A1 and pressing Enter trapped (#118). The native
apps and the CLI have a clock and were unaffected.

commit now reads the clock only when GRIDCRAFT_PROFILE is set, and
never on wasm. The other clock reads (NOW(), the current year for typed
dates, the UI's frame timer) already skip wasm.

Native tests can't see this trap, so clippy.toml now disallows
Instant::now and SystemTime::now. A clock read has to be gated off wasm
and allowed at the call, and `cargo clippy -D warnings` fails on the old
commit code. The existing, already-gated reads and the native-only perf
example allow it.

Checked by building the engine for wasm32-unknown-unknown into a small
cdylib that runs cell.set A1=1 on a new workbook, and running it in
Node: before the fix it traps with `RuntimeError: unreachable`, after
it returns normally.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 09:03:33 +02:00
lloyd ecaead4c12 DATE(1900,2,29) is serial 60, as in Excel
serial_from_ymd worked out the real calendar date and then moved serials
up to 60 down by one. February 1900 has no 29th in the real calendar, so
DATE(1900,2,29) and DATEVALUE("2/29/1900") rolled over to 1 March (61),
and DATE(1900,3,0) gave 28 February (59). Excel's 1900 system keeps the
Lotus leap day: serial 60 is 29 February 1900, and DAY(60) already
said so.

The serial of the first of the month is now taken in Excel's calendar
(one lower up to February 1900), and the day, with any overflow, counts
on from there. So day and month overflow pass through serial 60 both
ways: DATE(1900,1,60), DATE(1900,4,-31) and DATE(1901,-10,29) are 60 too.
Month and day arithmetic is checked, so hostile values return None.

days_in_month_in gives February 1900 29 days in the 1900 system; EDATE
and EOMONTH use it, so EOMONTH(60,0) is 60 rather than the day before,
and the text parser uses it in place of its own special case. The 1904
system is unchanged (1900 is before its epoch).

Tests: serials around the leap day (overflow both ways, every serial
0-366 round-trips through its year, month and day), hostile months and
days, parsing 2/29/1900 and 1900-02-29, DATE/DATEVALUE/EDATE/EOMONTH
in the 1900 system and the 1904 system. The DATE, DATEVALUE and serial
cases fail before the fix.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 20:36:08 +02:00
justinjohn0306 7e24aa398a CI: satisfy newer clippy lints (toolchain drift, behavior-preserving)
Local clippy 1.96 flags pre-existing patterns the code has always had:
manual range-contains comparisons, a dead `|| true` filter and a
simplifiable boolean. None change behaviour; they only clear the lints
so `cargo xtask ci` passes on a current toolchain.
2026-10-09 13:08:28 +05:30
Brandon Thomas 488e12de31 Rename SheetCraft to GridCraft everywhere (crates, apps, bundle ids, packaging, docs)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 01:39:08 -04:00
Brandon Thomas beb353943e M1: Excel-style egui UI, desktop app, chart renderer, MCP server, CLI, release packaging
- ui-egui: title bar with QAT, full ribbon (Home/Insert/Draw/Page Layout/Formulas/Data/
  Review/View/Automate + Table/Chart Design), formula bar with Name Box, virtualised grid
  (frozen panes, overflow, borders, CF data bars/scales/icons, tables, sparklines, filter
  buttons, charts/pictures/shapes), in-cell editor with point mode, reference colouring,
  autocomplete and argument hints, sheet tabs, status bar, dialogs, control channel
- apps/sheetcraft: desktop app (control server, file dialogs, prefs, drag & drop)
- chart: toolkit-free chart layout/rendering for 25 chart kinds + sparklines + rasteriser
- mcp + sheetcraft-cli: MCP server (headless or bridged) and CLI (info/convert/eval/cat/run/mcp)
- xtask (ci/layers/assets/wasm/version/parity), release workflows, packaging, placeholder icon
- automatic row heights

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 00:00:15 -04:00
Brandon Thomas 1ba9daa263 M0: foundation — core, numfmt, formula, functions (478), model, calc, xlsx/csv, engine
Clean-room spreadsheet engine: addresses/values/dates, Excel number formats,
formula parser/printer/reference adjustment, worksheet function library,
copy-on-write workbook model, dependency-driven recalculation with dynamic
arrays, XLSX/CSV I/O, and a command engine (cell entry, clipboard, fill,
formatting, sheets, sort/filter, tables, charts, CF, names, view, file).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-05 23:18:10 -04:00