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 .columns_in_row(row);
196 for column in columns {
197 self.update_single_cell_border(
198 border_area,
199 (sheet, row, column),
200 (first_row, 1, last_row, LAST_COLUMN),
201 &mut diff_list,
202 )?;
203 }
204
205 self.model.set_row_style(sheet, row, &new_value)?;
206 diff_list.push(Diff::SetRowStyle {
207 sheet,
208 row,
209 old_value: Box::new(old_value),
210 new_value: Box::new(new_value),
211 });
212 }
213 self.push_diff_list(diff_list);
215 Ok(())
216 }
217
218 fn set_columns_with_border(
219 &mut self,
220 sheet: u32,
221 first_column: i32,
222 last_column: i32,
223 border_area: &BorderArea,
224 ) -> Result<(), String> {
225 let mut diff_list = Vec::new();
226 let data_rows: Vec<i32> = self.model.workbook.worksheet(sheet)?.sheet_data.rows();
229 let styled_rows = &self.model.workbook.worksheet(sheet)?.rows.clone();
230 for column in first_column..=last_column {
231 let old_value = self.model.get_column_style(sheet, column)?;
232 let mut new_value = match &old_value {
233 Some(value) => value.clone(),
234 None => Default::default(),
235 };
236
237 match border_area.r#type {
238 BorderType::All => {
239 new_value.border.top = Some(border_area.item.clone());
240 new_value.border.right = Some(border_area.item.clone());
241 new_value.border.bottom = Some(border_area.item.clone());
242 new_value.border.left = Some(border_area.item.clone());
243 }
244 BorderType::Inner => {
245 if column != first_column {
246 new_value.border.left = Some(border_area.item.clone());
247 }
248 if column != last_column {
249 new_value.border.right = Some(border_area.item.clone());
250 }
251 }
252 BorderType::Outer => {
253 if column == first_column {
254 new_value.border.left = Some(border_area.item.clone());
255 }
256 if column == last_column {
257 new_value.border.right = Some(border_area.item.clone());
258 }
259 }
260 BorderType::Top => {
261 }
263 BorderType::Right => {
264 if column == last_column {
265 new_value.border.right = Some(border_area.item.clone());
266 }
267 }
268 BorderType::Bottom => {
269 }
271 BorderType::Left => {
272 if column == first_column {
273 new_value.border.left = Some(border_area.item.clone());
274 }
275 }
276 BorderType::CenterH => {
277 new_value.border.top = Some(border_area.item.clone());
278 new_value.border.bottom = Some(border_area.item.clone());
279 }
280 BorderType::CenterV => {
281 if column != first_column {
282 new_value.border.left = Some(border_area.item.clone());
283 }
284 if column != last_column {
285 new_value.border.right = Some(border_area.item.clone());
286 }
287 }
288 BorderType::None => {
289 new_value.border.top = None;
290 new_value.border.right = None;
291 new_value.border.bottom = None;
292 new_value.border.left = None;
293 }
294 }
295 for &row in &data_rows {
297 if self
298 .model
299 .workbook
300 .worksheet(sheet)?
301 .cell(row, column)
302 .is_some()
303 {
304 self.update_single_cell_border(
305 border_area,
306 (sheet, row, column),
307 (1, first_column, LAST_ROW, last_column),
308 &mut diff_list,
309 )?;
310 }
311 }
312
313 for row_s in styled_rows.iter() {
315 let row = row_s.r;
316 self.update_single_cell_border(
317 border_area,
318 (sheet, row, column),
319 (1, first_column, LAST_ROW, last_column),
320 &mut diff_list,
321 )?;
322 }
323
324 self.model.set_column_style(sheet, column, &new_value)?;
325 diff_list.push(Diff::SetColumnStyle {
326 sheet,
327 column,
328 old_value: Box::new(old_value),
329 new_value: Box::new(new_value),
330 });
331 }
332 self.push_diff_list(diff_list);
335 Ok(())
336 }
337
338 pub fn set_area_with_border(
342 &mut self,
343 range: &Area,
344 border_area: &BorderArea,
345 ) -> Result<(), String> {
346 let sheet = range.sheet;
347 let first_row = range.row;
348 let first_column = range.column;
349 let last_row = first_row + range.height - 1;
350 let last_column = first_column + range.width - 1;
351 if first_row == 1 && last_row == LAST_ROW {
352 self.set_columns_with_border(sheet, first_column, last_column, border_area)?;
354 return Ok(());
355 }
356 if first_column == 1 && last_column == LAST_COLUMN {
357 self.set_rows_with_border(sheet, first_row, last_row, border_area)?;
359 return Ok(());
360 }
361 let mut diff_list = Vec::new();
362 for row in first_row..=last_row {
363 for column in first_column..=last_column {
364 self.update_single_cell_border(
365 border_area,
366 (sheet, row, column),
367 (first_row, first_column, last_row, last_column),
368 &mut diff_list,
369 )?;
370 }
371 }
372
373 if first_row > 1
375 && [
376 BorderType::All,
377 BorderType::None,
378 BorderType::Outer,
379 BorderType::Top,
380 ]
381 .contains(&border_area.r#type)
382 {
383 let row = first_row - 1;
384 for column in first_column..=last_column {
385 let old_value = self.model.get_style_for_cell(sheet, row, column)?;
386 if is_max_border(Some(&border_area.item), old_value.border.bottom.as_ref()) {
387 let mut style = old_value.clone();
388 if border_area.r#type == BorderType::None {
389 style.border.bottom = None;
390 } else {
391 style.border.bottom = Some(border_area.item.clone());
392 }
393 self.model.set_cell_style(sheet, row, column, &style)?;
394 diff_list.push(Diff::SetCellStyle {
395 sheet,
396 row,
397 column,
398 old_value: Box::new(Some(old_value)),
399 new_value: Box::new(style),
400 });
401 }
402 }
403 }
404 if last_column < LAST_COLUMN
406 && [
407 BorderType::All,
408 BorderType::None,
409 BorderType::Outer,
410 BorderType::Right,
411 ]
412 .contains(&border_area.r#type)
413 {
414 let column = last_column + 1;
415 for row in first_row..=last_row {
416 let old_value = self.model.get_style_for_cell(sheet, row, column)?;
417 if is_max_border(Some(&border_area.item), old_value.border.left.as_ref()) {
419 let mut style = old_value.clone();
420 if border_area.r#type == BorderType::None {
421 style.border.left = None;
422 } else {
423 style.border.left = Some(border_area.item.clone());
424 }
425 self.model.set_cell_style(sheet, row, column, &style)?;
426 diff_list.push(Diff::SetCellStyle {
427 sheet,
428 row,
429 column,
430 old_value: Box::new(Some(old_value)),
431 new_value: Box::new(style),
432 });
433 }
434 }
435 }
436 if last_row < LAST_ROW
438 && [
439 BorderType::All,
440 BorderType::None,
441 BorderType::Outer,
442 BorderType::Bottom,
443 ]
444 .contains(&border_area.r#type)
445 {
446 let row = last_row + 1;
447 for column in first_column..=last_column {
448 let old_value = self.model.get_style_for_cell(sheet, row, column)?;
449 if is_max_border(Some(&border_area.item), old_value.border.top.as_ref()) {
450 let mut style = old_value.clone();
451 if border_area.r#type == BorderType::None {
452 style.border.top = None;
453 } else {
454 style.border.top = Some(border_area.item.clone());
455 }
456 self.model.set_cell_style(sheet, row, column, &style)?;
457 diff_list.push(Diff::SetCellStyle {
458 sheet,
459 row,
460 column,
461 old_value: Box::new(Some(old_value)),
462 new_value: Box::new(style),
463 });
464 }
465 }
466 }
467 if first_column > 1
469 && [
470 BorderType::All,
471 BorderType::None,
472 BorderType::Outer,
473 BorderType::Left,
474 ]
475 .contains(&border_area.r#type)
476 {
477 let column = first_column - 1;
478 for row in first_row..=last_row {
479 let old_value = self.model.get_style_for_cell(sheet, row, column)?;
480 if is_max_border(Some(&border_area.item), old_value.border.right.as_ref()) {
481 let mut style = old_value.clone();
482 if border_area.r#type == BorderType::None {
483 style.border.right = None;
484 } else {
485 style.border.right = Some(border_area.item.clone());
486 }
487 self.model.set_cell_style(sheet, row, column, &style)?;
488 diff_list.push(Diff::SetCellStyle {
489 sheet,
490 row,
491 column,
492 old_value: Box::new(Some(old_value)),
493 new_value: Box::new(style),
494 });
495 }
496 }
497 }
498
499 self.push_diff_list(diff_list);
500 Ok(())
501 }
502}