1057 Commits
Author SHA1 Message Date
Dylan M. Taylor 7f6a79fd98 Fix Flatpak permissions for update checks and self-updates (#3803)
* fix(flatpak): allow release checks and self-update helpers

* test: keep Flatpak permission parsing within strict Clippy rules
2026-11-11 14:24:13 -05:00
Dylan M. Taylor e258db5f19 Updates: take craft-update from craft-libs main at 6e03f65bf 2026-11-11 12:44:25 -05:00
Dylan M. Taylor bc2dabc7ea FORMULATEXT and the in-cell editor keep Hidden formulas hidden (#3298)
* 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
2026-11-11 05:48:31 -05:00
FredApps b79e992576 Merge branch 'main' into fix/3321-manage-rules 2026-11-11 07:57:35 +01:00
Dylan M. Taylor a84259d58c ui-egui: embed craft-fonts files only from inside the checkout (#3281)
* 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
2026-11-10 18:04:49 -05:00
FredAppsandFredApps a36e4987c1 i18n(uk): translate Chart as Діаграма (#3703)
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>
2026-11-10 17:07:10 +01:00
FredAppsandFredApps 457bc7e374 Naming: use Diagram and Decorative Text in the feature catalog (#3622)
* 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>
2026-11-10 16:13:13 +01:00
RockerHXandFredApps ec12eba83e UI.1265: align CJK fallback text with the Latin baseline (#3081)
* 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>
2026-11-10 12:44:19 +01:00
e9addf52fe Arabic bidi layout and cell reading direction in the grid and editors (#947)
* 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>
2026-11-09 15:55:43 +01:00
cda767b49b Arabic font fallback in cells, the formula bar and the web (#931)
* 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>
2026-11-09 15:54:55 +01:00
Valentin KleinandClaude Opus 5.5 7102429a9a perf(grid): skip hidden row runs and keep sheet geometry and CF statistics between frames (#3580) (#3629)
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>
2026-11-09 08:46:53 +01:00
dotCooCoo 3004a05e46 Updates: take craft-update from craft-libs main at 1b34eba41 2026-11-08 19:45:34 -08:00
dotCooCoo 99bbd237fc Updates: the updater reports installing, ready, installed and failed, and installs at exit
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.
2026-11-08 11:53:25 -08:00
vangel76andClaude Opus 5.5 684f051f0d Manage Rules: test reaching rules by scrolling down and sideways
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>
2026-11-08 12:51:27 +01:00
FredApps 94a8fb084a Merge pull request #1152 from vangel76/perf/chart-measure-allocs
Charts: label fitting and legend measuring avoid hundreds of text layouts per render (#1149)
2026-11-08 12:08:59 +01:00
vangel76andClaude Sonnet 5.5 019033e095 Merge upstream/main into fix/3321-manage-rules
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-07 18:37:04 +01:00
vangel76andClaude Sonnet 5.5 93dab0c420 Merge upstream/main into fix/3350-ctrl-tab-arrows
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-07 18:36:49 +01:00
vangel76andClaude Sonnet 5.5 9354fdb0c4 Chart: fit labels with a line break by a linear scan
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>
2026-11-07 17:37:20 +01:00
vangel76andClaude Sonnet 5.5 05cffdceb1 Tab strip: test the Previous arrow reveal for the already active first tab
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-07 17:27:07 +01:00
vangel76andClaude Sonnet 5.5 87cb0f11d2 Tab strip: reveal the edge tab after a repeated Ctrl-click on an arrow
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>
2026-11-07 17:22:54 +01:00
vangel76andClaude Sonnet 5.5 d7c0158f0a Manage Rules: let the rule list scroll sideways
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>
2026-11-07 17:08:44 +01:00
FredApps 8774fa45fb Merge pull request #3507 from ZIDAN44/fix/3485-scroll-per-window
View: a sheet keeps its own scroll position when sheets move (#3485)
2026-11-07 15:38:25 +01:00
Zinadin ZidanandOlivier 1688b43ae2 View: a sheet keeps its own scroll position when sheets move (#3485)
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>
2026-11-07 00:27:07 +06:00
Zinadin Zidan 7d3ede854f Sort: the closed Sort by box names the column, as its list does (#3446)
The Sort dialog's closed "Sort by" box showed only the stored column
letter ("B") while its open list showed "B: Revenue". It now looks the
letter up in the dialog's column labels and shows the same label, falling
back to the bare letter for a column outside the data block.
2026-11-07 00:27:07 +06:00
FredApps 0a58f94517 Merge remote-tracking branch 'origin/main' into pr 2026-11-05 14:49:58 +01:00
Pranav 4e43ad8868 UI: RefEdit follow-ups: a dialog keeps the sheet it was opened on, a click on the selected cell picks, quoted sheet names in Solver (#3180)
* UI: a dialog's reference boxes belong to the sheet it was opened on, recorded when it opens rather than at the first pick

* UI: a click on the cell already selected writes it into the reference box being picked into

* Solver: references split into areas only at commas outside quoted sheet names, through one splitter shared with the reference boxes

* Solver: a constraint splits at its relation only outside quoted sheet names, in constraint text and in a model loaded from cells

* Solver: Save Model counts a constraint's areas outside quoted sheet names, and reads a number on the right side as one value whatever its separators

* UI: a Ctrl+click that follows a link is no pick of the cell already selected

The press on the grid tells the reference box being picked into that a
cell was selected only in the branches that select: Shift+click, Ctrl+click
that adds a cell, and a plain click. A Ctrl+click on a link's text follows
the link and selects nothing, so a link back to the selected cell no longer
replaces the box's text.

* UI: while a reference box picks, a second quick click on a cell picks it

A click on the same cell within the double-click interval started editing
the cell and skipped the pick, also when the earlier click came before the
box was clicked into. While a reference box is the one grid selections
fill, the double-click handling is skipped and the click picks.

* Docs: reference boxes take a second quick click as a pick; a followed link is none

* UI: while a reference box picks, a click on a link or checkbox picks its cell

A link was followed (Go To moved the selection into the box, and a web
link's question replaced the dialog) and a checkbox was toggled. While a
reference box is the one grid selections fill, a click only picks the cell
clicked, with or without Ctrl. The test of the Ctrl+click on a link back to
the selected cell becomes part of a test of links on the same sheet, a web
link and a checkbox.
2026-11-05 13:20:51 +01:00
Zinadin ZidanandClaude Opus 5.5 cb05971659 i18n: German context menus' Insert reads "Zellen einfügen", not a second "Einfügen" (#2874)
German showed "Einfügen" for Paste and again for Insert in the cell menu
("Einfügen…") and the row and column header menus ("Einfügen"). The cell
menu's Insert… now reads "Zellen einfügen…", as Excel's German menu does.
The header menus' Insert gets its own key, "Header Menu|Insert", German
"Zellen einfügen"; the plain "Insert" stays as the Insert dialog's title
and button use it, and every other catalog gets the new key with the text
it shows today.

A test reads the three menus' items from menus.rs and checks that no two
read alike in German.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-05 12:04:32 +06:00
Francisco Herreraandalosslessdev 1fb191571b Charts: draw every doughnut series as a ring (#1827)
* Charts: draw every doughnut series as a ring (#1827)

* Charts: submit doughnut hole size and first slice angle when the drag ends (#1827)

---------

Co-authored-by: alosslessdev <alosslessdev@users.noreply.github.com>
2026-11-05 05:13:35 +01:00
FredAppsandClaude Opus 5.5 ede12f9da6 About: credits tables fit without side-scrolling and their columns resize (#3320)
* About: credits tables fit without side-scrolling and their columns resize

The Contributors table and the Models table were egui Grids inside a
two-way scroll area: they opened wider than the dialog, so they scrolled
sideways, and Company and Model sat almost touching. Both are now
egui_extras tables. Each column opens at the width of its header and widest
cell, the spare width goes to the text columns (Name; Company and Model),
and every column edge can be dragged. Widening a column grows the table
like a spreadsheet, and only then does it scroll sideways; the header stays
put while the rows scroll. Counts and dates are right-aligned and every
cell is vertically centred.

The sorted column stays highlighted and its direction shows on the
toolbar's sort-order button, so headers no longer reserve room for an
arrow. The opening widths come from fit_widths, a pure function with unit
tests that a fitted table fills its room exactly and that only the text
columns give way when room is short.

The About dialog opens 820 points wide, so every column fits at its natural width.

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

* Let every credits column be dragged, and refit changed tables

The last column was egui's remainder column, which has no drag handle, so
it could only be resized from the edge before it. It is now an ordinary
column with its own handle.

A table keeps its column widths, so switching to a longer name left the
Name column at its old width and clipped the text. The table now goes
back to the opening fit whenever that fit changes: a longer widest cell
or a resized window. Dragged widths are dropped at that point.

fit_widths could overflow the room when one column hit the minimum,
because the other columns did not take up its share. Columns now give
way in proportion to their width above the minimum.

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

* Refit credits tables on what they measure, not the fitted widths

Comparing the fitted widths missed the case it was meant for. Name is the
only growing column, so a longer name takes its extra width from the
spare room and the fit comes out the same: a dragged Name width stayed,
clipping the longer name.

It could also drop dragged widths by accident. The fit comes from the
available width inside the scroll area, which scrolling can nudge, so
scrolling a widened table could reset it.

The table now compares the natural widths and the clip rect's width,
which scrolling does not move.

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

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-05 04:33:46 +01:00
FredApps 73fad54671 Merge origin/main into pr/form-controls 2026-11-05 04:05:43 +01:00
vangel76andClaude Sonnet 5.5 7e828a982c Tabs: Ctrl-click on the sheet arrows jumps to the first or last visible sheet (#3350)
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-05 01:02:21 +01:00
vangel76andClaude Sonnet 5.5 51e242e1fa Manage Rules test: check the dialog rect and which rule was deleted
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-05 00:52:15 +01:00
vangel76andClaude Sonnet 5.5 8c1c7cfd27 Manage Rules: scroll the rule list and lay out only the visible rules (#3321)
The dialog laid out one row per rule with no height limit and ran
home.manageRules (copying and serialising every rule, and journaling a
step) on every frame. A sheet with thousands of rules made the window
as tall as the whole list and the application window go blank.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-05 00:47:47 +01:00
skylar taylor-barrick 919a6b58fe Merge pull request #2203 from Higgs32584/fix/2181-link-open-confirmation
link: require confirmation for programmatic link.open (#2181)
2026-11-05 00:30:08 +01:00
prxnvt b9595ccdec Merge origin/main into pr/form-controls
Conflicts:
- crates/xlsx/src/read.rs: main's names.unique() kept with this branch's
  (sheet, read_controls) result from read_sheet.
- crates/ui-egui/tests/it/keytips_generated.rs: regenerated with
  cargo xtask keytips from the merged keytips.json (413 sequences).
- docs/file-format-parity.md, docs/ui-parity.md: header and revision
  history keep main's entries and this branch's form-controls entries.
2026-11-04 13:01:54 -05:00
Dylan M. Taylor e5f6fa8197 ui-egui: reference colours through a map; cap fill-character repeats per cell (#3311) 2026-11-03 22:57:23 -05:00
Brandon Thomas ed2347782d Merge PR #3252 (author's fix: an expanded formula bar leaves room for the worksheet)
# Conflicts:
#	crates/ui-egui/src/formula_bar.rs
2026-11-03 10:00:05 -05:00
Brandon ThomasandClaude Opus 5.5 865a789c73 Review fixes for #3223, #3253, #3254, #3252, #3239, #3244 and #3268
- #3223: sniff the first 64 KiB for a web page and skip JSON and files over the text-import cap, so
  every CSV/TSV is no longer decoded in full before the size check.
- #3253: SYLK relative offsets use checked arithmetic (no overflow on R[9223372036854775807]); at
  most 1024 column-width records are kept; regression test.
- #3254: a single selected merged cell searches the whole sheet, as one selected cell does.
- #3252: the formula bar's height cap is half the room below the ribbon, not half the window, so
  the worksheet stays visible in a short window (CodeRabbit Major).
- #3239, #3244, #3252, #3268: es/de/cs/zh/ko/ru/pt entries for the new interface strings.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-03 09:59:27 -05:00
Brandon Thomas 166234eff0 Merge PR #3268 2026-11-03 09:55:39 -05:00
Brandon Thomas 6c386f79ed Merge PR #3252 2026-11-03 09:55:39 -05:00
Brandon Thomas 5ae7ecfab9 Merge PR #3244 2026-11-03 09:55:39 -05:00
Brandon Thomas 0081e4f29e Merge PR #3239 2026-11-03 09:55:38 -05:00
Brandon Thomas ebf762a03a Merge PR #3254 2026-11-03 09:55:38 -05:00
Brandon Thomas d7b53fcc20 Merge PR #3267 2026-11-03 09:55:37 -05:00
Brandon Thomas 31156f7949 Merge PR #3251 2026-11-03 09:55:37 -05:00
Brandon Thomas 502fac89fa Merge PR #3237 2026-11-03 09:55:37 -05:00
Brandon Thomas 56cc52eb39 Merge PR #3250 2026-11-03 09:55:37 -05:00
Brandon Thomas a6b7cf5c2a Merge PR #3243 2026-11-03 09:55:37 -05:00
Brandon Thomas 85f09f05d6 Merge PR #3240 2026-11-03 09:55:36 -05:00
Brandon Thomas cb4b7af1e3 Merge PR #3229 2026-11-03 09:55:36 -05:00