1use crate::{
2 constants::{LAST_COLUMN, LAST_ROW},
3 expressions::types::Area,
4};
5
6use super::{
7 border_utils::is_max_border, common::BorderType, history::Diff, BorderArea, UserModel,
8};
9
10impl<'a> UserModel<'a> {
11 fn update_single_cell_border(
12 &mut self,
13 border_area: &BorderArea,
14 cell: (u32, i32, i32),
15 range: (i32, i32, i32, i32),
16 diff_list: &mut Vec<Diff>,
17 ) -> Result<(), String> {
18 let (sheet, row, column) = cell;
19 let (first_row, first_column, last_row, last_column) = range;
20
21 let old_value = self.model.get_cell_style_or_none(sheet, row, column)?;
22 let mut new_value = match &old_value {
23 Some(value) => value.clone(),
24 None => Default::default(),
25 };
26 match border_area.r#type {
27 BorderType::All => {
28 new_value.border.top = Some(border_area.item.clone());
29 new_value.border.right = Some(border_area.item.clone());
30 new_value.border.bottom = Some(border_area.item.clone());
31 new_value.border.left = Some(border_area.item.clone());
32 }
33 BorderType::Inner => {
34 if row != first_row {
35 new_value.border.top = Some(border_area.item.clone());
36 }
37 if row != last_row {
38 new_value.border.bottom = Some(border_area.item.clone());
39 }
40 if column != first_column {
41 new_value.border.left = Some(border_area.item.clone());
42 }
43 if column != last_column {
44 new_value.border.right = Some(border_area.item.clone());
45 }
46 }
47 BorderType::Outer => {
48 if row == first_row {
49 new_value.border.top = Some(border_area.item.clone());
50 }
51 if row == last_row {
52 new_value.border.bottom = Some(border_area.item.clone());
53 }
54 if column == first_column {
55 new_value.border.left = Some(border_area.item.clone());
56 }
57 if column == last_column {
58 new_value.border.right = Some(border_area.item.clone());
59 }
60 }
61 BorderType::Top => {
62 if row == first_row {
63 new_value.border.top = Some(border_area.item.clone());
64 }
65 }
66 BorderType::Right => {
67 if column == last_column {
68 new_value.border.right = Some(border_area.item.clone());
69 }
70 }
71 BorderType::Bottom => {
72 if row == last_row {
73 new_value.border.bottom = Some(border_area.item.clone());
74 }
75 }
76 BorderType::Left => {
77 if column == first_column {
78 new_value.border.left = Some(border_area.item.clone());
79 }
80 }
81 BorderType::CenterH => {
82 if row != first_row {
83 new_value.border.top = Some(border_area.item.clone());
84 }
85 if row != last_row {
86 new_value.border.bottom = Some(border_area.item.clone());
87 }
88 }
89 BorderType::CenterV => {
90 if column != first_column {
91 new_value.border.left = Some(border_area.item.clone());
92 }
93 if column != last_column {
94 new_value.border.right = Some(border_area.item.clone());
95 }
96 }
97 BorderType::None => {
98 new_value.border.top = None;
99 new_value.border.right = None;
100 new_value.border.bottom = None;
101 new_value.border.left = None;
102 }
103 }
104 self.model.set_cell_style(sheet, row, column, &new_value)?;
105 diff_list.push(Diff::SetCellStyle {
106 sheet,
107 row,
108 column,
109 old_value: Box::new(old_value),
110 new_value: Box::new(new_value),
111 });
112 Ok(())
113 }
114
115 fn set_rows_with_border(
116 &mut self,
117 sheet: u32,
118 first_row: i32,
119 last_row: i32,
120 border_area: &BorderArea,
121 ) -> Result<(), String> {
122 let mut diff_list = Vec::new();
123 for row in first_row..=last_row {
124 let old_value = self.model.get_row_style(sheet, row)?;
125 let mut new_value = match &old_value {
126 Some(value) => value.clone(),
127 None => Default::default(),
128 };
129
130 match border_area.r#type {
131 BorderType::All => {
132 new_value.border.top = Some(border_area.item.clone());
133 new_value.border.right = Some(border_area.item.clone());
134 new_value.border.bottom = Some(border_area.item.clone());
135 new_value.border.left = Some(border_area.item.clone());
136 }
137 BorderType::Inner => {
138 if row != first_row {
139 new_value.border.top = Some(border_area.item.clone());
140 }
141 if row != last_row {
142 new_value.border.bottom = Some(border_area.item.clone());
143 }
144 }
145 BorderType::Outer => {
146 if row == first_row {
147 new_value.border.top = Some(border_area.item.clone());
148 }
149 if row == last_row {
150 new_value.border.bottom = Some(border_area.item.clone());
151 }
152 }
153 BorderType::Top => {
154 if row == first_row {
155 new_value.border.top = Some(border_area.item.clone());
156 }
157 }
158 BorderType::Right => {
159 }
161 BorderType::Bottom => {
162 if row == last_row {
163 new_value.border.bottom = Some(border_area.item.clone());
164 }
165 }
166 BorderType::Left => {
167 }
169 BorderType::CenterH => {
170 if row != first_row {
171 new_value.border.top = Some(border_area.item.clone());
172 }
173 if row != last_row {
174 new_value.border.bottom = Some(border_area.item.clone());
175 }
176 }
177 BorderType::CenterV => {
178 new_value.border.left = Some(border_area.item.clone());
179 new_value.border.right = Some(border_area.item.clone());
180 }
181 BorderType::None => {
182 new_value.border.top = None;
183 new_value.border.right = None;
184 new_value.border.bottom = None;
185 new_value.border.left = None;
186 }
187 }
188
189 let columns: Vec<i32> = self
191 .model
192 .workbook
193 .worksheet(sheet)?
194 .sheet_data
195 .get(&row)
196 .map(|row_data| row_data.keys().copied().collect())
197 .unwrap_or_default();
198 for column in columns {
199 self.update_single_cell_border(
200 border_area,
201 (sheet, row, column),
202 (first_row, 1, last_row, LAST_COLUMN),
203 &mut diff_list,
204 )?;
205 }
206
207 self.model.set_row_style(sheet, row, &new_value)?;
208 diff_list.push(Diff::SetRowStyle {
209 sheet,
210 row,
211 old_value: Box::new(old_value),
212 new_value: Box::new(new_value),
213 });
214 }
215 self.push_diff_list(diff_list);
217 Ok(())
218 }
219
220 fn set_columns_with_border(
221 &mut self,
222 sheet: u32,
223 first_column: i32,
224 last_column: i32,
225 border_area: &BorderArea,
226 ) -> Result<(), String> {
227 let mut diff_list = Vec::new();
228 let data_rows: Vec<i32> = self
231 .model
232 .workbook
233 .worksheet(sheet)?
234 .sheet_data
235 .keys()
236 .copied()
237 .collect();
238 let styled_rows = &self.model.workbook.worksheet(sheet)?.rows.clone();
239 for column in first_column..=last_column {
240 let old_value = self.model.get_column_style(sheet, column)?;
241 let mut new_value = match &old_value {
242 Some(value) => value.clone(),
243 None => Default::default(),
244 };
245
246 match border_area.r#type {
247 BorderType::All => {
248 new_value.border.top = Some(border_area.item.clone());
249 new_value.border.right = Some(border_area.item.clone());
250 new_value.border.bottom = Some(border_area.item.clone());
251 new_value.border.left = Some(border_area.item.clone());
252 }
253 BorderType::Inner => {
254 if column != first_column {
255 new_value.border.left = Some(border_area.item.clone());
256 }
257 if column != last_column {
258 new_value.border.right = Some(border_area.item.clone());
259 }
260 }
261 BorderType::Outer => {
262 if column == first_column {
263 new_value.border.left = Some(border_area.item.clone());
264 }
265 if column == last_column {
266 new_value.border.right = Some(border_area.item.clone());
267 }
268 }
269 BorderType::Top => {
270 }
272 BorderType::Right => {
273 if column == last_column {
274 new_value.border.right = Some(border_area.item.clone());
275 }
276 }
277 BorderType::Bottom => {
278 }
280 BorderType::Left => {
281 if column == first_column {
282 new_value.border.left = Some(border_area.item.clone());
283 }
284 }
285 BorderType::CenterH => {
286 new_value.border.top = Some(border_area.item.clone());
287 new_value.border.bottom = Some(border_area.item.clone());
288 }
289 BorderType::CenterV => {
290 if column != first_column {
291 new_value.border.left = Some(border_area.item.clone());
292 }
293 if column != last_column {
294 new_value.border.right = Some(border_area.item.clone());
295 }
296 }
297 BorderType::None => {
298 new_value.border.top = None;
299 new_value.border.right = None;
300 new_value.border.bottom = None;
301 new_value.border.left = None;
302 }
303 }
304 for &row in &data_rows {
306 if let Some(data_row) = self.model.workbook.worksheet(sheet)?.sheet_data.get(&row) {
307 if data_row.get(&column).is_some() {
308 self.update_single_cell_border(
309 border_area,
310 (sheet, row, column),
311 (1, first_column, LAST_ROW, last_column),
312 &mut diff_list,
313 )?;
314 }
315 }
316 }
317
318 for row_s in styled_rows.iter() {
320 let row = row_s.r;
321 self.update_single_cell_border(
322 border_area,
323 (sheet, row, column),
324 (1, first_column, LAST_ROW, last_column),
325 &mut diff_list,
326 )?;
327 }
328
329 self.model.set_column_style(sheet, column, &new_value)?;
330 diff_list.push(Diff::SetColumnStyle {
331 sheet,
332 column,
333 old_value: Box::new(old_value),
334 new_value: Box::new(new_value),
335 });
336 }
337 self.push_diff_list(diff_list);
340 Ok(())
341 }
342
343 pub fn set_area_with_border(
347 &mut self,
348 range: &Area,
349 border_area: &BorderArea,
350 ) -> Result<(), String> {
351 let sheet = range.sheet;
352 let first_row = range.row;
353 let first_column = range.column;
354 let last_row = first_row + range.height - 1;
355 let last_column = first_column + range.width - 1;
356 if first_row == 1 && last_row == LAST_ROW {
357 self.set_columns_with_border(sheet, first_column, last_column, border_area)?;
359 return Ok(());
360 }
361 if first_column == 1 && last_column == LAST_COLUMN {
362 self.set_rows_with_border(sheet, first_row, last_row, border_area)?;
364 return Ok(());
365 }
366 let mut diff_list = Vec::new();
367 for row in first_row..=last_row {
368 for column in first_column..=last_column {
369 self.update_single_cell_border(
370 border_area,
371 (sheet, row, column),
372 (first_row, first_column, last_row, last_column),
373 &mut diff_list,
374 )?;
375 }
376 }
377
378 if first_row > 1
380 && [
381 BorderType::All,
382 BorderType::None,
383 BorderType::Outer,
384 BorderType::Top,
385 ]
386 .contains(&border_area.r#type)
387 {
388 let row = first_row - 1;
389 for column in first_column..=last_column {
390 let old_value = self.model.get_style_for_cell(sheet, row, column)?;
391 if is_max_border(Some(&border_area.item), old_value.border.bottom.as_ref()) {
392 let mut style = old_value.clone();
393 if border_area.r#type == BorderType::None {
394 style.border.bottom = None;
395 } else {
396 style.border.bottom = Some(border_area.item.clone());
397 }
398 self.model.set_cell_style(sheet, row, column, &style)?;
399 diff_list.push(Diff::SetCellStyle {
400 sheet,
401 row,
402 column,
403 old_value: Box::new(Some(old_value)),
404 new_value: Box::new(style),
405 });
406 }
407 }
408 }
409 if last_column < LAST_COLUMN
411 && [
412 BorderType::All,
413 BorderType::None,
414 BorderType::Outer,
415 BorderType::Right,
416 ]
417 .contains(&border_area.r#type)
418 {
419 let column = last_column + 1;
420 for row in first_row..=last_row {
421 let old_value = self.model.get_style_for_cell(sheet, row, column)?;
422 if is_max_border(Some(&border_area.item), old_value.border.left.as_ref()) {
424 let mut style = old_value.clone();
425 if border_area.r#type == BorderType::None {
426 style.border.left = None;
427 } else {
428 style.border.left = Some(border_area.item.clone());
429 }
430 self.model.set_cell_style(sheet, row, column, &style)?;
431 diff_list.push(Diff::SetCellStyle {
432 sheet,
433 row,
434 column,
435 old_value: Box::new(Some(old_value)),
436 new_value: Box::new(style),
437 });
438 }
439 }
440 }
441 if last_row < LAST_ROW
443 && [
444 BorderType::All,
445 BorderType::None,
446 BorderType::Outer,
447 BorderType::Bottom,
448 ]
449 .contains(&border_area.r#type)
450 {
451 let row = last_row + 1;
452 for column in first_column..=last_column {
453 let old_value = self.model.get_style_for_cell(sheet, row, column)?;
454 if is_max_border(Some(&border_area.item), old_value.border.top.as_ref()) {
455 let mut style = old_value.clone();
456 if border_area.r#type == BorderType::None {
457 style.border.top = None;
458 } else {
459 style.border.top = Some(border_area.item.clone());
460 }
461 self.model.set_cell_style(sheet, row, column, &style)?;
462 diff_list.push(Diff::SetCellStyle {
463 sheet,
464 row,
465 column,
466 old_value: Box::new(Some(old_value)),
467 new_value: Box::new(style),
468 });
469 }
470 }
471 }
472 if first_column > 1
474 && [
475 BorderType::All,
476 BorderType::None,
477 BorderType::Outer,
478 BorderType::Left,
479 ]
480 .contains(&border_area.r#type)
481 {
482 let column = first_column - 1;
483 for row in first_row..=last_row {
484 let old_value = self.model.get_style_for_cell(sheet, row, column)?;
485 if is_max_border(Some(&border_area.item), old_value.border.right.as_ref()) {
486 let mut style = old_value.clone();
487 if border_area.r#type == BorderType::None {
488 style.border.right = None;
489 } else {
490 style.border.right = Some(border_area.item.clone());
491 }
492 self.model.set_cell_style(sheet, row, column, &style)?;
493 diff_list.push(Diff::SetCellStyle {
494 sheet,
495 row,
496 column,
497 old_value: Box::new(Some(old_value)),
498 new_value: Box::new(style),
499 });
500 }
501 }
502 }
503
504 self.push_diff_list(diff_list);
505 Ok(())
506 }
507}