Skip to main content

umya_spreadsheet/structs/
column.rs

1use quick_xml::{
2    Reader,
3    events::BytesStart,
4};
5
6use super::{
7    BooleanValue,
8    DoubleValue,
9    Style,
10    Stylesheet,
11    UInt32Value,
12};
13use crate::{
14    reader::driver::{
15        get_attribute,
16        set_string_from_xml,
17    },
18    structs::Cells,
19    traits::AdjustmentValue,
20};
21
22/// # Examples
23/// ## set auto width
24/// ```rust
25/// use umya_spreadsheet::*;
26/// let mut book = new_file();
27/// let mut worksheet = book.sheet_by_name_mut("Sheet1").unwrap();
28/// worksheet.column_dimension_mut("A").set_auto_width(true);
29/// ```
30/// ## set manual width
31/// ```rust
32/// use umya_spreadsheet::*;
33/// let mut book = new_file();
34/// let mut worksheet = book.sheet_by_name_mut("Sheet1").unwrap();
35/// worksheet.column_dimension_mut("A").set_width(60f64);
36/// ```
37#[derive(Clone, Debug)]
38pub struct Column {
39    col_num:             UInt32Value,
40    pub(crate) width:    DoubleValue,
41    pub(crate) hidden:   BooleanValue,
42    pub(crate) best_fit: BooleanValue,
43    style:               Box<Style>,
44    auto_width:          BooleanValue,
45}
46
47impl Default for Column {
48    #[inline]
49    fn default() -> Self {
50        let mut width = DoubleValue::default();
51        width.set_value(8.38f64);
52        Self {
53            col_num: UInt32Value::default(),
54            width,
55            hidden: BooleanValue::default(),
56            best_fit: BooleanValue::default(),
57            style: Box::new(Style::default()),
58            auto_width: BooleanValue::default(),
59        }
60    }
61}
62
63impl Column {
64    #[inline]
65    #[must_use]
66    pub fn col_num(&self) -> u32 {
67        self.col_num.value()
68    }
69
70    #[inline]
71    #[must_use]
72    #[deprecated(since = "3.0.0", note = "Use col_num()")]
73    pub fn get_col_num(&self) -> u32 {
74        self.col_num()
75    }
76
77    #[inline]
78    pub fn set_col_num(&mut self, value: u32) -> &mut Self {
79        self.col_num.set_value(value);
80        self
81    }
82
83    #[inline]
84    #[must_use]
85    pub fn width(&self) -> f64 {
86        self.width.value()
87    }
88
89    #[inline]
90    #[must_use]
91    #[deprecated(since = "3.0.0", note = "Use width()")]
92    pub fn get_width(&self) -> f64 {
93        self.width()
94    }
95
96    #[inline]
97    pub fn set_width(&mut self, value: f64) -> &mut Self {
98        self.width.set_value(value);
99        self
100    }
101
102    #[inline]
103    #[must_use]
104    pub fn hidden(&self) -> bool {
105        self.hidden.value()
106    }
107
108    #[inline]
109    #[must_use]
110    #[deprecated(since = "3.0.0", note = "Use hidden()")]
111    pub fn get_hidden(&self) -> bool {
112        self.hidden()
113    }
114
115    #[inline]
116    pub fn set_hidden(&mut self, value: bool) -> &mut Self {
117        self.hidden.set_value(value);
118        self
119    }
120
121    #[inline]
122    #[must_use]
123    pub fn best_fit(&self) -> bool {
124        self.best_fit.value()
125    }
126
127    #[inline]
128    #[must_use]
129    #[deprecated(since = "3.0.0", note = "Use best_fit()")]
130    pub fn get_best_fit(&self) -> bool {
131        self.best_fit()
132    }
133
134    #[inline]
135    pub fn set_best_fit(&mut self, value: bool) -> &mut Self {
136        self.best_fit.set_value(value);
137        self
138    }
139
140    #[inline]
141    #[must_use]
142    pub fn style(&self) -> &Style {
143        &self.style
144    }
145
146    #[inline]
147    #[must_use]
148    #[deprecated(since = "3.0.0", note = "Use style()")]
149    pub fn get_style(&self) -> &Style {
150        self.style()
151    }
152
153    #[inline]
154    pub fn style_mut(&mut self) -> &mut Style {
155        &mut self.style
156    }
157
158    #[inline]
159    #[deprecated(since = "3.0.0", note = "Use style()")]
160    pub fn get_style_mut(&mut self) -> &mut Style {
161        self.style_mut()
162    }
163
164    #[inline]
165    pub fn set_style(&mut self, value: Style) -> &mut Self {
166        *self.style = value;
167        self
168    }
169
170    #[inline]
171    #[must_use]
172    pub fn auto_width(&self) -> bool {
173        self.auto_width.value()
174    }
175
176    #[inline]
177    #[must_use]
178    #[deprecated(since = "3.0.0", note = "Use auto_width()")]
179    pub fn get_auto_width(&self) -> bool {
180        self.auto_width()
181    }
182
183    #[inline]
184    pub fn set_auto_width(&mut self, value: bool) -> &mut Self {
185        self.auto_width.set_value(value);
186        self
187    }
188
189    pub(crate) fn calculation_auto_width(&mut self, cells: &Cells) -> &mut Self {
190        if !self.auto_width() {
191            return self;
192        }
193
194        let mut column_width_max = 0f64;
195
196        // default font size len.
197        let column_font_size = match self.style().font() {
198            Some(font) => font.font_size().val(),
199            None => 11f64,
200        };
201
202        for cell in cells.iter_cells_by_column(self.col_num()) {
203            let column_width = cell.width_point(column_font_size);
204
205            if column_width > column_width_max {
206                column_width_max = column_width;
207            }
208        }
209
210        // set default width if empty column.
211        if column_width_max == 0f64 {
212            column_width_max = 8.38f64;
213        }
214
215        self.set_width(column_width_max);
216        self
217    }
218
219    #[inline]
220    pub(crate) fn has_style(&self) -> bool {
221        *self.style != Style::default()
222    }
223
224    #[inline]
225    pub(crate) fn hash_code(&self) -> String {
226        crate::helper::utils::md5_hash(format!(
227            "{}{}{}",
228            self.width.value_string(),
229            self.hidden.value_string(),
230            self.best_fit.value_string(),
231        ))
232    }
233
234    #[inline]
235    #[deprecated(since = "3.0.0", note = "Use hash_code()")]
236    pub(crate) fn get_hash_code(&self) -> String {
237        self.hash_code()
238    }
239
240    pub(crate) fn set_attributes<R: std::io::BufRead>(
241        &mut self,
242        _reader: &mut Reader<R>,
243        e: &BytesStart,
244        stylesheet: &Stylesheet,
245    ) {
246        set_string_from_xml!(self, e, width, "width");
247        set_string_from_xml!(self, e, hidden, "hidden");
248        set_string_from_xml!(self, e, best_fit, "bestFit");
249
250        if let Some(v) = get_attribute(e, b"style") {
251            let style = stylesheet.style(v.parse::<usize>().unwrap());
252            self.set_style(style);
253        }
254    }
255}
256impl AdjustmentValue for Column {
257    #[inline]
258    fn adjustment_insert_value(&mut self, root_num: u32, offset_num: u32) {
259        if self.col_num.value() >= root_num {
260            self.col_num.set_value(self.col_num.value() + offset_num);
261        }
262    }
263
264    #[inline]
265    fn adjustment_remove_value(&mut self, root_num: u32, offset_num: u32) {
266        if self.col_num.value() >= root_num {
267            self.col_num.set_value(self.col_num.value() - offset_num);
268        }
269    }
270
271    #[inline]
272    fn is_remove_value(&self, root_num: u32, offset_num: u32) -> bool {
273        self.col_num.value() >= root_num && self.col_num.value() < root_num + offset_num
274    }
275}