package.rs keeps GridCraft's Package, Rel and ZipOut, now on craft_opc::LazyPackage
and craft_opc::ZipOut (on craft-zip). Limits stay GridCraft's (200,000 entries,
512 MB a part, 1 GB a package) and so do the budget rules, which craft-opc took
from GridCraft. The budget tests moved with them. normalize, resolve and
split_dir are craft-opc's (the same code).
Every craft-libs crate moves to aa84415b. craft-xls now reads data validation;
until GridCraft maps it, a sheet with rules still warns that .xls data validation
is not imported. ods.rs matches entity names through a slice, since the new
dependencies make the old as_ref() call ambiguous.
The BIFF8 reader moved to storytold/craft-libs as craft-xls (#878). GridCraft
keeps the mapping onto its model in xls.rs: formulas parsed, Excel's implicit @
for legacy formulas, pixel widths and heights, styles interned per XF, sheet-name
checks, print areas and titles, calculation settings and GridCraft's warning text.
The workbook now opens on the sheet it was saved on when that sheet is visible,
else on the first visible sheet (from #3551 by @Morzilla, whose test is kept).
RString cells are read as text.
Every craft-libs crate moves to one revision, 119415f4.
* engine: bound Advanced Filter, Remove Duplicates, AutoFilter, Circle Invalid Data; one-pass AutoFit; saturating range dimensions
* address review: AutoFit scans each run of adjacent selected columns separately
* address review: report a truncated circle-invalid scan, no spill scan for plain cells in Replace, one pass for many AutoFit runs
* address review: warn in the app when Circle Invalid Data stopped early; Replace test requires success
* address review: the scan note joins an open-time notice; say cell visits
* FORMULATEXT and the cell editor keep a hidden formula's source hidden
* address review: recalculate formulas when sheet protection changes
* address review: skip the full recalculation for a no-op unprotect
* address review: recalculate on protect/unprotect without marking the edit structural
* ui-egui: embed craft-fonts files only from inside the checkout
The build hook canonicalised each manifest row's file and embedded it
with include_bytes! wherever it led, so an absolute path, a .. path or
a symlink in a craft-fonts checkout could put any readable file of the
build machine into the binary. Manifests and font files must now
resolve inside the canonical checkout directory.
* address review: register the manifest path before validation and keep the Chinese manifest fallback optional
The one-line label widened the Insert tab enough to scroll the Equation button
out of view at 1400 px, which broke the equation editor tests in CI.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Upstream retires WordArt as a display name (display_names guard); the
button and its tooltip use the already translated Decorative Text key,
and the parity checklist is regenerated.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Use the shared craft-i18n Ukrainian term, distinct from Diagram (Схема).
Also translate the remaining Chart-labelled strings that were still English.
Co-authored-by: FredApps <FredApps@users.noreply.github.com>
* Naming: use Diagram and Decorative Text in the feature catalog
* Naming: align the Chinese decorative text term
* test(naming): guard neutral display labels
* Naming: Diagram no longer repeats the chart word in de, uk and ro
German Schema and Ukrainian Схема match craft-i18n#211; Romanian Schemă
avoids GridCraft's own chart word Diagramă. A catalog test checks every
shipped language translates both labels and that Diagram differs from
Chart/Charts. The display-name guard now handles escaped char literals
and any #[cfg(test)] item, asserts it scanned catalog.rs and a minimum
of files and literals, and tests word boundaries. The catalog test
asserts each ID appears once. Docs carry timestamps and revision history.
---------
Co-authored-by: FredApps <FredApps@users.noreply.github.com>
* UI.1265: align CJK fallback text with the Latin baseline
Use epaint's existing baseline alignment for system CJK fallback faces
and embedded faces tagged with CJK scripts. Mixed CJK, Latin and digits
then share a baseline in cells, editors and window titles.
Add regression coverage for zoom, font styles, wrapping, fixed-height
clipping, vertical alignment, editor height and title truncation.
Refs #1265, #2621.
* UI.1265: assert title baselines and document visual validation
* UI.1265: add baseline comparison and review validation
* UI.1265: adapt tooltip regression after upstream merge
The upstream shortcut update uses the runtime OS to choose tooltip text.
Use the harness OS for the existing split-button test expectation too.
Validation: cargo xtask ci; all 10 steps pass; 3,002 tests passed, 1 ignored, no exclusions.
* UI.1265: propagate CJK fallback to installed fonts
* UI.1265: align fallback baselines across cells
* UI.1265: align wrapped and unwrapped cell text
* UI.1265: preserve blank lines in wrapped cell alignment
* UI.1265: preserve centered fallback placement
* UI.1265: find CJK cell text by its visible bounds
Use the overlap of text ink, clip rect and cell rect to locate painted text
instead of testing a fixed offset from the galley origin. Baseline-aligned
fallbacks can move that origin above the cell on Ubuntu.
Keep the existing baseline and wrapping assertions unchanged.
Validation: cargo xtask ci on macOS; all 3 cjk_baseline tests on Ubuntu 24.04 x86_64.
---------
Co-authored-by: FredApps <153173854+FredApps@users.noreply.github.com>
* M12.AR4: preserve Arabic logical text in bidi display and editing
* M12.AR4: drop the stale "no bidi" note from the RTL sheet status
* M12.AR4: open the Arabic editors and place the caret through key and pointer events in tests
* M12.AR4: skip the conditional-format lookup in the formula bar unless a rule sets reading order
* M12.AR4: test that the caret after typed Arabic is drawn at the text's left end (#1070)
* M12.AR4: pass the theme body font in the reading-order style test
* M12.AR4: adapt the Arabic UI tests to egui 0.37 (row direction, editor ids, Ctrl+End to the logical end)
* M12.AR4: read the active sheet through Workbook::active_sheet() in the formula bar
main made `Workbook::active_sheet` an `ActiveSheet` (shared between windows on one
workbook); the formula bar's reading-order lookup takes the index from the accessor.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* M12.AR4: keep explicit Left on wrapped right-to-left cells and trailing spaces in the editor
Wrapped cell text lays out every row from the left when the painted alignment is Left, instead of aligning right-to-left rows to their start. The cell and formula bar editor keep trailing whitespace in their layout so a right-to-left entry ending in a space keeps the caret inside the text.
* M12.AR4: keep Right and General on right-to-left sheets aligned right in wrapped cells
* M12.AR4: keep right-aligned Arabic with a marked first letter inside its cell
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: FredApps <153173854+FredApps@users.noreply.github.com>
Co-authored-by: FredApps <FredApps@users.noreply.github.com>
* M12.AR2: Arabic font fallback in cells and the interface (#229)
* M12.AR2: reserve the preferred Arabic file only once it has loaded
load_fallback treated fontconfig's Arabic file as already loaded even
when load_preferred_arabic could not load it, so a system Arabic face
from the same file was skipped and the chains could end up with no
Arabic system face. The file is now reserved only when the preferred
face is in the font set; the candidate loop moves to load_faces so a
test can drive it with a fixture file.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* M12.AR2: say where fontconfig's Arabic choice applies
fontconfig's Arabic face leads the Arabic fallbacks, so it draws Arabic
where the UI or cell font has none. A UI font with Arabic of its own,
such as DejaVu Sans in the Flatpak, still draws interface Arabic (#229),
which is left for a follow-up. The docs and the test's doc comment no
longer say the choice comes first in every chain.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: FredApps <153173854+FredApps@users.noreply.github.com>
Co-authored-by: FredApps <FredApps@users.noreply.github.com>
A sheet whose filter hides a million rows walked every hidden row
several times per frame (cells, gridlines, headers), rebuilt the row
index, the outline and the used range every frame, and a conditional
format over a whole column rescanned it every frame for its statistics.
- LineIndex::next_visible / visible step over a run of hidden lines in
one O(log n) search; the grid's row and column loops use them.
- The grid keeps the active sheet's line index, outlines, used range and
CfCache between frames, tied to the sheet by a Weak: any change goes
through Arc::make_mut, which moves or copies a sheet that has a weak
reference, so the cache can't outlive a change.
- Scroll offsets for the scrollbars and the scroll limit come from the
line index instead of walking every custom row.
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Leaving a merged cell downwards kept the start column and dropped the
column offset Enter passes to return to the Tab run's start column, so
Tab A2 -> B2:C3, Enter landed on B4 instead of A4. Keep the computed
column (and the computed row when leaving to the right).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Shift+Left/Up from a selected merged cell now widen the selection past
its edges, Shift+arrows shrink an area back over a merged cell, and
Enter/Tab leave a selected merged cell instead of walking the cells it
covers. Inside a larger selection Enter visits a merged cell once.
Fixes#3619
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
craft-update, craft-window, craft-print and craft-ui move from craft-libs
c5a1cbfb to c7c84230, a branch with storytold/craft-libs#687 and #696
merged into craft-libs main.
- The check result window shows whenever the updater's status is not
idle, so the first start after an update reports that it installed or
why it failed. Restart to Update asks the app to quit once nothing is
unsaved.
- An update's close request quits the app (Quit asks about each unsaved
workbook), so every workbook window closes.
- on_exit starts the install helper of a ready update before the macOS
process exit.
Esc during a header-boundary resize was only peeked at, so the grid's
own Esc handling saw it as well and dropped a marked copy and Format
Painter. The cancel now removes the Esc presses from the frame's input,
with any modifiers, as before, cancelling the drag. The regression test
covers a pending copy and sticky Format Painter for rows and columns,
with the release in a later frame or the same frame, and Shift+Esc.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A series like =FreshClock, where the workbook name FreshClock is NOW(),
was cached because only the literal series text was searched for
volatile calls. The check now also follows defined names the formulas
use (workbook or sheet scope, bare or sheet-qualified, LAMBDA names),
the way the evaluator looks them up. Nesting deeper than 8, cycles and
more than 64 lookups per chart count as volatile, so a chart whose
stability isn't established is not cached.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Scroll the 3,000-rule list to a row that was off screen and move and
delete that rule through its own buttons; give one rule a label of 200
ranges whose buttons start outside the dialog, scroll sideways, then move
and delete it. Each test checks the intended rule changed.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The width of a prefix plus an ellipsis is not monotone when the text has a
line break, so the binary search could drop a label that fits. Also pass the
series index to plot_kind in the data table (upstream/main does not compile
without it).
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
A refused size no longer replaces the size the release applies to the
selection, and Esc puts back the redo stack the drag began with.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
When the edge sheet was already active nothing changed, so the strip was not
scrolled back to it. A Ctrl-click on the arrow now asks for the reveal itself.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
A long range list pushed the move and Delete buttons out of the vertical-only
scroll area, where they could not be clicked.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Move retain_docs out of the per-chart paint path into SheetApp::logic so closed
documents are forgotten even when no chart is painted. Charts whose series call
NOW, TODAY, RAND, RANDBETWEEN or RANDARRAY bypass the cache because their
resolved values change between evaluations.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Scroll positions were stored by (window, sheet index), and nothing re-keyed
them when sheets were inserted, deleted or moved. A new PivotTable sheet,
which goes in front of its source, opened at the source's position, and the
source took over whatever was stored at its new index. Positions are now
keyed by (window, sheet uid), so they follow the sheet through inserts,
deletes, moves and undo. A closed window's positions are dropped. Saving the
active cell still happens when no window is active.
Co-Authored-By: Olivier <5681030+tutis@users.noreply.github.com>