Commit Graph
275 Commits
Author SHA1 Message Date
Brandon Thomas ca9b3fbbe8 Merge pull request #586 from MarekSpodBiedry:issue-578 2026-10-12 23:35:32 -04:00
Brandon Thomas 591040ce09 Merge pull request #475 from prxnvt:pr/solver-extras 2026-10-12 23:35:22 -04:00
Brandon Thomas d43eefe522 Merge pull request #461 from neilcawse:fix/ribbon-paste 2026-10-12 23:35:19 -04:00
Brandon Thomas 31eb549204 Merge pull request #454 from Dejan-Port:fix-french-header-footer 2026-10-12 23:35:16 -04:00
Brandon Thomas ed971d8f87 Merge pull request #453 from Dejan-Port:i18n-serbian 2026-10-12 23:35:14 -04:00
Brandon Thomas f267530b7c Merge pull request #452 from tydude001:fix/432-filter-list-scroll 2026-10-12 23:35:13 -04:00
Brandon Thomas dd165335e1 Merge pull request #448 from Dejan-Port:select-inserted-chart 2026-10-12 23:35:11 -04:00
Brandon Thomas 4d8af67d0e Merge pull request #635 from MarekSpodBiedry:issue-520 2026-10-12 23:21:57 -04:00
Brandon Thomas c3546f0c97 Merge pull request #634 from MarekSpodBiedry:issue-521 2026-10-12 23:21:56 -04:00
Brandon Thomas ff16e979cd Merge pull request #633 from MarekSpodBiedry:issue-522 2026-10-12 23:21:54 -04:00
Brandon Thomas a507761696 Merge pull request #631 from MarekSpodBiedry:issue-524 2026-10-12 23:21:53 -04:00
neilcawse 95012e03b4 UI: a cut's text pastes again once the clipboard has held other text 2026-10-12 21:19:05 -04:00
neilcawse 4d654c5185 UI: Cmd/Ctrl+V doesn't re-paste a pasted cut's clipboard text either 2026-10-12 20:51:39 -04:00
neilcawse fd1ed6649b UI: Paste doesn't re-paste a pasted cut's clipboard text; Paste keytip (H,V,P) pastes the system clipboard 2026-10-12 20:51:39 -04:00
neilcawse cc65915d16 UI: keytip Copy/Cut publish to the system clipboard; ribbon Paste keeps a newer programmatic copy 2026-10-12 20:51:39 -04:00
neilcawseandClaude Opus 5.5 fa1dcd73e2 UI: Paste button and menus paste the system clipboard; freeze regression test (#273)
In 0.5.0 a click anywhere on the Home ribbon's Paste button (label,
icon or dropdown arrow) froze the app for good. home() called
paste.secondary_clicked() inside ctx.data_mut(); after any click egui
answers that with ctx.input(), which takes the context lock the closure
already holds, so the UI thread waited on itself. Sampling the hung
0.5.0 process on macOS shows the main thread parked in
RawRwLock::lock_exclusive_slow under Context::write <- data_mut <-
ribbon::home. #272 moved the query out of the closure; it landed after
the 0.5.0 release, which is the build both reporters used.

No test ever clicked the Paste button itself, which is how this
shipped. The new test clicks it, then opens its menu with a secondary
click and picks Paste Values, on a worker thread with a timeout so a
regression fails instead of hanging the run. With #272 reverted it
fails (egui's debug lock check panics after 10 s); with it, it passes.
The Paste button gets an accessible "Paste" name so the test (and
screen readers) can find it, the same way Pictures and Border presets
are named.

With the freeze gone, the button still did not do what it says: it
pasted GridCraft's own copy only (GridState::system_clipboard was never
assigned), so text copied in another app gave "Nothing to paste." The
ribbon button, its options menu's Paste, the cell and header context
menus and the macOS Edit menu now read the system clipboard through a
new paste_text host service and paste it like Cmd/Ctrl+V does, falling
back to GridCraft's own copy when there is no text (or no service, as
on the web). Asking egui for the clipboard instead (RequestPaste) was
tried and stalled the macOS event loop until the next input event.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 20:51:39 -04:00
skylar taylor-barrick 9fc4108899 Printing: expose native commands through control discovery 2026-10-12 16:50:03 +02:00
MarekSpodBiedry 85c7fc4d6e Zoom dialog: a Magnification choice sets the percentage to store (#521) 2026-10-12 08:39:42 +02:00
MarekSpodBiedry 2ce94fa581 Data Validation dialog opens on the active cell's current rule (#522) 2026-10-12 08:38:44 +02:00
MarekSpodBiedry dc6f7246a3 Page Setup opens on the sheet's saved margins (#524) 2026-10-12 08:38:09 +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 3f45edf144 Fix ribbon checkboxes sending the pre-click value (#520) 2026-10-12 08:31:39 +02:00
prxnvt 019d5de98e Data: Solver Answer and Limits reports
Builds on the Solver of #327. data.solver takes reports: [answer, limits]
and writes them on new sheets before the model's sheet once a solution
is found. The Answer report lists the objective and variable cells with
their original and final values and each constraint's value, formula,
status (Binding or Not Binding) and slack; cells are named by the
nearest labels to their left and above. The Limits report minimises and
maximises each variable with the others held at the solution, under the
model's constraints, and gives the objective at both ends (Simplex LP
and GRG Nonlinear, without integer constraints).

