FIX: [App]: Borders done right

This commit is contained in:
Nicolás Hatcher
2024-10-27 16:45:14 +01:00
committed by Nicolás Hatcher Andrés
parent 494a315cbd
commit 2c2228c2c2
6 changed files with 442 additions and 35 deletions

View File

@@ -51,6 +51,84 @@ fn borders_all() {
}
}
// let's check the borders around
{
let row = 4;
for column in 6..9 {
let style = model.get_cell_style(0, row, column).unwrap();
let border_item = BorderItem {
style: BorderStyle::Thin,
color: Some("#FF5566".to_string()),
};
let expected_border = Border {
diagonal_up: false,
diagonal_down: false,
left: None,
right: None,
top: None,
bottom: Some(border_item.clone()),
diagonal: None,
};
assert_eq!(style.border, expected_border);
}
let row = 9;
for column in 6..9 {
let style = model.get_cell_style(0, row, column).unwrap();
let border_item = BorderItem {
style: BorderStyle::Thin,
color: Some("#FF5566".to_string()),
};
let expected_border = Border {
diagonal_up: false,
diagonal_down: false,
left: None,
right: None,
top: Some(border_item.clone()),
bottom: None,
diagonal: None,
};
assert_eq!(style.border, expected_border);
}
}
{
let column = 5;
for row in 5..9 {
let style = model.get_cell_style(0, row, column).unwrap();
let border_item = BorderItem {
style: BorderStyle::Thin,
color: Some("#FF5566".to_string()),
};
let expected_border = Border {
diagonal_up: false,
diagonal_down: false,
left: None,
right: Some(border_item.clone()),
top: None,
bottom: None,
diagonal: None,
};
assert_eq!(style.border, expected_border);
}
let column = 9;
for row in 5..9 {
let style = model.get_cell_style(0, row, column).unwrap();
let border_item = BorderItem {
style: BorderStyle::Thin,
color: Some("#FF5566".to_string()),
};
let expected_border = Border {
diagonal_up: false,
diagonal_down: false,
left: Some(border_item.clone()),
right: None,
top: None,
bottom: None,
diagonal: None,
};
assert_eq!(style.border, expected_border);
}
}
// Lets remove all of them:
let border_area: BorderArea = serde_json::from_str(
r##"{
@@ -63,8 +141,8 @@ fn borders_all() {
)
.unwrap();
model.set_area_with_border(range, &border_area).unwrap();
for row in 5..9 {
for column in 6..9 {
for row in 4..10 {
for column in 5..10 {
let style = model.get_cell_style(0, row, column).unwrap();
let expected_border = Border {
diagonal_up: false,
@@ -229,6 +307,84 @@ fn borders_outer() {
};
assert_eq!(style.border, expected_border);
}
// let's check the borders around
{
let row = 4;
for column in 6..9 {
let style = model.get_cell_style(0, row, column).unwrap();
let border_item = BorderItem {
style: BorderStyle::Thin,
color: Some("#FF5566".to_string()),
};
let expected_border = Border {
diagonal_up: false,
diagonal_down: false,
left: None,
right: None,
top: None,
bottom: Some(border_item.clone()),
diagonal: None,
};
assert_eq!(style.border, expected_border);
}
let row = 9;
for column in 6..9 {
let style = model.get_cell_style(0, row, column).unwrap();
let border_item = BorderItem {
style: BorderStyle::Thin,
color: Some("#FF5566".to_string()),
};
let expected_border = Border {
diagonal_up: false,
diagonal_down: false,
left: None,
right: None,
top: Some(border_item.clone()),
bottom: None,
diagonal: None,
};
assert_eq!(style.border, expected_border);
}
}
{
let column = 5;
for row in 5..9 {
let style = model.get_cell_style(0, row, column).unwrap();
let border_item = BorderItem {
style: BorderStyle::Thin,
color: Some("#FF5566".to_string()),
};
let expected_border = Border {
diagonal_up: false,
diagonal_down: false,
left: None,
right: Some(border_item.clone()),
top: None,
bottom: None,
diagonal: None,
};
assert_eq!(style.border, expected_border);
}
let column = 9;
for row in 5..9 {
let style = model.get_cell_style(0, row, column).unwrap();
let border_item = BorderItem {
style: BorderStyle::Thin,
color: Some("#FF5566".to_string()),
};
let expected_border = Border {
diagonal_up: false,
diagonal_down: false,
left: Some(border_item.clone()),
right: None,
top: None,
bottom: None,
diagonal: None,
};
assert_eq!(style.border, expected_border);
}
}
}
#[test]
@@ -275,6 +431,72 @@ fn borders_top() {
assert_eq!(style.border, expected_border);
}
}
// let's check the borders around
{
let row = 4;
for column in 6..9 {
let style = model.get_cell_style(0, row, column).unwrap();
let border_item = BorderItem {
style: BorderStyle::Thin,
color: Some("#FF5566".to_string()),
};
let expected_border = Border {
diagonal_up: false,
diagonal_down: false,
left: None,
right: None,
top: None,
bottom: Some(border_item.clone()),
diagonal: None,
};
assert_eq!(style.border, expected_border);
}
let row = 9;
for column in 6..9 {
let style = model.get_cell_style(0, row, column).unwrap();
let expected_border = Border {
diagonal_up: false,
diagonal_down: false,
left: None,
right: None,
top: None,
bottom: None,
diagonal: None,
};
assert_eq!(style.border, expected_border);
}
}
{
let column = 5;
for row in 5..9 {
let style = model.get_cell_style(0, row, column).unwrap();
let expected_border = Border {
diagonal_up: false,
diagonal_down: false,
left: None,
right: None,
top: None,
bottom: None,
diagonal: None,
};
assert_eq!(style.border, expected_border);
}
let column = 9;
for row in 5..9 {
let style = model.get_cell_style(0, row, column).unwrap();
let expected_border = Border {
diagonal_up: false,
diagonal_down: false,
left: None,
right: None,
top: None,
bottom: None,
diagonal: None,
};
assert_eq!(style.border, expected_border);
}
}
}
#[test]

View File

@@ -48,6 +48,54 @@ fn tsv_crlf_paste() {
);
}
#[test]
fn cut_paste() {
let mut model = UserModel::new_empty("model", "en", "UTC").unwrap();
model.set_user_input(0, 1, 1, "42").unwrap();
model.set_user_input(0, 1, 2, "=A1*3+1").unwrap();
// set A1 bold
let range = Area {
sheet: 0,
row: 1,
column: 1,
width: 1,
height: 1,
};
model.update_range_style(&range, "font.b", "true").unwrap();
model
.set_user_input(0, 2, 1, "A season of faith, \"perfection\"")
.unwrap();
// Select A1:B2 and copy
model.set_selected_range(1, 1, 2, 2).unwrap();
let copy = model.copy_to_clipboard().unwrap();
model.set_selected_cell(4, 4).unwrap();
// paste in cell D4 (4, 4)
model
.paste_from_clipboard((1, 1, 2, 2), &copy.data, true)
.unwrap();
assert_eq!(model.get_cell_content(0, 4, 4), Ok("42".to_string()));
assert_eq!(model.get_cell_content(0, 4, 5), Ok("=D4*3+1".to_string()));
assert_eq!(
model.get_formatted_cell_value(0, 4, 5),
Ok("127".to_string())
);
// cell D4 must be bold
let style_d4 = model.get_cell_style(0, 4, 4).unwrap();
assert!(style_d4.font.b);
// range A1:B2 must be empty
assert_eq!(model.get_cell_content(0, 1, 1), Ok("".to_string()));
assert_eq!(model.get_cell_content(0, 1, 2), Ok("".to_string()));
assert_eq!(model.get_cell_content(0, 2, 1), Ok("".to_string()));
assert_eq!(model.get_cell_content(0, 2, 2), Ok("".to_string()));
}
#[test]
fn copy_paste_internal() {
let mut model = UserModel::new_empty("model", "en", "UTC").unwrap();

View File

@@ -7,7 +7,7 @@ use csv_sniffer::Sniffer;
use serde::{Deserialize, Serialize};
use crate::{
constants::{self, DEFAULT_ROW_HEIGHT},
constants::{self, DEFAULT_ROW_HEIGHT, LAST_COLUMN, LAST_ROW},
expressions::{
types::{Area, CellReferenceIndex},
utils::{is_valid_column_number, is_valid_row},
@@ -41,7 +41,7 @@ pub struct Clipboard {
pub(crate) range: (i32, i32, i32, i32),
}
#[derive(Serialize, Deserialize)]
#[derive(Serialize, Deserialize, PartialEq)]
pub enum BorderType {
All,
Inner,
@@ -796,7 +796,6 @@ impl UserModel {
range: &Area,
border_area: &BorderArea,
) -> Result<(), String> {
// FIXME: We need to set the border also in neighbouring cells.
let sheet = range.sheet;
let mut diff_list = Vec::new();
let last_row = range.row + range.height - 1;
@@ -806,12 +805,6 @@ impl UserModel {
let old_value = self.model.get_style_for_cell(sheet, row, column)?;
let mut style = old_value.clone();
// First remove all existing borders
style.border.top = None;
style.border.right = None;
style.border.bottom = None;
style.border.left = None;
match border_area.r#type {
BorderType::All => {
style.border.top = Some(border_area.item.clone());
@@ -868,7 +861,10 @@ impl UserModel {
}
}
BorderType::None => {
// noop, we already removed all the borders
style.border.top = None;
style.border.right = None;
style.border.bottom = None;
style.border.left = None;
}
}
@@ -882,6 +878,122 @@ impl UserModel {
});
}
}
// bottom of the cells above the first
if range.row > 1
&& [
BorderType::Top,
BorderType::All,
BorderType::None,
BorderType::Outer,
]
.contains(&border_area.r#type)
{
let row = range.row - 1;
for column in range.column..=last_column {
let old_value = self.model.get_style_for_cell(sheet, row, column)?;
let mut style = old_value.clone();
if border_area.r#type == BorderType::None {
style.border.bottom = None;
} else {
style.border.bottom = Some(border_area.item.clone());
}
self.model.set_cell_style(sheet, row, column, &style)?;
diff_list.push(Diff::SetCellStyle {
sheet,
row,
column,
old_value: Box::new(old_value),
new_value: Box::new(style),
});
}
}
// Cells to the right
if last_column < LAST_COLUMN
&& [
BorderType::Right,
BorderType::All,
BorderType::None,
BorderType::Outer,
]
.contains(&border_area.r#type)
{
let column = last_column + 1;
for row in range.row..=last_row {
let old_value = self.model.get_style_for_cell(sheet, row, column)?;
let mut style = old_value.clone();
if border_area.r#type == BorderType::None {
style.border.left = None;
} else {
style.border.left = Some(border_area.item.clone());
}
self.model.set_cell_style(sheet, row, column, &style)?;
diff_list.push(Diff::SetCellStyle {
sheet,
row,
column,
old_value: Box::new(old_value),
new_value: Box::new(style),
});
}
}
// Cells bellow
if last_row < LAST_ROW
&& [
BorderType::Bottom,
BorderType::All,
BorderType::None,
BorderType::Outer,
]
.contains(&border_area.r#type)
{
let row = last_row + 1;
for column in range.column..=last_column {
let old_value = self.model.get_style_for_cell(sheet, row, column)?;
let mut style = old_value.clone();
if border_area.r#type == BorderType::None {
style.border.top = None;
} else {
style.border.top = Some(border_area.item.clone());
}
self.model.set_cell_style(sheet, row, column, &style)?;
diff_list.push(Diff::SetCellStyle {
sheet,
row,
column,
old_value: Box::new(old_value),
new_value: Box::new(style),
});
}
}
// Cells to the left
if range.column > 1
&& [
BorderType::Left,
BorderType::All,
BorderType::None,
BorderType::Outer,
]
.contains(&border_area.r#type)
{
let column = range.column - 1;
for row in range.row..=last_row {
let old_value = self.model.get_style_for_cell(sheet, row, column)?;
let mut style = old_value.clone();
if border_area.r#type == BorderType::None {
style.border.right = None;
} else {
style.border.right = Some(border_area.item.clone());
}
self.model.set_cell_style(sheet, row, column, &style)?;
diff_list.push(Diff::SetCellStyle {
sheet,
row,
column,
old_value: Box::new(old_value),
new_value: Box::new(style),
});
}
}
self.push_diff_list(diff_list);
Ok(())