Commit Graph
1780 Commits
Author SHA1 Message Date
Helen Kwok e93d15b50a Contributors: credit helenkwok as Helen Kwok 2026-10-24 10:17:32 +08:00
Helen Kwok b389d9067a XLSX: write accounting formats 42 and 44 with their code
builtin_id already wrote the currency formats 5-8 as custom formats
because readers resolve those ids by locale. The accounting formats
with a currency, 42 and 44, are resolved the same way but were written
as bare ids, so LibreOffice showed a 44 cell holding -0.14 as "- 0.14"
where US Excel shows "$ (0.14)". Treat them like 5-8.
2026-10-24 10:17:32 +08:00
Dylan M. Taylor b8771d51fb Merge pull request #2390 from dylanmtaylor/ci/sonar-main-not-cancelled
ci(sonar): stop cancelling main-branch runs so coverage is published
2026-10-23 16:59:11 -04:00
Dylan M. Taylor 2329507a8e ci(sonar): don't cancel superseded runs on main, so coverage is published 2026-10-23 16:51:16 -04:00
Brandon ThomasandClaude Opus 5.5 7cf44d0fbb Integration and review fixes for #2367, #2369 and #2387
- #2369: its test joins the single ui-egui integration-test binary (tests/it), as main now builds them.
- #2367: a cell set to empty text is a blank entry and doesn't grow the AutoFilter (CodeRabbit).
- #2387: MOD's range check also covers the sign-corrected remainder (CodeRabbit).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-23 16:05:43 -04:00
Brandon Thomas 81fd0f6f7d Merge PR #2387 2026-10-23 16:05:03 -04:00
Brandon Thomas 68da23e2eb Merge PR #2386 2026-10-23 16:05:01 -04:00
Brandon Thomas fba4224ffc Merge PR #2375 2026-10-23 16:04:59 -04:00
Brandon Thomas 2a4cc2a5b6 Merge PR #2369 2026-10-23 16:04:58 -04:00
Brandon Thomas ca0c3afbab Merge PR #2367 2026-10-23 16:04:56 -04:00
Brandon Thomas 87935eb245 Merge PR #2366 2026-10-23 16:04:55 -04:00
NetterSilverandClaude Haiku 5.5 c746eea876 Fix MOD returning wrong sign and magnitude for tiny divisors
Found while testing crates/functions/src/math.rs:305-319

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-23 21:43:22 +02:00
aiongg 15a705e234 i18n: missing translations are reported, never a failure (#2383)
A string a catalog lacks shows in English. Coverage, key-parity and
per-language count tests and tests of one language's exact wording are
removed; UI wiring tests take their expected text from the catalog.
cargo xtask i18n-report lists the missing strings per language and
always passes; cargo xtask ci runs it first.
2026-10-23 15:39:59 -04:00
Marco Arnulfo 43a5a3c435 PivotTables: Show Details checks the report is up to date before looking at the cell 2026-10-23 21:00:07 +02:00
aiongg 530a8cc810 CI: the gate builds with the release craft-fonts pin (#2381) 2026-10-23 14:47:33 -04:00
Marco Arnulfo 7111812b87 PivotTables: Show Details refuses an out-of-date report, and reports its errors instead of editing the cell 2026-10-23 20:41:47 +02:00
aiongg 08820cb4b2 CI: run the gate through craft-common-actions' shared gate.yml; FreeBSD nightly and on release (#2338)
ci.yml calls the shared workflow (cached apt packages, nextest, main-only cache saves, Cargo.lock check). FreeBSD runs nightly and on pushes to release instead of on pull requests. Depends on storytold/craft-common-actions#69.
2026-10-23 14:32:15 -04:00
Marco Arnulfo 0c14f59555 PivotTables: Show Details, double-click a value cell to list its source records on a new sheet (#2364) 2026-10-23 20:21:27 +02:00
aiongg aa8399be95 Grid: #### is sized by the width of #, so it fits its cell in every font (#2378)
A number too wide for its column is drawn as ####, with as many # as fit. The count used the
width of 0, and in fonts where # is wider than 0 the hashes ran past the cell edge.
accounting_fill::too_wide_fill_number_shows_hashes_not_a_clipped_value caught it on FreeBSD
and on Linux machines without the CI font set.
2026-10-23 14:14:15 -04:00
xc4pr 49f26bdd79 Fill handle: the Auto Fill Options button on a right-to-left sheet is checked in screen space (#2368) 2026-10-23 19:04:27 +02:00
xc4pr 39450b80d1 Hyperlinks: Ctrl+Alt+click on a link extends the selection again (#2368) 2026-10-23 19:04:27 +02:00
aiongg 33a45130a1 Packaging: pin the signing client and appimagetool, and check their hashes (#2073)
* Packaging: pin the Windows signing client and check its hash

* Packaging: pin appimagetool and check its hash

* Packaging: pin the AppImage runtime and stop clearly without a pinned tool

* Packaging: shellcheck-clean empty hashes
2026-10-23 13:02:16 -04:00
aiongg a7608ada6d CI: one test binary per crate, nextest, line tables only (#2372)
* CI: dev builds keep line tables only

* CI: one integration-test binary per crate

* CI: xtask runs tests with nextest, doctests apart, --keep-going on clippy and wasm

cargo xtask test runs the workspace tests (--lib --bins --tests) with cargo-nextest when it is installed, else cargo test, then the doctests. cargo xtask ci uses the same two steps.

* CI: docs name cargo xtask test

* CI: agent guides name the moved fuzz test

* CI: tests added on main join their crate's test binary
2026-10-23 12:59:46 -04:00
Marco Arnulfo 45ec9dfbfe Build the saved UiState in the test with struct update syntax (clippy field_reassign_with_default) 2026-10-23 18:44:23 +02:00
MarekSpodBiedry 8f2a60d176 Keep the in-cell editor the cell's width while the text fits (#2336) 2026-10-23 17:56:16 +02:00
Dylan M. Taylor bdf8b8cc75 Use chrono instead of hand-rolled UTC conversion (#2121)
* Use chrono for UTC/calendar conversion instead of hand-rolled copies

Replaces the hand-rolled civil_from_days / days_from_civil copies and the
is_leap / days_in_month calendar helpers with chrono as a workspace dependency
(default-features = false, std only, so wasm is unaffected). The spreadsheet
serial-date semantics are untouched: Excel's 1900 fictitious leap day (serial
60 = 1900-02-29), the 1899-12-30 / 1904-01-01 serial offsets, Excel's weekday
numbering and the 1900/1904 systems keep their explicit special cases in
serial_from_ymd / datetime_from_serial / days_in_month_in. chrono only backs
the plain proleptic-Gregorian day-number <-> date conversion and the
leap-year / month-length helpers those build on; a small fallback keeps the old
answer for dates outside chrono's NaiveDate range. The duplicate local is_leap
in the financial functions now uses the core one. Output is byte-identical and
pinned by the existing date, parse, financial and logging tests. AGENTS.md now
says time goes through chrono.

Follow-up to storytold/cadcraft#1785

* Never panic on out-of-range clocks or years; keep calendar results outside chrono's range

- logging::timestamp: chrono's From<SystemTime> unwraps, so a clock past year
  262143 panicked inside the logger. Use the fallible DateTime::from_timestamp
  and read such a clock as the epoch, like the old saturating code. Years past
  9999 are written with {:04} (not %Y, which prefixes a '+').
- date::is_leap: restore the Gregorian leap-year rule for years outside chrono's
  NaiveDate range (e.g. is_leap(400000) is true again) via direct arithmetic.
- date::days_in_month: compute the December boundary with checked_add so
  days_in_month(i32::MAX, 12) no longer overflows, and compute month lengths
  through days_from_civil's fallback so out-of-range years keep their real
  lengths (e.g. days_in_month(400000, 2) is 29). Invalid months still return 0.
- civil_from_days: add missing docstring.
- AGENTS.md: note the narrow out-of-range fallback exception to the chrono rule.

* Don't build an unrepresentable SystemTime in the far-future test

UNIX_EPOCH + Duration::from_secs(u64::MAX / 2) overflows Windows'
SystemTime and panicked before timestamp() ran, failing the Windows
test job. Build it with checked_add and only assert where it exists.

* Route out-of-range dates through chrono's 400-year cycle, not hand-rolled copies

The PR kept hand-rolled Hinnant `days_from_civil_fallback`/`civil_from_days_fallback`
copies for dates outside chrono's ±262143-year range, plus a hand-rolled
Gregorian leap rule in `is_leap` and an i32::MAX special-case in `days_in_month`.
AGENTS.md carved a "narrow fallback" exception for them, which left calendar
arithmetic outside chrono after all.

Replace all of it with the Gregorian 400-year cycle (146_097 days): chrono
converts the day/year within one cycle and whole cycles are added back via i128
(so the i32/i64 extremes can't overflow). `is_leap` and `days_in_month` reduce
the year with `rem_euclid(400)` (leap years and month lengths repeat every 400
years), which also removes the December `i32::MAX` overflow special-case.

chrono is now the only calendar logic, and every output is unchanged: verified
the cycle result equals the old formula over wide ranges and at the i32/i64
extremes with a scratch chrono program. The Excel 1900 leap bug (serial 60 =
fictitious 1900-02-29) and 1904 semantics are untouched -- `serial_from_ymd`/
`datetime_from_serial` only ever hand the converters in-range years, so their
serials are byte-for-byte the pre-chrono ones (pinned by a new test).

New tests pin `days_from_civil`/`civil_from_days` past chrono's range on both
sides of the epoch, round-tripping, with values from the old formula; the
existing leap/month-length-beyond-range test still passes unchanged. Removed the
AGENTS.md "narrow fallback" exception.

Tested: cargo test -p gridcraft-core -p gridcraft-functions; fmt --check;
clippy --all-targets -D warnings.

* time: preserve out-of-range years in the log timestamp instead of the epoch

`DateTime::from_timestamp(..).unwrap_or_default()` changed the existing output: a
clock set far ahead (an input the old hand-rolled civil-from-days converted)
collapsed to `1970-01-01`. Restore the old conversion domain with a cycle-based
helper: reduce by whole 400-year Gregorian cycles (146_097 days), convert the
in-range remainder with chrono, and carry the year back as i128. Only the year
leaves chrono's range; month/day/time stay exact. Pre-1970 still clamps to the
epoch as before. chrono stays the only calendar logic (no new features).

apps/gridcraft logging.rs `timestamp` (SystemTime, u64 secs), pinned via a
platform-safe `UNIX_EPOCH.checked_add`:
  u64::MAX/2 s → "292277026596-12-04T15:30:07.000Z" (was "1970-01-01..."),
  10e12 s → "318857-05-20T17:46:40.000Z", 253_402_300_800 s → "10000-01-01...".

* Name the 400-year range extension as the one exception to the time rule

The rule said never to hand-roll calendar math, but the range fix
(shifting by whole 400-year Gregorian cycles so dates past chrono's year
range keep their old output) is cycle arithmetic, so the rule and the code
disagreed. The rule now names that exception: the library still computes
month, day and time, and only whole cycles are carried in the year.

* Say the library computes month and day; time-of-day is plain arithmetic

Narrows the range-extension wording: the date library computes the
calendar fields, and splitting seconds into hours, minutes and seconds
is ordinary arithmetic, which is what the code does.
2026-10-23 11:48:02 -04:00
MarekSpodBiedry 599762f534 AutoFilter: grow the range when a value is entered in the row below it (#2342) 2026-10-23 17:36:39 +02:00
MarekSpodBiedry ba98039988 Keep the in-cell editor wide enough for the next character at high zoom (#2336) 2026-10-23 17:33:31 +02:00
Dylan M. Taylor 168acc5889 packaging: shell, PowerShell and web page fixes (SonarCloud S7688, S7679, S7682, S8677, S7926) (#2323)
- Shell: [[ ]] for conditional tests, positional parameters copied into
  named locals, explicit return at the end of the env.sh helpers.
- PowerShell: the desktop-shortcut smoke test writes its progress with
  Write-Output instead of Write-Host.
- Web: the viewport no longer sets user-scalable=no, so people can zoom
  the page.
2026-10-23 11:17:38 -04:00
Marco Arnulfo a0ceea1468 Open on the Home tab every launch, as in Excel (fixes #2329) 2026-10-23 17:16:30 +02:00
Marco Arnulfo 9135c7f6f0 Ribbon: fall back to Home when the active contextual tab is gone (fixes #2329) 2026-10-23 17:07:42 +02:00
Brandon ThomasandClaude Opus 5.5 f1e29fa828 Review fixes for #2267 and #2292
- range.setValues with parse: false still turns on Wrap Text for a line break (CodeRabbit).
- Japanese: the fill-handle hint says AutoFill (オートフィル), not paint (CodeRabbit).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-23 10:15:31 -04:00
Brandon Thomas fe2f9a7582 Merge PR #2357
# Conflicts:
#	docs/ui-parity.md
2026-10-23 10:11:33 -04:00
Brandon Thomas a09454e250 Merge PR #2315
# Conflicts:
#	docs/ui-parity.md
2026-10-23 10:11:33 -04:00
Brandon Thomas bcf55f0f00 Merge PR #2274
# Conflicts:
#	docs/ui-parity.md
2026-10-23 10:11:33 -04:00
Brandon Thomas 4b8725b29b Merge PR #2314 2026-10-23 10:11:12 -04:00
Brandon Thomas e92d8b4e48 Merge PR #2295 2026-10-23 10:11:12 -04:00
Brandon Thomas 817cf80470 Merge PR #2292 2026-10-23 10:11:12 -04:00
Brandon Thomas 2d0fe1f01e Merge PR #2289 2026-10-23 10:11:12 -04:00
Brandon Thomas d1399ff2ca Merge PR #2279 2026-10-23 10:11:12 -04:00
Brandon Thomas 67f13d804c Merge PR #2275 2026-10-23 10:11:12 -04:00
Brandon Thomas 50e5a3e928 Merge PR #2267 2026-10-23 10:11:11 -04:00
Brandon Thomas a725f2dc67 Merge PR #2266 2026-10-23 10:11:11 -04:00
Brandon Thomas 27a33f1ee0 Merge PR #2260 2026-10-23 10:11:11 -04:00
Brandon Thomas 5d0fc0b06a Merge PR #2245 2026-10-23 10:11:11 -04:00
Brandon Thomas 3c62ae27fd Merge PR #2244 2026-10-23 10:11:11 -04:00
Brandon Thomas 073ae2df39 Merge PR #2233 2026-10-23 10:11:11 -04:00
RedBearAKandClaude Opus 5.5 8eda577545 Page Up into frozen rows scrolls the rows below back to the top
With row 1 frozen, Page Up could land on A1, which is always on screen, while the scrolled rows
stayed a page down (row 10, Page Down, Page Up, Page Up ends on row 1 with rows 2-9 hidden). The
same held for Ctrl+Up into frozen rows and Ctrl+Left / Alt+Page Up into frozen columns.

Arrow and paging keys now record the cell they moved from (`GridState::reveal_from`). When such a
move goes from the scrolled rows (columns) into the frozen ones, the scrolled area goes back to
its top (left). Other reveals (clicks, Find, Go To, Name Box, Undo, the control channel, formula
pointing) leave it unset and keep the view where the user scrolled it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-23 03:20:18 -08:00
xc4pr 7c1ec1df7d Fill handle: test the Auto Fill Options button on a right-to-left sheet, merge the duplicate fill handle row (#1403) 2026-10-23 02:37:49 +02:00
xc4pr 60776ff4de Hyperlinks: test that Ctrl+click beside the link text still extends the selection (#1198) 2026-10-23 02:23:37 +02:00