data.solverReport writes the reports for a given solution and model,
so data.solver's result (which now carries the original values and the
model) can be passed to it as is. The Solver Results dialog offers the
two reports; they are written after Keep Solver Solution or Restore
Original Values.
2026-10-11 22:25:08 -04:00
prxnvt fa2b9566fb Data: Solver Evolutionary method
Builds on the Solver of #327. method: evolutionary runs a genetic search
for models that aren't smooth: tournament selection, blend crossover and
Gaussian mutation inside the variable bounds, feasibility-first ranking
and integer rounding, then a compass search around the best member. It
stops when the population converges, when the best member stops
improving for a number of generations, or at the evaluation budget. A
seeded generator makes runs repeatable. Population size, mutation rate,
random seed, convergence and Require Bounds are options; the method and
its options are saved in the hidden solver_* names. The Solver
Parameters dialog offers the method.
2026-10-11 22:09:10 -04:00
skylar taylor-barrick 587d879f13 Print: adopt craft-print with native settings and job feedback 2026-10-12 03:25:47 +02:00
Dejan PortandClaude Sonnet 5 c59e94297c fix(i18n): correct scattered wrong French translations and add 2 missing keys
The completeness test's failure (missing "Different First Page") was
only the visible tip: fr.rs was missing that key and "Different Odd &
Even Pages" outright, but also had roughly 50 *present* keys mapped to
the wrong value — reading as a real, different English string's French
translation instead of its own. The completeness test only checks that
a translation exists and is non-empty, not that it's correct, so none
of this was caught before.

Examples found by inspection (key => previous wrong value => what that
value actually means):
  "Click to add data"  => "Fermer"                        (= Close)
  "Header"              => "Informations"                  (= Info)
  "Ruler"                => "Enregistrer sous"              (= Save As)
  "Info"                 => "Insérer les cellules copiées…" (= Insert Copied Cells…)
  "Animations"          => "Auteur"                        (= Author)
  "Auto"                 => "Retour"                        (= Back)
  "Previous Comment"    => "Imprimer tout le classeur"      (= Print Entire Workbook)

The wrong values aren't a local shuffle (adjacent keys swapped) — "Info"
drew a value that belongs near the start of the key list while "Info"
itself is near the end, so whatever produced this scattered entries
from unrelated parts of the file onto each other. Given the extent and
that it wasn't contained to one block, patching individual lines risked
missing more of them, so this regenerates every one of the 381 entries
from the English source text (same source list i18n-serbian used),
rather than auditing the existing file entry by entry.

