ironcalc_base/user_model/
conditional_formatting.rs1use crate::{
2 cf_types::{CfRule, CfRuleInput, ConditionalFormattingView},
3 types::Dxf,
4};
5
6use super::{common::UserModel, history::Diff};
7
8impl<'a> UserModel<'a> {
9 pub fn get_conditional_formatting_list(
14 &self,
15 sheet: u32,
16 ) -> Result<Vec<ConditionalFormattingView>, String> {
17 self.model.get_conditional_formatting_list(sheet)
18 }
19
20 pub fn get_dxf_for_conditional_formatting(
23 &self,
24 sheet: u32,
25 index: u32,
26 ) -> Result<Option<Dxf>, String> {
27 self.model
28 .get_dxf_for_conditional_formatting(sheet, index as usize)
29 }
30
31 pub fn add_conditional_formatting(
33 &mut self,
34 sheet: u32,
35 range: &str,
36 rule: CfRuleInput,
37 ) -> Result<(), String> {
38 let priority = self.model.add_conditional_formatting(sheet, range, rule)?;
39 let stored_rule = self
41 .model
42 .workbook
43 .worksheet(sheet)
44 .ok()
45 .and_then(|ws| {
46 ws.conditional_formatting
47 .iter()
48 .find(|cf| cf.priority == priority)
49 .map(|cf| cf.cf_rule.clone())
50 })
51 .unwrap_or(CfRule::DuplicateValues {
52 dxf_id: 0,
53 stop_if_true: false,
54 });
55 self.push_diff_list(vec![Diff::AddConditionalFormatting {
56 sheet,
57 range: range.to_string(),
58 rule: Box::new(stored_rule),
59 priority,
60 }]);
61 self.evaluate_if_not_paused();
62 Ok(())
63 }
64
65 pub fn delete_conditional_formatting(&mut self, sheet: u32, index: u32) -> Result<(), String> {
67 let old = self
68 .model
69 .delete_conditional_formatting(sheet, index as usize)?;
70 self.push_diff_list(vec![Diff::DeleteConditionalFormatting {
71 sheet,
72 index,
73 old_range: old.range,
74 old_rule: Box::new(old.cf_rule),
75 old_priority: old.priority,
76 }]);
77 self.evaluate_if_not_paused();
78 Ok(())
79 }
80
81 pub fn update_conditional_formatting(
83 &mut self,
84 sheet: u32,
85 index: u32,
86 new_range: &str,
87 new_rule: CfRuleInput,
88 ) -> Result<(), String> {
89 let old =
90 self.model
91 .update_conditional_formatting(sheet, index as usize, new_range, new_rule)?;
92 let stored_rule = self
94 .model
95 .workbook
96 .worksheet(sheet)
97 .ok()
98 .and_then(|ws| {
99 ws.conditional_formatting
100 .get(index as usize)
101 .map(|cf| cf.cf_rule.clone())
102 })
103 .unwrap_or(CfRule::DuplicateValues {
104 dxf_id: 0,
105 stop_if_true: false,
106 });
107 self.push_diff_list(vec![Diff::UpdateConditionalFormatting {
108 sheet,
109 index,
110 old_range: old.range,
111 old_rule: Box::new(old.cf_rule),
112 old_priority: old.priority,
113 new_range: new_range.to_string(),
114 new_rule: Box::new(stored_rule),
115 }]);
116 self.evaluate_if_not_paused();
117 Ok(())
118 }
119
120 pub fn raise_conditional_formatting_priority(
124 &mut self,
125 sheet: u32,
126 index: u32,
127 ) -> Result<(), String> {
128 self.swap_conditional_formatting_priority(sheet, index, true)
129 }
130
131 pub fn lower_conditional_formatting_priority(
135 &mut self,
136 sheet: u32,
137 index: u32,
138 ) -> Result<(), String> {
139 self.swap_conditional_formatting_priority(sheet, index, false)
140 }
141
142 fn swap_conditional_formatting_priority(
147 &mut self,
148 sheet: u32,
149 index: u32,
150 raise: bool,
151 ) -> Result<(), String> {
152 let before: Vec<u32> = self
153 .model
154 .workbook
155 .worksheet(sheet)?
156 .conditional_formatting
157 .iter()
158 .map(|cf| cf.priority)
159 .collect();
160 if raise {
161 self.model
162 .raise_conditional_formatting_priority(sheet, index as usize)?;
163 } else {
164 self.model
165 .lower_conditional_formatting_priority(sheet, index as usize)?;
166 }
167 let after: Vec<u32> = self
168 .model
169 .workbook
170 .worksheet(sheet)?
171 .conditional_formatting
172 .iter()
173 .map(|cf| cf.priority)
174 .collect();
175 let changed: Vec<usize> = (0..before.len())
178 .filter(|&i| before[i] != after[i])
179 .collect();
180 if let [a, b] = changed[..] {
181 self.push_diff_list(vec![Diff::SwapConditionalFormattingPriority {
182 sheet,
183 index_a: a as u32,
184 index_b: b as u32,
185 priority_a: before[a],
186 priority_b: before[b],
187 }]);
188 }
189 self.evaluate_if_not_paused();
190 Ok(())
191 }
192}