From 9c5d3c57e088787d1daaa2160b59a4dab39525bb Mon Sep 17 00:00:00 2001 From: Artur Sultanov Date: Mon, 29 Jun 2026 13:35:55 +0300 Subject: [PATCH] [dev] locked property --- src/lib.rs | 5 +++++ src/style.rs | 36 +++++++++++++++++++++++++----------- 2 files changed, 30 insertions(+), 11 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 406502e..8ebfe86 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -424,6 +424,11 @@ fn get_styles_data(style_table: StyleTable) -> String { xf.add_attr("applyAlignment", "1").add_children(vec![alignment]); } + if let Some(locked) = p.locked { + let mut protection = Element::new("protection"); + protection.add_attr("locked", if locked { "1" } else { "0" }); + xf.add_attr("applyProtection", "1").add_children(vec![protection]); + } xf }).collect(); diff --git a/src/style.rs b/src/style.rs index f6dbbb7..80c44f7 100644 --- a/src/style.rs +++ b/src/style.rs @@ -35,6 +35,7 @@ pub struct StyleProps { pub align_h: Option, pub align_v: Option, pub wrap_text: bool, + pub locked: Option, } #[derive(PartialEq, Debug)] @@ -80,6 +81,7 @@ pub struct XFSProps { pub align_h: Option, pub align_v: Option, pub wrap_text: bool, + pub locked: Option, } impl StyleTable { @@ -137,6 +139,7 @@ impl StyleTable { xsf_props.align_h = st.align_h; xsf_props.align_v = st.align_v; xsf_props.wrap_text = st.wrap_text; + xsf_props.locked = st.locked; xsf_props.format_id = style.get("format").and_then(|format_name| { match format_name { Value::String(s) => { @@ -238,6 +241,7 @@ impl StyleProps { border: None, align_v: None, wrap_text: false, + locked: None, } } } @@ -252,6 +256,7 @@ impl XFSProps { align_h: None, align_v: None, wrap_text: false, + locked: None, } } } @@ -293,19 +298,11 @@ fn style_to_props(styles: &HashMap) -> StyleProps { "borderLeft" => border.left = value.as_str().and_then(|s| str_to_border(s, BorderPosition::Left)), "wrapText" => { // accept boolean, string or number values - match value { - Value::Bool(b) => st.wrap_text = *b, - Value::String(s) => st.wrap_text = s == "true" || s == "1", - Value::Number(n) => { - if let Some(i) = n.as_i64() { - st.wrap_text = i != 0; - } else if let Some(f) = n.as_f64() { - st.wrap_text = f != 0.0; - } - } - _ => (), + if let Some(v) = value_to_bool(value) { + st.wrap_text = v; } } + "locked" => st.locked = value_to_bool(value), _ => (), } } @@ -316,6 +313,21 @@ fn style_to_props(styles: &HashMap) -> StyleProps { st } +fn value_to_bool(value: &Value) -> Option { + match value { + Value::Bool(b) => Some(*b), + Value::String(s) => Some(s == "true" || s == "1"), + Value::Number(n) => { + if let Some(i) = n.as_i64() { + Some(i != 0) + } else { + n.as_f64().map(|f| f != 0.0) + } + } + _ => None, + } +} + fn color_to_argb(color: &str) -> Option { let len = color.len(); let mut argb_color = String::new(); @@ -508,6 +520,7 @@ fn style_to_props_test() { styles.insert(String::from("textDecoration"), Value::String(String::from("underline"))); styles.insert(String::from("align"), Value::String(String::from("left"))); styles.insert(String::from("verticalAlign"), Value::String(String::from("bottom"))); + styles.insert(String::from("locked"), Value::Bool(true)); styles.insert(String::from("borderTop"), Value::String(String::from("1px solid #9AFF02"))); styles.insert( String::from("borderRight"), @@ -526,6 +539,7 @@ fn style_to_props_test() { assert_eq!(st.fill.unwrap().color, Some(String::from("FFFF0000"))); assert_eq!(st.align_h, Some(String::from("left"))); assert_eq!(st.align_v, Some(String::from("bottom"))); + assert_eq!(st.locked, Some(true)); let border = st.border.unwrap(); assert_eq!(border.top.unwrap().color, String::from("FF9AFF02"));