Commit Graph

40 Commits

Author SHA1 Message Date
Brandon Thomas 9bf5ecaf04 Merge main into VBA preservation; save macros only into .xlsm (an .xlsx never carries a VBA project); drop the shell round-trip script (review fix-up for #19)
The Rust round-trip test covers what scripts/check-vba-roundtrip.sh checked.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 15:20:45 -04:00
Brandon Thomas 0305d2a666 Merge pull request #335 from Losminek/cs-pr
i18n: Czech interface language (cs)

# Conflicts:
#	ROADMAP.md
#	contributors/people.toml
#	crates/ui-egui/src/control.rs
#	crates/ui-egui/src/i18n.rs
#	crates/ui-egui/src/theme.rs
#	docs/localization-parity.md
2026-10-11 12:10:06 -04:00
Brandon Thomas 839072c6dd Merge pull request #327 from vangel76/feat/solver
Data: Solver with Simplex LP, integer branch and bound and a nonlinear method (#326)

# Conflicts:
#	crates/ui-egui/src/dialogs.rs
#	crates/ui-egui/src/i18n.rs
#	crates/ui-egui/src/i18n/ko.rs
#	crates/ui-egui/src/i18n/pt.rs
#	crates/ui-egui/src/i18n/ru.rs
#	crates/ui-egui/src/i18n/zh.rs
#	crates/ui-egui/src/ribbon.rs
#	crates/ui-egui/tests/interaction.rs
#	docs/gaps.md
#	docs/parity-checklist.md
#	docs/target-app-parity.md
#	docs/ui-parity.md
2026-10-11 12:07:34 -04:00
Brandon Thomas 1dbad7768d Merge pull request #320 from vangel76/feat/analysis-toolpak
Data: Analysis ToolPak with 13 tools and the Data Analysis dialog (#312)

# Conflicts:
#	crates/ui-egui/src/dialogs.rs
#	docs/gaps.md
#	docs/parity-checklist.md
2026-10-11 12:06:42 -04:00
Brandon Thomas 925ff53122 Merge pull request #303 from vangel76/fix/chart-category-axis
Charts: Select Data edits the category axis labels; blank corner makes column 1 the categories (#287)

# Conflicts:
#	crates/engine/src/tests.rs
#	crates/ui-egui/src/dialogs.rs
#	crates/ui-egui/tests/interaction.rs
#	docs/chart-parity.md
2026-10-11 12:06:39 -04:00
Brandon Thomas fe9e3163f0 Merge pull request #301 from vangel76/fix/recommended-charts
Charts: Recommended Charts opens a dialog of chart types with previews (#215)

# Conflicts:
#	crates/engine/src/tests.rs
#	crates/ui-egui/tests/interaction.rs
#	docs/chart-parity.md
2026-10-11 12:06:37 -04:00
Brandon Thomas 685802ee9f Merge pull request #306 from vangel76/feat/pivot-calculated-field
PivotTables: calculated fields (pivot.calculatedField) (#304)

# Conflicts:
#	ROADMAP.md
#	docs/gaps.md
#	docs/parity-checklist.md
#	docs/target-app-parity.md
2026-10-11 12:05:52 -04:00
Brandon Thomas 2f6c2cd486 Fix-up: Spanish and German strings for Interface size (#294 met #242/#271); rustfmt after merges
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 11:59:24 -04:00
Brandon Thomas 505d001ad4 Merge pull request #293 from vangel76/fix/name-manager-new
Name Manager: New… and Edit… open the name dialog and return to the manager (#238)

# Conflicts:
#	crates/engine/src/tests.rs
2026-10-11 11:45:00 -04:00
Brandon Thomas fb9266f479 Merge pull request #271 from arekown/german-translation
Add German (de) interface language

# Conflicts:
#	ROADMAP.md
#	crates/ui-egui/src/i18n.rs
2026-10-11 11:44:58 -04:00
Brandon Thomas 0a65ffc31a Merge pull request #219 from Zarvinx/fix-keyboard-chart-delete
Delete selected charts with the keyboard

# Conflicts:
#	ROADMAP.md
2026-10-11 11:44:53 -04:00
Losminek dd8016225d Merge origin/main into cs-pr
The only conflict was contributors/people.toml: other contributors appended
their entries at the end of the file in the meantime. All entries kept.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 17:44:24 +02:00
Losminek f44b31e154 i18n: cover Czech in the interface-language tests
- The catalog-completeness test requires a non-empty Czech label for
  every key of the reference (Japanese) table.
- Czech context keys: `Page Layout|Orientation` and `Orientation` get
  different labels; unknown text such as `Sheet1!A1` passes through.
- `cs-CZ` / `cs_CZ.UTF-8` system tags and `parse("cs")` resolve to Czech.
- The ribbon renders after switching to Czech, and the choice persists
  in UiState.
- Czech keeps canonical formula entry (`=SUM(1.5,2.25)`), and `=SUMA(1;2)`
  is not accepted.
- The UI font draws every Czech accented letter, upper and lower case,
  without tofu; Czech shares the default Han font order.

Czech spells "Data" as English does, so the Czech checks probe
"Formulas" -> "Vzorce", where an English fallback would be caught.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 13:36:33 +02:00
vangel76 dc75b2cf5e Data: Solver with Simplex LP, integer branch and bound and a nonlinear method (#326)
data.solver maximises, minimises or targets a value in an objective cell by
changing variable cells under <=, >=, =, int and bin constraints. Simplex LP
linearises the model through recalculation, checks linearity and solves it
with a two-phase simplex; integers use branch and bound. The GRG Nonlinear
choice runs an augmented-Lagrangian projected-gradient method. The model is
saved as hidden solver_* names; Solver Parameters and Solver Results dialogs.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 12:56:36 +02:00
vangel76 0dfd29efde Data: Analysis ToolPak with 13 tools and the Data Analysis dialog (#312)
data.analysisToolPak runs Descriptive Statistics, Histogram, Correlation,
Covariance, Regression, Moving Average, Exponential Smoothing, Rank and
Percentile, the three t-Tests, F-Test and Anova: Single Factor, writing a
static report to an output range or a new sheet. Non-empty output cells are
refused unless overwrite is set; the dialog asks instead.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 12:44:47 +02:00
vangel76 400ab591cb PivotTables: calculated fields (pivot.calculatedField) (#304)
A value field can be a calculated field whose formula is evaluated on
the sums of the fields it names for each report cell (Excel's documented
semantics). Command to add/change/delete, dialog from the field pane,
XLSX cacheField formula round trip.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 12:24:50 +02:00
vangel76 9262fba5ce Charts: Select Data edits the category axis labels; blank corner makes column 1 the categories (#287)
A line chart from numeric X values (years) plotted them as a series and
there was no way to set the axis labels. Now:
- a blank top-left cell over a header row makes the first column the
  category labels even when it holds numbers (the usual convention);
- chart.selectData takes categories (Horizontal (Category) Axis Labels,
  "" clears) and removeSeries, and range is optional;
- Chart Design gets a Select Data button opening a Select Data Source
  dialog: chart data range, legend entries with Remove, axis labels.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 12:20:29 +02:00
vangel76 f58b1234fb Charts: Recommended Charts opens a dialog of chart types with previews (#215)
The ribbon button inserted a column chart straight away. It now opens an
Insert Chart dialog: a Recommended tab (insert.chartRecommendations, a
heuristic over the data's shape: series, points, labels, negatives) and an
All Charts tab, each with a live preview of the chart for the selection.
OK inserts the chosen type and selects the chart.

insert.recommendedCharts stays dialog-free for programmatic calls: without
a type it inserts the first recommendation; type/subtype pick one.
insert_chart is split into build_chart (also used for previews).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 12:15:12 +02:00
vangel76 a11446f2f0 Name Manager: New… and Edit… open the name dialog and return to the manager (#238)
dialogs::show put the Name Manager back into app.dialog after its body
had opened the New Name dialog, so New… did nothing. A dialog opened from
another one now takes over and the opener waits behind it (back), coming
back when the child closes; Go To still hands over to Go To Special.

The Name Manager gets Excel's New…/Edit…/Delete buttons over a selectable
list. formulas.defineName takes oldName/oldScope to edit a name in place;
a renamed name is renamed in cell formulas and other names' definitions.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 12:09:19 +02:00
vangel76 5c614fca48 UI: Name Box Enter goes to the typed cell, not the one below (#247)
The Enter that commits the Name Box stayed in the frame's input; the grid,
drawn after the formula bar and focused again, read it as its own Enter
and moved the active cell down. The Name Box now consumes it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 11:57:26 +02:00
arekown a44cc8540d Add German (de) interface language
New catalog crates/ui-egui/src/i18n/de.rs (266 entries) mirroring the ru.rs
key set exactly; original translations written from the meaning of the
English UI strings, MIT OR Apache-2.0.

- Language::De registered (code de, name Deutsch); de/de-DE/de_AT/de-CH
  resolve via from_tag
- Tests: German coverage in the i18n coverage loop, de/de-AT/de-CH locale
  tags, ribbon round-trip case, default CJK font-order assertion
- Docs: localization-parity.md row, ROADMAP.md languages section

cargo test -p gridcraft-ui-egui i18n: 5 passed; --lib: 21 passed;
interaction + formula_locale: 13 + 8 passed.
2026-10-11 10:57:27 +02:00
Zarvinx ac87c269ff Fix #213: delete selected objects from keyboard 2026-10-11 01:02:18 +03:00
Brandon Thomas ca4011dc5e Review fix-up: merge fixed #104; Portuguese as an i18n/pt.rs module
Merge the fixed #104 branch (which carries #31 and #38) and restructure
the Brazilian Portuguese language onto its per-language layout:

- The PORTUGUESE table moves, unchanged, to crates/ui-egui/src/i18n/pt.rs
  as pt::translate, like zh/ko/ru. Language::PtBr gets code() "pt"
  (parse also accepts pt-BR/pt_BR via the tag reduction); it is still
  saved as "pt".
- No per-language command: the View combo and the control channel switch
  with app.language.set {"language": "pt"} (app.language.portuguese is
  dropped); error text, engine.commands params and the snapshot example
  list every code.
- pt.rs covers the keys added since (Page Layout|Orientation, the display
  theme combo, and the Sheet Options View/Print checkboxes, Exibir /
  Imprimir); the coverage test checks pt like zh/ko/ru.
- people.toml keeps both new contributor entries.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 12:54:33 -04:00
Brandon Thomas f54c0ca2a6 Review fix-up: merge fixed #31; language-ordered Han faces on #38's fallback
Merge the fixed #31 branch (which carries #38's font fallback) and resolve:

- theme.rs: build on #38's fallback_faces/load_fallback instead of the old
  load_cjk. The interface language only reorders the two Han entries
  (sys-cjk-han-ja / sys-cjk-han-zh; Japanese first for ja, Chinese first
  otherwise); Hangul, Thai and Hebrew keep their place. The region-merged
  Noto Sans CJK .ttc is loaded once, with the leading language's face index.
- Fonts are rebuilt on a language switch only when the Han order changes
  (HanOrder), not on every switch. font_definitions()/setup_context() use
  the default order and never read the host locale.
- Tests stay locale-independent (UiState defaults to English; the desktop
  app applies the system language). The web build follows the browser
  language except CJK, which would render as tofu without system fonts.
- app.language.set error/params list all five codes; engine.commands lists
  it. zh/ko/ru gain the keys #31 added (Page Layout|Orientation, display
  theme). The Page Layout screen checkbox keeps English "View" via a
  "Sheet Options|View" key (was shown as "Screen").
- Coverage test checks zh/ja/ko/Thai/Hebrew/Cyrillic in both the UI and
  cell families by comparing glyphs with the tofu glyph.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 12:52:00 -04:00
Brandon Thomas d7c77e94cd Review fix-up: locale-independent defaults, lenient saved language, listed commands
- UiState::default() is English: tests, the kittest harness and the
  snapshot example no longer depend on the host's locale. The desktop app
  alone starts from the system language, when ui.json names no supported
  language (first run, an older file, an unknown value).
- An unknown or malformed saved language reads as English instead of
  failing the whole UiState and resetting every other preference.
- app.language.set takes {"language": "ja"} (with `code` as an alias, the
  name the PR description used); the View combo now uses it via
  Language::code(). The app.language.* commands are listed by
  engine.commands with the other UI commands and documented in
  docs/control-protocol.md.
- Home's text "Orientation" (方向) and Page Layout's print "Orientation"
  (印刷の向き) get separate keys through a `context|label` key form.
- Japanese: Hide Rows → 行を表示しない, Trace Dependents → 参照先のトレース;
  translate the display-theme combo merged in from main.
- system_theme test: the View tab now has two combo boxes; pick the theme one.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 12:44:57 -04:00
Brandon Thomas 277f01265b Merge fixed #38 (font fallback) into feat/i18n-language
# Conflicts:
#	crates/ui-egui/src/grid.rs
#	crates/ui-egui/src/ribbon.rs
#	crates/ui-egui/src/widgets.rs
2026-10-10 12:31:57 -04:00
Brandon Thomas 674d422dc0 Merge pull request #77 from DWAA1660/fix/73-vertical-scrollbar
Add the missing vertical worksheet scrollbar (#73)
2026-10-10 11:57:29 -04:00
Brandon Thomas f736286f24 Merge pull request #50 from LloydNicholson/rotated-wrap-text
Issue #48: rotated text with Wrap Text draws upright (grid and print)

# Conflicts:
#	crates/ui-egui/tests/interaction.rs
2026-10-10 11:57:25 -04:00
Brandon Thomas 0aaaf9aeab Merge pull request #53 from LloydNicholson/general-number-fit
Issue #51: General numbers fit by the cell's own font, not 11pt
2026-10-10 11:57:15 -04:00
neko233-com 12bfdb0798 i18n: add Chinese, Korean and Russian interface languages 2026-10-10 10:24:09 +08:00
harrisonoconnorhover 698a2a8009 Keep keyboard navigation separate from pointer clicks (#87) 2026-10-09 21:26:06 -04:00
DWAA1660 165e6c8a3b M2: add a vertical worksheet scrollbar (#73)
Reserve a strip beside the virtual grid for a theme-aware vertical
scrollbar. Support paging, dragging and wheel scrolling without changing
the active cell. Keep the scroll extent fixed during thumb dragging.

Co-authored-by: Codex <noreply@openai.com>
2026-10-09 14:46:29 -06:00
lloyd 903bbb096d Issue #51: General numbers fit by the cell's own font, not 11pt
grid.rs measured the digit width once, for an 11pt cell font, and
display_text judged how many General digits fit from that whatever the
cell's size. 9pt marks such as 100 in columns with a stored width of 4
(common in mark sheets) came out as ##. The width is now measured per cell
with its own font and size, as print.rs already does; the shared 11pt
measurement and its paint_quadrant parameter go away.

Test: a 9pt 100 in a 28px column draws in full, while 123456789 next to it
still shows ####. Fails before the fix.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 17:23:15 +02:00
lloyd ad6e77f6ef Issue #48: rotated text with Wrap Text draws upright (grid and print)
Narrow columns with tall, upright headers (mark sheets) set both a text
rotation and Wrap Text. The wrap path drew the text flat and returned before
the rotation was applied, so headers came out as 3-4 character fragments.

- Rotated text no longer takes the flat wrap path. Upright (+/-90 deg) text
  wraps to the row height, its lines stacking across the column; other
  angles keep one line, as before.
- Downward text was anchored at the bottom-left and ran out of the cell
  (over the row headers); it now starts at the top, one block-height in.
- Upright text no longer overflows into empty neighbours: its width is its
  line height, and the overflow repainted their gridlines.
- Print/PDF gets the same three fixes.

Tests: ui-egui interaction test (shapes drawn at +/-90 deg, inside a
one-column clip) and a print test (every text block on the page rotated,
a few long lines each). Each failed before the fix.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 17:13:40 +02:00
justinjohn0306 e8e010b446 i18n: switch the interface language (issue #20)
Add an interface-language preference. It defaults to the system's
language on first run (sys-locale, native only) and is switched by hand
from the View tab, next to Dark Mode, or with app.language.english /
app.language.japanese over the control channel. It is saved in ui.json.

Follows the filmcraft house convention: a Language enum and a
table of English-to-Japanese strings with English fallback, so coverage
can grow incrementally. Japanese chrome renders without any bundled
font: the CJK fallback faces already appended to every family cover
kana and kanji.

The ribbon chrome all flows through the small_button/big_button/
toggle_button/split_button/icon_button helpers and menu_items, so
translating there localises the whole ribbon in one place; the language
of the frame is read from egui context data (i18n::current). Command
ids, file names and document text are never translated.
2026-10-09 13:14:48 +05:30
justinjohn0306 596b465bb1 Macros UX: Excel-style info bar, Macros dialog, status badge (issue #6)
The engine now preserves a workbook's VBA project, but the UI had no surface
for it and silently dropped every open-time warning. Give preserved macros an
honest, Excel-shaped home without a false "Enable Content":

- Info bar under the ribbon (Excel's message-bar slot) showing the warning a
  `file.open` result carries. A VBA project gets an amber bar reading "This
  workbook contains VBA macros. GridCraft keeps them intact when you save, but
  does not run them." with a "What this means" button; anything else becomes a
  blue informational bar. Dismissable; a clean open clears a stale notice.
- Macros dialog (Automate ▸ Macros, Alt+F8): lists GridCraft's own scripts and
  the preserved VBA project (presence + size, not module names — the blob is
  opaque). Mirrors Excel's Developer ▸ Macros without claiming to run VBA.
- Status-bar badge "Macros preserved (not executed)" whenever the workbook
  carries a VBA project.

New panel `notice_bar` reuses theme tokens (notice_warn_*/notice_info_*), so it
follows light/dark. Two new UI commands, `ui.notice` and `ui.notice.dismiss`,
reach it from the control channel.

Tests: info bar appears for a macro workbook and clears on dismiss; a non-VBA
warning becomes an info bar; clean open clears the notice; the macros dialog
lists the VBA entry; status bar renders with a VBA project; Alt+F8 opens the
dialog. Snapshot-verified in light and dark.
2026-10-09 05:20:04 +05:30
Brandon Thomas 39082d13c8
About: contributor and model credits compiled in (grab bag + table, self-submitted names) (#2)
* About: contributors compiled in from contributors.json (grab bag + table, sortable, name toggle)

Adds an About GridCraft dialog (tabs About · Contributors · Models) following the craftrules
standard (standards/contributors.md): contributors/contributors.json is generated by
craftrules/scripts/contributors.py and baked into the binary by crates/ui-egui/build.rs as
static tables. Each contributor line: @username, opt-in display/real name, PRs, commits,
lines +/−/Δ, binary assets +/−, first/last commit. Sortable by every column; alphabetical
ignores case and the leading @.

Reachable from the macOS app menu (About GridCraft, previously a web link), Help ▸
Contributors…, and Automate ▸ About GridCraft in the ribbon (all platforms and the web).
Dialog hyperlinks open through the host's open_url service. The snapshot example gains
--dialog 'name={json}' for offscreen renders of dialogs.

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

* Contributors: self-submitted names in contributors/people.toml; AGENTS.md credit-yourself section

build.rs reads contributors/people.toml next to the generated contributors.json and shows a name only
for entries the generator verified as written by that person (craftrules standards/contributors.md).

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

* Contributors: regenerate (verified people.toml entries)

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

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 21:16:34 -04:00
Brandon Thomas 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 Thomas 433726773b M3: column AutoComplete, spelling dialog, Page Break Preview, icons gallery
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 01:14:18 -04:00
Brandon Thomas 168b8ec8b7 M4–M10: PivotTables, PDF export & printing, what-if analysis, spelling, more commands
- PivotTables: engine (grouping, date groups, multiple values, show-as, filters, layouts,
  refresh, recommended pivots) + PivotTable Fields task pane
- sheetcraft-pdf (dependency-free PDF writer, core-14 fonts) + file.exportPdf/print/
  printPreview/pageLayout.pageSetup with pagination, headers/footers, charts, images
- What-if: Goal Seek, Scenario Manager, data tables, advanced filter, consolidate
- Page Break Preview rendering; view mode buttons
- Spelling (system dictionary), icons library, cell checkboxes, recorded scripts,
  chart design/format commands, arrange, custom views, watch window, Get Data from CSV/JSON
- Native macOS menu bar
- UI interaction tests (kittest): fixed arrow keys losing grid focus and Escape not cancelling
- Perf: FxHash in calc, sparse range reads, Arc'd formula ASTs, fast auto row heights
- Parity 254/290 (87.6%)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 01:04:46 -04:00