Merge g3 into g4

# Conflicts:
#	ROADMAP.md
#	crates/engine/src/cmd/edit.rs
#	crates/engine/src/cmd/formulas.rs
#	crates/engine/src/cmd/inspect.rs
#	crates/engine/src/cmd/pivot.rs
#	crates/ui-egui/src/lib.rs
#	crates/ui-egui/src/tabs.rs
#	docs/gaps.md
#	docs/ui-parity.md
This commit is contained in:
aiongg
2026-10-26 02:45:41 +00:00
353 changed files with 24668 additions and 3425 deletions
+5
View File
@@ -410,6 +410,7 @@ pub enum ChartKind {
Doughnut,
Area,
AreaStacked,
AreaStacked100,
Scatter,
ScatterLines,
Bubble,
@@ -1044,6 +1045,9 @@ pub struct PivotTable {
pub values: Vec<PivotValue>,
pub filters: Vec<PivotFilter>,
pub layout: PivotLayout,
/// PivotTable Options › Data › Enable show details: Show Details lists a value cell's
/// source records only while this is on.
pub enable_show_details: bool,
/// Grand total for each row (the "Grand Total" column), like Excel's "On for Rows".
pub grand_totals_rows: bool,
/// Grand total for each column (the "Grand Total" row), like Excel's "On for Columns".
@@ -1087,6 +1091,7 @@ impl Default for PivotTable {
values: vec![],
filters: vec![],
layout: PivotLayout::Compact,
enable_show_details: true,
grand_totals_rows: true,
grand_totals_cols: true,
subtotals: true,
+2
View File
@@ -56,6 +56,8 @@ pub struct PreservedSheet {
pub rel_id: String,
/// How many worksheets come before it: its position among the model's sheets.
pub before: usize,
/// Its `sheetId` in the source file.
pub sheet_id: u32,
}
/// Unmodelled content kept for one owner (the workbook, which also holds package-root content,
+32 -3
View File
@@ -7,7 +7,10 @@ use gridcraft_core::{CellRef, RangeRef, Value};
use serde::{Deserialize, Serialize};
use crate::cell::{Cell, CellPicture};
use crate::features::*;
use crate::features::{
AutoFilter, Chart, Comment, CondFormat, Hyperlink, Image, LineInfo, PivotTable, PrintSettings, Shape, SheetProtection, Slicer, Sparkline, Table,
Validation,
};
use crate::store::CellStore;
use crate::style::{Color, StyleId};
@@ -52,6 +55,10 @@ impl SheetViewMode {
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct Sheet {
pub name: String,
/// The `sheetId` the file gave the sheet, written back on save so that what refers to the
/// sheet by its id keeps finding it; 0 for a sheet the file did not have. Not in JSON.
#[serde(skip)]
pub file_id: u32,
pub cells: CellStore,
/// Static pictures are sparse rich content. Ordinary cells carry no picture pointer.
#[serde(default, skip_serializing_if = "BTreeMap::is_empty", with = "picture_map")]
@@ -76,6 +83,17 @@ pub struct Sheet {
pub show_headings: bool,
pub show_formulas: bool,
pub show_zeros: bool,
/// The outline's level buttons and brackets (Excel's Show Outline Symbols, Ctrl+8); the
/// outline itself stays.
#[serde(default = "yes")]
pub show_outline_symbols: bool,
/// Outline summary rows sit below their detail, and summary columns right of it (Data ▸
/// Outline ▸ Settings; off puts them above / left). Saved as `outlinePr summaryBelow` and
/// `summaryRight`.
#[serde(default = "yes")]
pub summary_below: bool,
#[serde(default = "yes")]
pub summary_right: bool,
pub right_to_left: bool,
pub zoom: u16,
pub cond_formats: Vec<CondFormat>,
@@ -113,6 +131,10 @@ pub struct Sheet {
pub preserved: Option<Arc<crate::preserved::Preserved>>,
}
fn yes() -> bool {
true
}
/// Default width of a column and height of a row (pixels at 96 dpi) for the default font.
pub const DEFAULT_COL_WIDTH: f32 = 64.0;
pub const DEFAULT_ROW_HEIGHT: f32 = 20.0;
@@ -127,6 +149,7 @@ impl Sheet {
pub fn new(name: impl Into<String>) -> Sheet {
Sheet {
name: name.into(),
file_id: 0,
cells: CellStore::new(),
cell_pictures: BTreeMap::new(),
spill: BTreeMap::new(),
@@ -140,6 +163,9 @@ impl Sheet {
tab_color: None,
visibility: Visibility::Visible,
show_gridlines: true,
show_outline_symbols: true,
summary_below: true,
summary_right: true,
show_headings: true,
show_formulas: false,
show_zeros: true,
@@ -604,8 +630,11 @@ mod tests {
// CellRef is a struct, so encode the sparse map as entries for JSON as well as other formats.
mod picture_map {
use super::*;
use serde::{Deserializer, Serializer};
use crate::cell::CellPicture;
use gridcraft_core::CellRef;
use serde::{Deserialize, Deserializer, Serialize, Serializer};
use std::collections::BTreeMap;
use std::sync::Arc;
pub fn serialize<S: Serializer>(map: &BTreeMap<CellRef, Arc<CellPicture>>, serializer: S) -> Result<S::Ok, S::Error> {
map.iter().collect::<Vec<_>>().serialize(serializer)
}
+10 -1
View File
@@ -193,6 +193,14 @@ pub struct Font {
/// Font family class (1 roman, 2 swiss, 3 modern…); `None` is swiss, the default.
#[serde(default)]
pub family: Option<u8>,
/// The font follows the theme's body font (`<scheme val="minor"/>`) while its face is the
/// theme's minor font. Fonts derived from it (bold, a colour, a size) keep the link.
#[serde(default = "default_minor")]
pub minor: bool,
}
fn default_minor() -> bool {
true
}
impl Eq for Font {}
@@ -200,7 +208,7 @@ impl Hash for Font {
fn hash<H: Hasher>(&self, h: &mut H) {
self.name.hash(h);
self.size.to_bits().hash(h);
(self.bold, self.italic, self.underline, self.strike, self.color, self.vert, self.charset, self.family).hash(h);
(self.bold, self.italic, self.underline, self.strike, self.color, self.vert, self.charset, self.family, self.minor).hash(h);
}
}
@@ -217,6 +225,7 @@ impl Default for Font {
vert: VertAlign::Baseline,
charset: None,
family: None,
minor: true,
}
}
}