use super::BooleanValue;
use super::DoubleValue;
use super::Style;
use super::Stylesheet;
use super::UInt32Value;
use crate::reader::driver::*;
use crate::structs::Cells;
use crate::traits::AdjustmentValue;
use md5::Digest;
use quick_xml::events::BytesStart;
use quick_xml::Reader;
#[derive(Clone, Debug)]
pub struct Column {
col_num: UInt32Value,
pub(crate) width: DoubleValue,
pub(crate) hidden: BooleanValue,
pub(crate) best_fit: BooleanValue,
style: Box<Style>,
auto_width: BooleanValue,
}
impl Default for Column {
#[inline]
fn default() -> Self {
let mut width = DoubleValue::default();
width.set_value(8.38f64);
Self {
col_num: UInt32Value::default(),
width,
hidden: BooleanValue::default(),
best_fit: BooleanValue::default(),
style: Box::new(Style::default()),
auto_width: BooleanValue::default(),
}
}
}
impl Column {
#[inline]
pub fn get_col_num(&self) -> &u32 {
self.col_num.get_value()
}
#[inline]
pub fn set_col_num(&mut self, value: u32) -> &mut Self {
self.col_num.set_value(value);
self
}
#[inline]
pub fn get_width(&self) -> &f64 {
self.width.get_value()
}
#[inline]
pub fn set_width(&mut self, value: f64) -> &mut Self {
self.width.set_value(value);
self
}
#[inline]
pub fn get_hidden(&self) -> &bool {
self.hidden.get_value()
}
#[inline]
pub fn set_hidden(&mut self, value: bool) -> &mut Self {
self.hidden.set_value(value);
self
}
#[inline]
pub fn get_best_fit(&self) -> &bool {
self.best_fit.get_value()
}
#[inline]
pub fn set_best_fit(&mut self, value: bool) -> &mut Self {
self.best_fit.set_value(value);
self
}
#[inline]
pub fn get_style(&self) -> &Style {
&self.style
}
#[inline]
pub fn get_style_mut(&mut self) -> &mut Style {
&mut self.style
}
#[inline]
pub fn set_style(&mut self, value: Style) -> &mut Self {
self.style = Box::new(value);
self
}
#[inline]
pub fn get_auto_width(&self) -> &bool {
self.auto_width.get_value()
}
#[inline]
pub fn set_auto_width(&mut self, value: bool) -> &mut Self {
self.auto_width.set_value(value);
self
}
pub(crate) fn calculation_auto_width(&mut self, cells: &Cells) -> &mut Self {
if !*self.get_auto_width() {
return self;
}
let mut column_width_max = 0f64;
let column_font_size = match self.get_style().get_font() {
Some(font) => *font.get_font_size().get_val(),
None => 11f64,
};
for cell in cells.iter_cells_by_column(*self.get_col_num()) {
let column_width = cell.get_width_point(&column_font_size);
if column_width > column_width_max {
column_width_max = column_width;
}
}
if column_width_max == 0f64 {
column_width_max = 8.38f64;
}
self.set_width(column_width_max);
self
}
#[inline]
pub(crate) fn has_style(&self) -> bool {
&*self.style != &Style::default()
}
#[inline]
pub(crate) fn get_hash_code(&self) -> String {
format!(
"{:x}",
md5::Md5::digest(format!(
"{}{}{}",
&self.width.get_value_string(),
&self.hidden.get_value_string(),
&self.best_fit.get_value_string(),
))
)
}
pub(crate) fn set_attributes<R: std::io::BufRead>(
&mut self,
_reader: &mut Reader<R>,
e: &BytesStart,
stylesheet: &Stylesheet,
) {
set_string_from_xml!(self, e, width, "width");
set_string_from_xml!(self, e, hidden, "hidden");
set_string_from_xml!(self, e, best_fit, "bestFit");
if let Some(v) = get_attribute(e, b"style") {
let style = stylesheet.get_style(v.parse::<usize>().unwrap());
self.set_style(style);
}
}
}
impl AdjustmentValue for Column {
#[inline]
fn adjustment_insert_value(&mut self, root_num: &u32, offset_num: &u32) {
if self.col_num.get_value() >= root_num {
self.col_num
.set_value(self.col_num.get_value() + offset_num);
}
}
#[inline]
fn adjustment_remove_value(&mut self, root_num: &u32, offset_num: &u32) {
if self.col_num.get_value() >= root_num {
self.col_num
.set_value(self.col_num.get_value() - offset_num);
}
}
#[inline]
fn is_remove_value(&self, root_num: &u32, offset_num: &u32) -> bool {
self.col_num.get_value() >= root_num
&& self.col_num.get_value() <= &(root_num + offset_num - 1)
}
}