Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions ROADMAP.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

**Stage: alpha** · next: beta, ~25 points of "ready for real work" and ~160–240 h away

> **Last reviewed:** 2026-10-11 · **Last updated:** 2026-10-12 · **Change:** minor (rows auto-fit oversized fonts on open and whole-row/column formatting) · **Target:** Microsoft Excel (Microsoft 365)
> **Last reviewed:** 2026-10-11 · **Last updated:** 2026-10-12 · **Change:** minor (regional formats, `app.region`) · **Target:** Microsoft Excel (Microsoft 365)

GridCraft aims at full Microsoft Excel parity, and at being better in places: faster, open (XLSX
is the native format), fully scriptable by agents (MCP, control channel, CLI), and on the web.
Expand Down Expand Up @@ -93,7 +93,8 @@ The ribbon is translated into Japanese, Simplified Chinese, Korean, Brazilian Po
and German (266–268 labels each, ~12% of ~2,200 strings; merged 10-10 in #31, #104, #82, German
added 10-11), the
interface follows the system language, and CJK, Thai and Hebrew text falls back to system fonts
(#38). Dialogs, menus and messages are English; formulas and number formats are en-US only.
(#38). Dialogs, menus and messages are English; formulas are en-US (plus Spanish). Numbers, dates
and times follow a Regional format setting (15 regions; File › Options, `app.region`).
Localized German formulas and numbers are in PR #163. Detail: [localization-parity.md](docs/localization-parity.md).

| Language | Code | Status | UI strings |
Expand Down Expand Up @@ -165,6 +166,7 @@ Ranked; estimates in Opus 5.5 agent-hours. Detail and the full beta-gate list in
| 2026-10-11 | XLSX pass-through: custom XML, external links, connections, query tables, printer settings, form/ActiveX controls and OLE objects are kept on save (#330, #324) |
| 2026-10-11 | Data › Forecast › Forecast Sheet: a new sheet with the history, FORECAST.ETS forecast, confidence bounds, statistics and a chart (#322) |
| 2026-10-11 | Startup no longer panics on a system font egui can't parse: fonts are validated and skipped (#226) |
| 2026-10-11 | Regional formats: File › Options › Regional format (`app.region`) changes how numbers, dates and times are typed and shown, for 15 regions |
| 2026-10-11 | Ctrl+drag on the fill handle swaps copying and extending a series (#264) |
| 2026-10-11 | Odd-period bond functions ODDFPRICE, ODDFYIELD, ODDLPRICE, ODDLYIELD: Financial 55 / 55 (#275) |
| 2026-10-11 | PERCENTOF and EUROCONVERT worksheet functions (#279) |
Expand Down Expand Up @@ -201,6 +203,7 @@ Ranked; estimates in Opus 5.5 agent-hours. Detail and the full beta-gate list in
| 2026-10-12 | minor | Ink preservation across XLSX save/reopen (ink portion of #551) |
| 2026-10-12 | minor | Desktop File > Print now discovers printers and submits PDF jobs through pinned craft-print with printer choice, copies, duplex and grayscale; browser printing and PDF export remain available. Remaining print parity includes page ranges and driver-specific tray/options UI; physical printer fidelity needs hardware validation. |
| 2026-10-11 | minor | Password-encrypted workbooks open (#11); progress log row |
| 2026-10-11 | minor | Regional formats (`app.region`); progress log row |
| 2026-10-11 | minor | Forecast Sheet (#322); progress log row |
| 2026-10-11 | minor | Worksheet functions 505 / 523 (ODD* bond functions); progress log row |
| 2026-10-11 | minor | Worksheet functions 503 / 523 (PERCENTOF, EUROCONVERT); progress log row |
Expand Down
6 changes: 6 additions & 0 deletions apps/gridcraft-web/src/web.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,12 @@ pub fn start() {
) {
app.ui.language = browser;
}
// The browser's regional format too, with the same CJK exception: month names and AM/PM
// words of those regions need a CJK font the web build doesn't have.
let region = gridcraft_ui_egui::i18n::system_region();
if !matches!(region.tag, "ja-JP" | "ko-KR" | "zh-CN" | "zh-TW") {
let _ = app.session.set_region(region.tag);
}
SheetApp::setup_context_for_language(&cc.egui_ctx, false, app.ui.language);
if let Some(bridge) = &app_bridge {
if let Some(author) = query_param("author") {
Expand Down
12 changes: 11 additions & 1 deletion apps/gridcraft/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,9 @@ fn load_prefs(app: &mut SheetApp) {
app.ui.language = gridcraft_ui_egui::i18n::Language::system();
// ...and its light or dark appearance (#239), until a theme is chosen and saved in ui.json.
app.ui.system_theme = true;
// ...and its regional format (separators, date order), until one is chosen and saved in prefs.json.
app.session.prefs.region = gridcraft_ui_egui::i18n::system_region().tag.into();
app.session.apply_region();
let Some(dir) = config_dir() else { return };
if let Ok(b) = std::fs::read(dir.join("ui.json"))
&& let Ok(ui) = serde_json::from_slice::<gridcraft_ui_egui::UiState>(&b)
Expand All @@ -115,9 +118,16 @@ fn load_prefs(app: &mut SheetApp) {
app.ui.language = language;
}
if let Ok(b) = std::fs::read(dir.join("prefs.json"))
&& let Ok(p) = serde_json::from_slice(&b)
&& let Ok(mut p) = serde_json::from_slice::<gridcraft_engine::Prefs>(&b)
{
// A prefs.json from before regions existed has no region: keep the system's.
let saved_region =
serde_json::from_slice::<serde_json::Value>(&b).ok().is_some_and(|v| v.get("region").is_some_and(serde_json::Value::is_string));
if !saved_region {
p.region = app.session.prefs.region.clone();
}
app.session.prefs = p;
app.session.apply_region();
}
}

Expand Down
4 changes: 3 additions & 1 deletion crates/core/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
//! GridCraft core types: cell addresses, values and Excel's coercion rules, error values,
//! date serials and typed-input parsing. No dependencies on the rest of the workspace.
//! date serials, regional formats and typed-input parsing. No dependencies on the rest of the workspace.
#![deny(clippy::unwrap_used, clippy::expect_used, clippy::panic, clippy::unimplemented, clippy::todo, clippy::unreachable)]
#![forbid(unsafe_code)]

pub mod addr;
pub mod date;
pub mod parse;
pub mod region;
pub mod value;

pub use addr::{CellRef, MAX_COLS, MAX_ROWS, RangeRef, col_to_letters, letters_to_col};
pub use date::DateSystem;
pub use region::Region;
pub use value::{Array, CellError, Value, compare, compare_numbers, compare_text, number_to_text, sort_compare};
Loading