Verified: the existing completeness test (translations_are_unique_...)
now passes end to end — it was failing on a clean main checkout before
this change, purely from the 2 missing keys. Full cargo test -p
gridcraft-ui-egui --lib: 75/75 (was 74/75 on main).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-10-12 02:22:00 +02:00
Dejan PortandClaude Sonnet 5 b60d641083 i18n: add Serbian (Latin script) interface translations
Adds Language::Sr ("sr"), following the existing per-language module
pattern (crates/ui-egui/src/i18n/<lang>.rs with a translate(text) ->
Option<&'static str>). All 381 strings in the JAPANESE master list are
covered, verified by the existing completeness test.

Latin script (sr-Latn), ekavian dialect — the common default for
digital/software Serbian. Cyrillic (sr-Cyrl) could follow as a
separate variant if wanted; this keeps the PR to one script, matching
how every other language here is a single variant.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-10-12 02:14:17 +02:00
tydude001andClaude Opus 5.5 3a8f6f5aa5 AutoFilter: the value list scrolls across the menu's full width (Fixes #432)
The value list kept egui's default auto_shrink, so its scroll bar sat mid-menu after the longest
value and the wheel only scrolled it with the pointer over a value. Keep the height shrinking but
not the width: the scroll bar is at the menu's right edge and the wheel works anywhere over the list.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 19:04:55 -05:00
Dejan PortandClaude Sonnet 5 faba681c99 fix: select a newly inserted chart from Recommended Charts
Resubmit of the selection half of #224 against current main, as
requested — the Delete-key half was a duplicate of #219 and is
already merged.

Insert > Recommended Charts left the prior cell/range selection in
place instead of selecting the new chart, unlike every other object
insertion path (see insert.chart in dialogs.rs, which already selects
the chart it creates). With the selection left on the source data,
pressing Del right after inserting deleted that data and left an
empty chart behind (#214).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-10-12 01:31:29 +02:00
Brandon Thomas 3b19cb80e6 Merge pull request #412 from jsymes21-byte/keytips-table-refactor
Keytips: full Excel sequential Alt table — 364 sequences, badges on every control, generated tests (fixes #33, #49)

# Conflicts:
#	contributors/people.toml
2026-10-11 18:06:06 -04:00
Brandon Thomas 63e60de76c Merge pull request #413 from pechnikov2026-star/i18n-fr
i18n: add French (fr) interface
2026-10-11 18:06:05 -04: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
Brandon Thomas f170b89a92 Merge pull request #420 from neilcawse/fix/structref
Formulas: trim-reference operators (A1:.E10, A1.:E10, A1.:.E10); read unbracketed [[#This Row],Col]

# Conflicts:
#	docs/function-parity.md
#	docs/gaps.md
2026-10-11 18:05:40 -04:00
Brandon Thomas a96f19f02b Merge pull request #409 from shrshk/fix/formula-arg-count-363
Refuse formulas with the wrong argument count on entry (#363)
2026-10-11 18:05:18 -04:00
Brandon Thomas e6773dac3c Merge pull request #433 from derechopiano/fix/autofit-filter-button-spacing
Fix AutoFit width for table and AutoFilter dropdowns
2026-10-11 18:05:13 -04:00
Fabio LussiandClaude Opus 5.5 dbc04ddae0 Rotated text follows the cell's alignment (Fixes #435)
Text turned by an angle was drawn at a fixed anchor (bottom-left for upward,
top-left for downward text) and ignored the horizontal and vertical alignment,
so upright text with Middle Align in a tall merged cell sat at the bottom.

rotated_text_pos places the turned galley's bounding box in the cell per the
alignment, then derives the TextShape anchor from it. General/Bottom keep the
old placement for upright text.

Fixes #435

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 00:00:56 +02:00
lloydandClaude Opus 5.5 312b4c056e UI: password dialog fixes from review (#11)
OK on the untouched field says the password is incorrect instead of
asking again; the Backstage closes once the workbook opens; app.open on
the control channel takes a password and never opens the dialog. Control
protocol docs cover file.open {password}.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 23:29:28 +02:00
lloydandClaude Opus 5.5 c882d169ff UI: ask for the password of an encrypted workbook (#11)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 23:29:28 +02:00
derechopiano 1a6c864235 home.autofitColumnWidth: reserve filter dropdown space 2026-10-11 22:09:51 +01:00
James 7a2361de7f T10: resolve conflicts with main; new upstream commands go live (slicer, pivot chart, forecast sheet, show comments) 2026-10-11 23:54:15 +03:00
James 8e7e247589 Resolve James's real-Excel checks: drop QAT/Backstage and nonexistent View sequences; arrow navigation in the colour palette
- Side-by-side and synchronous-scrolling keytips removed (do not exist in
  James's Excel); Copy H,C / Spelling R,S / Fill H,H / Sparklines N,Z,K
  confirmed already correct
- QAT digits 0-9 and Backstage account/home/options + legacy Share Workbook
  sequences dropped (no meaningful GridCraft target; not left as trash)
- Colour palette (H,H fill and F,C font colour): arrow keys move a highlight
  through the swatches, Enter applies; key events are stripped so the grid
  behind the popup does not react
2026-10-11 23:40:23 +03:00
James d2a691aea8 Fix combo navigation edge cases and wire Page Layout Sheet Options badges
- Arrows/Enter while a keytip combo is open now navigate the list instead
  of moving the filter field's text cursor (events stripped from TextEdit)
- Reopening a combo resets the filter: the reset frame requests a repaint
  so the stale filtered list never lingers on screen
- Page Layout Sheet Options: Gridlines View/Print and Headings View/Print
  checkboxes painted with VG/PG/VH/PH badges and keytip toggles
- Background rebound from PG to PGB (Excel's Page Setup GB badge); PG is
  no longer terminal
2026-10-11 23:40:23 +03:00
James 7ba871c6f2 Excel-style combo navigation (type to filter, arrows to move) and complete tab badges
- editable_combo: every dropdown keytip opens with a filter field focused;
  typing narrows the list, Up/Down move the highlight (wrapping), Enter or
  click applies, custom text applies where valid (font size). Fixes arrows
  and typing in ALT+H FF/FS/N.
- Audited all 54 painted ribbon ids against the table: real mismatches fixed
  (Data Sort/Text-to-Columns/Remove-Duplicates/Subtotal, Review Spelling/
  Accessibility/New Comment/Notes, View Zoom/Freeze, Formulas Insert Function/
  Name Manager/Define Name/Use-in-Formula/Error Checking/Evaluate, Insert Link/
  Comment/Header-Footer/Sparklines, Home Protect Sheet).
- keytips.json: dialog kind for real dialog openers; control kind for the 6
  chart-type buttons, 7 formula-category buttons, and Orientation (HFQ added,
  was missing); M-family restructured to Excel semantics (ML/MT/ME/MO/MG/MQ
  fire directly, MI1 opens Financial) with 14 unreachable children dropped;
  383 entries total.
2026-10-11 23:40:23 +03:00
James cbd9bb51c6 Dropdown keytips open their controls instead of firing empty commands; complete View badges
- New Action::Control routes a keytip to its ribbon control (popup/dropdown
  open, checkbox toggle, button handler) instead of an engine command with
  empty params. Fixes ALT+H FF/FS/N/H/H error boxes.
- Ribbon consumes a one-shot ui.keytip_invoke: font/size/number combos
  converted to the popup pattern (ComboBox has no open_memory), fill/font
  color menus force-open via SetOpenCommand, 100% zoom and Formula Bar run
  their handlers.
- keytips.json: FF/FS/N/H/H -> control kind; View/Formulas/Data dialog
  openers (WQ zoom, HFM format cells, HO*, MV, AWG, sparkline types) and
  control WVF; MSP/HVP re-targeted; dropped 15 unreachable Home sub-items
  and non-Excel HWS shrink-to-fit.
- View tab: badges on workbook views, gridlines/headings, formula bar.
- Generated suite: 399 tests incl control-kind arm; direct tests 18.
2026-10-11 23:40:23 +03:00
James 7591fca086 T7: generated per-sequence regression tests (412 tests, catalog-probed)
cargo xtask keytips now emits tests/keytips_generated.rs alongside the
table: one end-to-end test per sequence, asserting exactly what its
action does today. The generator probes the live engine catalog at
generation time (blank workbook, empty params), so each live command
asserts journaled / ran clean / surfaced its missing-params error;
pending asserts silence; dialogs assert the dialog opens; tabs assert
the ribbon switch; group levels assert the prefix stays armed.

- pending-but-landed targets get live assertions and a generation
  warning (HWS home.shrinkToFit and MAA formulas.removeArrows had
  landed since population - flipped to live)
- unreachable-sequence validation: any seq with a terminal prefix
  entry is rejected (HCP dropped - HC Copy fires first)
- ENV_SENSITIVE list keeps the checked-in file byte-stable across
  machines (review.spelling uses the system dictionary)
- sample_sequences_work_with_text_before_key covers IME text-first
  event order for one representative of each action kind
- generated_test_count_matches_the_table pins the table size

518 ui-egui tests green; all 8 CI gates pass.
2026-10-11 23:40:04 +03:00
James cd5f3f0a71 T6: pending keytips resolve at runtime and go live when their command lands
- Action::Pending now consults the engine catalog at fire time: silent
  no-op while the command is missing, runs it once it exists - no table
  edit needed when a future feature lands.
- Stripped stray backticks from 7 pending target ids so catalog lookup
  can ever match them.
- gridcraft-engine: doc(hidden) register_test_command hook so UI tests
  can prove the go-live path without touching production code.
- Tests: pending_sequences_are_silent_no_ops (no dialog/toast/journal),
  pending_sequences_go_live_when_the_command_lands (fake command fires
  via its reserved sequence), every_sequence_terminates_without_panicking
  (all 413 sequences pressed end-to-end).
2026-10-11 23:40:04 +03:00
James 659a4d5bd3 Real-Excel keytip corrections from James (Home/Insert/Formulas)
- HP -> home.percent (was wrongly numberFormat); HN stays the Number dropdown.
- H3 -> home.underline fires directly; H3U/H3D dropped as unreachable.
- HAT/HAM/HAB -> Top/Middle/Bottom Align (were unbound).
- NCM/NZT/NZS -> modern Comment/Text Box/Symbol (NC2/NZTX/NU kept as
  legacy aliases); MI1 -> Financial first item.
- Badges on the three dropdowns (font FF, font size FS, number format N)
  and the vertical alignment buttons; Print Titles paints PI.
2026-10-11 23:39:35 +03:00
neilcawseandClaude Opus 5.5 9ce910f87f Formulas: trim-reference operators (A1:.E10, A1.:E10, A1.:.E10); read unbracketed [[#This Row],Col]
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 16:39:31 -04:00
James 95b3641725 Paint keytip badges on every ribbon control (issue #49)
The badge painter only covered five sites, so pressing Alt+H showed
nothing past the tab letter. Now every control with a catalog command id
paints its badge automatically:

- control_badge(prefix, id): the rest of a control's unique sequence
  (HFC -> "FC" on Font Color), or the common group letter when many
  variants land on one control (HBA..HBW -> "B" on Borders).
- anchor_badge(prefix, targets): menu anchors resolve to the dominant
  group-level candidate (Pictures shows "P", not SmartArt's "M").
- ribbon.rs: 90+ control sites now paint through control_keytip/
  anchor_keytip (mechanical sweep + hand-wired anchors); split buttons
  paint at their arrow rect.
- Offscreen snapshot verified: at prefix H the Home ribbon paints
  V/X/C/FP/1/2/3U/FC/H/FG/FK/AL/AC/AR/5/6/WW/MC/K/0/9/L/T/J/I/D/O.
- Tests: 29 lib + 14 keytips, all 8 CI gates green.
2026-10-11 23:39:11 +03:00
James f11d74ee7c Populate the full Excel keytip table (408 sequences, issues #33 and #49)
Population of keytips.json from the collected Excel Alt-sequence set:
- 408 curated entries: 10 tabs, 354 command binds (64 reserved pending,
  290 live catalog commands), 2 dialog openers, 42 group levels.
- Bind-all policy: sequences whose command does not exist yet bind to the
  canonical future id as Action::Pending -- badge shows, invocation is a
  silent no-op until the command lands (ids from docs/parity-checklist).
- Group levels: 46 command entries that are strict prefixes of deeper
  sequences were demoted to menu openers so the trie never fires early
  (HV must not paste; it waits for the variant letter).
- Fire-immediately restores: HC Copy, HAN Accounting, FA Save As, FO Open,
  FI Info. Unreachable legacy aliases (HCC, HANM, FA1, FAY3, FOC, FOO, FIP)
  dropped: the parent fires first.
- ES stays a terminal dialog opener as in Excel: the A/F/T/V variants are
  dialog mnemonics, not trie sequences.
- Escape pops one trie level and returns to the armed root at a single
  letter; keytips.json is the single modifiable source; xtask keytips now
  emits through rustfmt so --check is byte-stable.
- Tests: 99 pass (27 lib + 14 keytips + suite), all 8 CI gates green.
2026-10-11 23:37:45 +03:00