FIX: [App]: Borders done right
This commit is contained in:
committed by
Nicolás Hatcher Andrés
parent
494a315cbd
commit
2c2228c2c2
@@ -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]
|
||||
|
||||
@@ -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), ©.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();
|
||||
|
||||
@@ -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(())
|
||||
|
||||
Reference in New Issue
Block a user