Commit Graph
34 Commits
Author SHA1 Message Date
3b65b9af58 Sonar maintainability: explicit imports, method paths, smaller functions (#2412)
* Sonar: explicit imports, fn paths for closures, extract helpers for cognitive complexity

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* Fix imports

* Fix serde imports

* Fix engine imports

* Fix clippy gate and a type error from the explicit-import change

Remove the unused imports the review flagged (cf.rs, pivot.rs, tables.rs, cmd/sheet.rs) so clippy -D warnings passes, and point the backstage parent-folder lookup at Path::to_str, which the fn-path rewrite had broken.

Generated with Codebuff
Co-Authored-By: Codebuff <noreply@codebuff.com>

* Apply rustfmt to the explicit-import cleanup so the fmt gate passes

* Share the per-directory font path expansion in theme.rs

The candidate font lists repeated the same loop over the Linux font
directories in every role. A single helper expands them in the same order,
so the lookup order is unchanged and the duplicated blocks go away.

🤖 Generated with Codebuff
Co-Authored-By: Codebuff <noreply@codebuff.com>

* Read the Windows fonts folder in one place in theme.rs

Every script-font list repeated the same WINDIR lookup. A single helper
returns the same path, so the duplicated lines go away without changing
which font files are tried.

🤖 Generated with Codebuff
Co-Authored-By: Codebuff <noreply@codebuff.com>

* Build the light and dark UI palettes from one table in theme.rs

Tokens::light() and Tokens::dark() listed the same 40 colour fields in the
same order, so every change had to be made twice. A single palette
constructor takes the mode and picks each colour's value, so each field is
written once and both modes keep their exact colours.

🤖 Generated with Codebuff
Co-Authored-By: Codebuff <noreply@codebuff.com>

* Share the Noto CJK font list between the CJK script lists in theme.rs

The Japanese, Simplified and Korean lists each repeated the same loop over
the Linux CJK directories with a different locale file name. One helper
builds that loop, and each list keeps its own face index, so the lookup
order is unchanged.

🤖 Generated with Codebuff
Co-Authored-By: Codebuff <noreply@codebuff.com>

* Share Linux Noto directory list across Thai and Hebrew font lookups

Removes the duplicated directory arrays flagged by SonarCloud new-code duplication.

* Reuse in_dirs for Thai and Hebrew Noto font candidates

Removes the remaining duplicated per-directory loops flagged by SonarCloud.

* Share one font-list builder for the Thai and Hebrew faces

The two per-script functions repeated the same Windows, macOS, Linux and
variable-font setup. A single script_fonts helper now builds both lists,
keeping the candidate order unchanged, which clears the Sonar duplication gate.

---------

Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-authored-by: Codebuff <noreply@codebuff.com>
2026-10-25 12:32:02 -04:00
aiongg 561382cc6d Integration: track t14
# Conflicts:
#	ROADMAP.md
#	contributors/people.toml
#	crates/formula/src/tests.rs
#	docs/file-format-parity.md
#	docs/localization-parity.md
#	docs/ui-parity.md
2026-10-22 03:05:30 +00:00
Eduardo GarciaandClaude Sonnet 5.5 41cb19fd6d Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> 2026-10-20 18:39:49 -03:00
Marco Arnulfo 736cc89b2b Opening an XLSX with a part over 512 MB says how to get the data in (fixes #1242) 2026-10-14 07:44:41 +02:00
Brandon Thomas 9972a75f10 Merge main into #824
# Conflicts:
#	crates/engine/src/cmd/file.rs
#	crates/engine/src/tests.rs
#	crates/xlsx/src/tests/passthrough_tests.rs
2026-10-13 00:53:41 -04:00
NetterSilver 39b3d55f8a CSV export: refuse a file over 512 MiB instead of expanding the whole used range (#528)
write_csv visited every position of the used range and appended to one growing
String with no limit, so two cells far apart (A1 and XFD1048576) asked for
about 16 GiB of commas. The output is now capped at 512 MiB: a lower bound
(delimiters and line ends of every row) is checked before anything is
allocated, and the text written so far is checked after each row. Over the
cap, write_csv returns IoError::TooLarge naming the rows, columns and limit,
and Save As / Export CSV and TSV report it without writing a file. Accepted
exports are unchanged. write_csv now returns a Result.
2026-10-13 01:16:05 +02:00
Marco Arnulfo 5406fc5629 XLSX: Save As into another folder keeps links on the same workbook (fixes #801)
Excel stores the path of a linked workbook relative to the file that uses it, and rewrites it when the file is saved into another folder. The path was kept as text, so after Save As it named a file next to the new copy: a missing link, or another workbook with the same name. Relative externalLinkPath targets are now resolved against the folder the workbook was read from and written relative to the folder it is saved into (absolute when there is no relative path, on another drive).
2026-10-12 22:55:53 +02:00
Brandon Thomas a34fe4a7af Merge pull request #436 from LloydNicholson/feat/open-encrypted
Open password-encrypted workbooks (Agile and Standard encryption) (#11)

# Conflicts:
#	ROADMAP.md
#	docs/file-format-parity.md
#	docs/gaps.md
#	docs/target-app-parity.md
2026-10-11 18:06:04 -04:00
lloydandClaude Opus 5.5 1532349227 Encrypted workbooks no password opens are named before asking for one (#11)
gridcraft_xlsx::check_encryption parses EncryptionInfo without a
password, so RC4, Extensible, certificate-only and rights-management
(IRM) files, and damaged ones, get their real message instead of a
password prompt first.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 23:29:28 +02:00
lloydandClaude Opus 5.5 c9f03cc36a XLSX: build encrypted workbooks in code for tests (test-support feature) (#11)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 23:29:28 +02:00
lloydandClaude Opus 5.5 70d857a699 XLSX: decrypt Agile and Standard encrypted packages (#11)
Clean-room from [MS-OFFCRYPTO]: EncryptionInfo parsing, SHA-1/SHA-2 key
derivation with a capped spin count, AES-ECB/CBC. RC4, Extensible and
certificate-only encryption are reported as unsupported.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 23:29:28 +02:00
neilcawseandClaude Opus 5.5 eecfa4074d File formats: CSV/TSV export writes displayed values; templates and .xlsm saved with their own content types
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 16:39:31 -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 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 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
vangel76andClaude Opus 5.5 ed62390244 XLSX: keep unmodelled parts on save (#330)
Pass-through of package content GridCraft does not model: on read the raw
parts are kept with their content types and relationship graph per owner
(package root, workbook, sheet); on write they get fresh part names where
needed and new relationship ids, and the r:ids in kept XML are rewritten.

Kept: custom document properties, ribbon customisation, add-in task panes,
custom XML, links to external workbooks with <externalReferences> (never
followed), connections, sheet query tables, printer settings with the
<pageSetup r:id> (#324), form and ActiveX controls, OLE objects and sheet
backgrounds with their VML shapes (merged with GridCraft's note shapes).
Content whose graph reaches parts GridCraft rewrites is dropped with a
warning; sheet content goes with its sheet and is not copied by Copy Sheet.

Fixes #324

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 13:12:56 +02:00
vangel76andClaude Opus 5.5 bd5c5c1d26 XLSX/IO: read legacy .xls (BIFF8) workbooks (#121)
Clean-room import of Excel 97-2003 workbooks from the public [MS-CFB] and
[MS-XLS] specifications: compound-file streams (FAT, mini FAT, directory
tree), the BIFF8 Workbook stream with Continue records, shared strings,
all cell records, formulas decoded from Ptg tokens (shared and array
formulas, 3-D refs, names, add-in/newer functions by name) with cached
results, number formats, the 1904 date system, merges, column widths, row
heights, defined names and print areas/titles. Encrypted (FILEPASS) and
BIFF5 files are refused with a clear message; everything else is skipped
with a warning. .xls opens as a new unsaved workbook (Save As .xlsx).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 13:09:27 +02:00
vangel76andClaude Opus 5.5 ce411edc91 Checkboxes: ribbon button, Excel's value and Delete rules, XLSX cell controls (#196)
insert.checkbox existed but had no ribbon button, replaced existing values
with FALSE and was written to XLSX as an invalid number format. Now:
Insert > Checkbox (Cell Controls); empty cells start FALSE, other values
stay and display as General; toggling an emptied box checks it and only
checkbox cells toggle; Delete unchecks first, then removes the boxes; XLSX
reads and writes the checkbox as Excel's feature-property-bag cell control
([MS-XLSX] 2.1.22, 2.3.9, 2.4.99).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 12:24:25 +02:00
Brandon Thomas 88d0c772fb Merge pull request #161 from nihilist-narwhal/fix-chart-kinds-roundtrip
Charts: histogram, box & whisker, waterfall, funnel, treemap and sunburst keep their kind through XLSX
2026-10-10 15:50:48 -04:00
Brandon ThomasandClaude Opus 5.5 f75ded37e7 Merge pull request #105 from harrisonoconnorhover/codex/cell-pictures
Add static pictures inside cells with XLSX roundtrip

Rebased onto main (conflicts with #83/#98 and main resolved by maintainer); the contributor's branch does not allow maintainer edits.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 15:02:44 -04:00
Brandon ThomasandClaude Opus 5.5 59c8e36d36 Merge pull request #83 from harrisonoconnorhover/codex/nonspilling-array-export
Preserve array evaluation for non-spilling XLSX formulas

Rebased onto main with a maintainer fix-up (LET bindings via split_last/as_chunks for clippy, no slice indexing); the contributor's branch does not allow maintainer edits.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 15:02:43 -04:00
Brandon Thomas eb4174723d Merge pull request #17 from justinjohn0306/fix/encrypted-file-message
File open: report password-protected (encrypted) files clearly (#11)

# Conflicts:
#	crates/engine/src/io.rs
2026-10-10 13:17:21 -04:00
Harrison O'Connor-Hoover 9dc3aaf9fa Support static pictures inside cells with XLSX roundtrip (#61) 2026-10-10 12:43:27 -04:00
Brandon ThomasandClaude Opus 5.5 f041904bf8 Review fix-up: only CFB files with an EncryptedPackage are encrypted
Every legacy .xls/.doc is a CFB/OLE2 file, so the signature alone isn't encryption. Walk the
compound file's directory (bounds-checked, bounded loops; raw UTF-16 scan when the structure
is unreadable) and report Encrypted only for an EncryptedPackage/EncryptionInfo stream;
other compound files are LegacyBinary with a "save as .xlsx" message. Tests build CFB bytes
in code.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 12:35:36 -04:00
Brandon ThomasandClaude Opus 5.5 20e39fa3cd Review fix-up: clip blank ODS repeats past the sheet edge, struct-update Cell literal
Blank cell and row repeats that run past 16384 columns / 1048576 rows
(padding from writers with larger sheets) are clipped instead of
rejecting the file; any data or merge past the edge is still an error.
convert() builds its Cell with ..Cell::value(value) so new Cell fields
take their defaults.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 12:22:51 -04:00
Brandon ThomasandClaude Opus 5.5 26b3db78db Merge codex/xlsb-import (with origin/main) into codex/ods-import
Resolves the shared integration points for both formats: combined sniff,
file.open spec, file filters, MCP description, docs. open_bytes now lets
sniffed content (ODS or XLSB) win over the extension.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 12:20:30 -04:00
Harrison O'Connor-Hoover 42854f2fb9 Preserve array-sensitive XLSX formulas (#64) 2026-10-10 12:19:52 -04:00
nihilist-narwhal f16fed557e Charts: write and read chartex parts
Histogram, box & whisker, waterfall, funnel, treemap and sunburst charts
were written as clustered columns, and reading skipped such charts in
files made by Excel, which keeps them as cx:chartSpace (chartex) parts.

The writer now writes these kinds as chartEx parts, as Excel lays them
out: the data goes through hidden _xlchart.v1.N workbook names, each
part comes with chart style and colour parts, and the drawing frames it
in mc:AlternateContent with a text-box fallback. Fills are written out
(series in theme accents, waterfall decreases and treemap/sunburst boxes
in their own, a white chart area), so they don't depend on the style
part. The reader reads the parts back (resolving the _xlchart names,
which aren't kept as names) with data, title, axis titles, legend,
labels and colours, and follows mc:AlternateContent in drawings.
2026-10-10 06:25:24 -05:00
harrisonoconnorhover c51e51fe7b #92: import XLSB worksheet data and saved formula results 2026-10-09 22:19:36 -04:00
harrisonoconnorhover da0bf32d8a #16: import ODS worksheet data without overwriting source files 2026-10-09 22:09:09 -04:00
justinjohn0306 2276eabba8 File open: recognize Excel password-protected (CFB) files, report clearly (#11)
Excel-encrypted workbooks are CFB/OLE2 compound files (magic D0CF11E0),
not zip packages. sniff() now returns Format::Encrypted for them, and
open_bytes reports a clear password-protected message instead of the
cryptic 'not a valid zip package' error.
2026-10-08 21:04:07 +05:30
Brandon ThomasandClaude Opus 5.5 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 ThomasandClaude Opus 5.5 b8ff9648a9 M4: PivotTable XLSX round-trip — cache definitions/records, date grouping, pivotTable parts, reader with warnings
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 01:36:28 -04:00
Brandon ThomasandClaude Opus 5.5 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