umya_spreadsheet/structs/
row.rs

1use super::BooleanValue;
2use super::Cell;
3use super::Cells;
4use super::DoubleValue;
5use super::SharedStringTable;
6use super::Style;
7use super::Stylesheet;
8use super::UInt32Value;
9use crate::helper::formula::*;
10use crate::reader::driver::*;
11use crate::traits::AdjustmentValue;
12use crate::writer::driver::*;
13use quick_xml::events::{BytesStart, Event};
14use quick_xml::Reader;
15use quick_xml::Writer;
16use std::collections::HashMap;
17use std::io::Cursor;
18
19#[derive(Clone, Debug, PartialEq, PartialOrd)]
20pub struct Row {
21    row_num: UInt32Value,
22    height: DoubleValue,
23    descent: DoubleValue,
24    thick_bot: BooleanValue,
25    custom_height: BooleanValue,
26    hidden: BooleanValue,
27    style: Box<Style>,
28}
29impl Default for Row {
30    #[inline]
31    fn default() -> Self {
32        Self {
33            row_num: UInt32Value::default(),
34            height: DoubleValue::default(),
35            descent: DoubleValue::default(),
36            thick_bot: BooleanValue::default(),
37            custom_height: BooleanValue::default(),
38            hidden: BooleanValue::default(),
39            style: Box::new(Style::default()),
40        }
41    }
42}
43impl Row {
44    #[inline]
45    pub fn get_row_num(&self) -> &u32 {
46        self.row_num.get_value()
47    }
48
49    #[inline]
50    pub(crate) fn set_row_num(&mut self, value: u32) -> &mut Self {
51        self.row_num.set_value(value);
52        self
53    }
54
55    #[inline]
56    pub fn get_height(&self) -> &f64 {
57        self.height.get_value()
58    }
59
60    #[inline]
61    pub fn set_height(&mut self, value: f64) -> &mut Self {
62        self.height.set_value(value);
63        self.custom_height.set_value(true);
64        self
65    }
66
67    #[inline]
68    pub fn get_descent(&self) -> &f64 {
69        self.descent.get_value()
70    }
71
72    #[inline]
73    pub fn set_descent(&mut self, value: f64) -> &mut Self {
74        self.descent.set_value(value);
75        self
76    }
77
78    #[inline]
79    pub fn get_thick_bot(&self) -> &bool {
80        self.thick_bot.get_value()
81    }
82
83    #[inline]
84    pub fn set_thick_bot(&mut self, value: bool) -> &mut Self {
85        self.thick_bot.set_value(value);
86        self
87    }
88
89    #[inline]
90    pub fn get_custom_height(&self) -> &bool {
91        self.custom_height.get_value()
92    }
93
94    #[inline]
95    pub fn set_custom_height(&mut self, value: bool) -> &mut Self {
96        self.custom_height.set_value(value);
97        self
98    }
99
100    #[inline]
101    pub fn get_hidden(&self) -> &bool {
102        self.hidden.get_value()
103    }
104
105    #[inline]
106    pub fn set_hidden(&mut self, value: bool) -> &mut Self {
107        self.hidden.set_value(value);
108        self
109    }
110
111    #[inline]
112    pub fn get_style(&self) -> &Style {
113        &self.style
114    }
115
116    #[inline]
117    pub fn get_style_mut(&mut self) -> &mut Style {
118        &mut self.style
119    }
120
121    #[inline]
122    pub fn set_style(&mut self, value: Style) -> &mut Self {
123        self.style = Box::new(value);
124        self
125    }
126
127    #[inline]
128    pub(crate) fn has_style(&self) -> bool {
129        &*self.style != &Style::default()
130    }
131
132    pub(crate) fn set_attributes<R: std::io::BufRead>(
133        &mut self,
134        reader: &mut Reader<R>,
135        e: &BytesStart,
136        cells: &mut Cells,
137        shared_string_table: &SharedStringTable,
138        stylesheet: &Stylesheet,
139        formula_shared_list: &mut HashMap<u32, (String, Vec<FormulaToken>)>,
140        empty_flag: bool,
141    ) {
142        set_string_from_xml!(self, e, row_num, "r");
143        set_string_from_xml!(self, e, height, "ht");
144        set_string_from_xml!(self, e, thick_bot, "thickBot");
145        set_string_from_xml!(self, e, custom_height, "customHeight");
146        set_string_from_xml!(self, e, hidden, "hidden");
147
148        if let Some(v) = get_attribute(e, b"x14ac:dyDescent") {
149            if !v.is_empty() {
150                self.descent.set_value_string(v);
151            }
152        }
153
154        if let Some(v) = get_attribute(e, b"s") {
155            let style = stylesheet.get_style(v.parse::<usize>().unwrap());
156            self.set_style(style);
157        }
158
159        if empty_flag {
160            return;
161        }
162
163        xml_read_loop!(
164            reader,
165            Event::Empty(ref e) => {
166                if e.name().into_inner() == b"c" {
167                    let mut obj = Cell::default();
168                    obj.set_attributes(reader, e, shared_string_table, stylesheet, true, formula_shared_list);
169                    cells.set_fast(obj);
170                }
171            },
172            Event::Start(ref e) => {
173                if e.name().into_inner() == b"c" {
174                    let mut obj = Cell::default();
175                    obj.set_attributes(reader, e, shared_string_table, stylesheet, false, formula_shared_list);
176                    cells.set_fast(obj);
177                }
178            },
179            Event::End(ref e) => {
180                if e.name().into_inner() == b"row" {
181                    return
182                }
183            },
184            Event::Eof => panic!("Error: Could not find {} end element", "row")
185        );
186    }
187
188    pub(crate) fn write_to(
189        &self,
190        writer: &mut Writer<Cursor<Vec<u8>>>,
191        stylesheet: &mut Stylesheet,
192        spans: &str,
193        empty_flag: bool,
194    ) {
195        let xf_index_str: String;
196        let xf_index = stylesheet.set_style(self.get_style());
197
198        // row
199        let mut attributes: Vec<(&str, &str)> = Vec::new();
200        let row_num = self.row_num.get_value_string();
201        attributes.push(("r", &row_num));
202        if !empty_flag {
203            attributes.push(("spans", spans));
204        }
205        let height = self.height.get_value_string();
206        if self.height.get_value() != &0f64 {
207            attributes.push(("ht", &height));
208        }
209        if *self.thick_bot.get_value() {
210            attributes.push(("thickBot", self.thick_bot.get_value_string()));
211        }
212        if *self.custom_height.get_value() {
213            attributes.push(("customHeight", self.custom_height.get_value_string()));
214        }
215        if xf_index > 0 {
216            attributes.push(("customFormat", "1"));
217        }
218        if *self.hidden.get_value() {
219            attributes.push(("hidden", self.hidden.get_value_string()));
220        }
221        let descent = self.descent.get_value_string();
222        if self.descent.has_value() {
223            attributes.push(("x14ac:dyDescent", &descent));
224        }
225
226        if xf_index > 0 {
227            xf_index_str = xf_index.to_string();
228            attributes.push(("s", &xf_index_str));
229        }
230
231        write_start_tag(writer, "row", attributes, empty_flag);
232    }
233}
234impl AdjustmentValue for Row {
235    #[inline]
236    fn adjustment_insert_value(&mut self, root_num: &u32, offset_num: &u32) {
237        if self.row_num.get_value() >= root_num {
238            self.row_num
239                .set_value(self.row_num.get_value() + offset_num);
240        }
241    }
242
243    #[inline]
244    fn adjustment_remove_value(&mut self, root_num: &u32, offset_num: &u32) {
245        if self.row_num.get_value() >= root_num {
246            self.row_num
247                .set_value(self.row_num.get_value() - offset_num);
248        }
249    }
250
251    #[inline]
252    fn is_remove_value(&self, root_num: &u32, offset_num: &u32) -> bool {
253        self.row_num.get_value() >= root_num
254            && self.row_num.get_value() <= &(root_num + offset_num - 1)
255    }
256}