diff --git a/base/src/model.rs b/base/src/model.rs index a334ebb..4bd36ec 100644 --- a/base/src/model.rs +++ b/base/src/model.rs @@ -865,7 +865,11 @@ impl Model { let worksheet_names = worksheets.iter().map(|s| s.get_name()).collect(); - let defined_names = workbook.get_defined_names_with_scope(); + let defined_names = workbook + .get_defined_names_with_scope() + .iter() + .map(|s| (s.0.to_owned(), s.1)) + .collect(); // add all tables // let mut tables = Vec::new(); // for worksheet in worksheets { diff --git a/base/src/new_empty.rs b/base/src/new_empty.rs index 92f0e2e..454821b 100644 --- a/base/src/new_empty.rs +++ b/base/src/new_empty.rs @@ -144,7 +144,12 @@ impl Model { /// Reparses all formulas and defined names pub(crate) fn reset_parsed_structures(&mut self) { - let defined_names = self.workbook.get_defined_names_with_scope(); + let defined_names = self + .workbook + .get_defined_names_with_scope() + .iter() + .map(|s| (s.0.to_owned(), s.1)) + .collect(); self.parser .set_worksheets_and_names(self.workbook.get_worksheet_names(), defined_names); self.parsed_formulas = vec![]; diff --git a/base/src/test/user_model/test_defined_names.rs b/base/src/test/user_model/test_defined_names.rs index 88700e7..23c50dd 100644 --- a/base/src/test/user_model/test_defined_names.rs +++ b/base/src/test/user_model/test_defined_names.rs @@ -15,6 +15,11 @@ fn create_defined_name() { Ok("42".to_string()) ); + assert_eq!( + model.get_defined_name_list(), + vec![("myName".to_string(), None, "Sheet1!$A$1".to_string())] + ); + // delete it model.delete_defined_name("myName", None).unwrap(); assert_eq!( @@ -22,6 +27,8 @@ fn create_defined_name() { Ok("#NAME?".to_string()) ); + assert_eq!(model.get_defined_name_list().len(), 0); + model.undo().unwrap(); assert_eq!( model.get_formatted_cell_value(0, 5, 7), @@ -324,3 +331,68 @@ fn invalid_formula() { Ok("#NAME?".to_string()) ); } + +#[test] +fn undo_redo() { + let mut model = UserModel::new_empty("model", "en", "UTC").unwrap(); + model.set_user_input(0, 1, 1, "Hello").unwrap(); + model.set_user_input(0, 2, 1, "Hola").unwrap(); + model.set_user_input(0, 1, 2, r#"=MyName&"!""#).unwrap(); + + model + .new_defined_name("MyName", None, "Sheet1!$A$1") + .unwrap(); + + assert_eq!( + model.get_formatted_cell_value(0, 1, 2), + Ok("Hello!".to_string()) + ); + model.undo().unwrap(); + assert_eq!(model.get_defined_name_list().len(), 0); + assert_eq!( + model.get_formatted_cell_value(0, 1, 2), + Ok("#NAME?".to_string()) + ); + model.redo().unwrap(); + + assert_eq!(model.get_defined_name_list().len(), 1); + assert_eq!( + model.get_formatted_cell_value(0, 1, 2), + Ok("Hello!".to_string()) + ); + + model + .update_defined_name("MyName", None, "MyName", None, "Sheet1!$A$2") + .unwrap(); + assert_eq!(model.get_defined_name_list().len(), 1); + assert_eq!( + model.get_formatted_cell_value(0, 1, 2), + Ok("Hola!".to_string()) + ); + model.undo().unwrap(); + + assert_eq!(model.get_defined_name_list().len(), 1); + assert_eq!( + model.get_formatted_cell_value(0, 1, 2), + Ok("Hello!".to_string()) + ); + + model.redo().unwrap(); + + assert_eq!(model.get_defined_name_list().len(), 1); + assert_eq!( + model.get_formatted_cell_value(0, 1, 2), + Ok("Hola!".to_string()) + ); + + let send_queue = model.flush_send_queue(); + + let mut model2 = UserModel::new_empty("model", "en", "UTC").unwrap(); + model2.apply_external_diffs(&send_queue).unwrap(); + + assert_eq!(model2.get_defined_name_list().len(), 1); + assert_eq!( + model2.get_formatted_cell_value(0, 1, 2), + Ok("Hola!".to_string()) + ); +} diff --git a/base/src/user_model/common.rs b/base/src/user_model/common.rs index 601eeab..7c5fc76 100644 --- a/base/src/user_model/common.rs +++ b/base/src/user_model/common.rs @@ -13,8 +13,8 @@ use crate::{ }, model::Model, types::{ - Alignment, BorderItem, CellType, Col, DefinedName, HorizontalAlignment, SheetProperties, - SheetState, Style, VerticalAlignment, + Alignment, BorderItem, CellType, Col, HorizontalAlignment, SheetProperties, SheetState, + Style, VerticalAlignment, }, utils::is_valid_hex_color, }; @@ -1735,8 +1735,8 @@ impl UserModel { } /// Returns the list of defined names - pub fn get_defined_name_list(&self) -> Vec { - self.model.workbook.defined_names.clone() + pub fn get_defined_name_list(&self) -> Vec<(String, Option, String)> { + self.model.workbook.get_defined_names_with_scope() } /// Delete an existing defined name diff --git a/base/src/workbook.rs b/base/src/workbook.rs index 606ee81..05e05e9 100644 --- a/base/src/workbook.rs +++ b/base/src/workbook.rs @@ -29,7 +29,7 @@ impl Workbook { } /// Returns the a list of defined names in the workbook with their scope - pub(crate) fn get_defined_names_with_scope(&self) -> Vec<(String, Option)> { + pub(crate) fn get_defined_names_with_scope(&self) -> Vec<(String, Option, String)> { let sheet_id_index: Vec = self.worksheets.iter().map(|s| s.sheet_id).collect(); let defined_names = self @@ -45,7 +45,7 @@ impl Workbook { // convert Option to Option .map(|pos| pos as u32); - (dn.name.clone(), index) + (dn.name.clone(), index, dn.formula.clone()) }) .collect::>(); defined_names diff --git a/bindings/wasm/src/lib.rs b/bindings/wasm/src/lib.rs index ec23c2d..c440520 100644 --- a/bindings/wasm/src/lib.rs +++ b/bindings/wasm/src/lib.rs @@ -568,12 +568,11 @@ impl Model { .get_defined_name_list() .iter() .map(|s| DefinedName { - name: s.name.to_string(), - scope: s.sheet_id, - formula: s.formula.to_string(), + name: s.0.to_owned(), + scope: s.1, + formula: s.2.to_owned(), }) .collect(); - // Ok(data) serde_wasm_bindgen::to_value(&data).map_err(|e| to_js_error(e.to_string())) }