Skip to main content

umya_spreadsheet/structs/drawing/
body_properties.rs

1// a:bodyPr
2use std::io::Cursor;
3
4use quick_xml::{
5    Reader,
6    Writer,
7    events::{
8        BytesStart,
9        Event,
10    },
11};
12
13use super::{
14    super::{
15        BooleanValue,
16        EnumValue,
17        Int32Value,
18    },
19    ShapeAutoFit,
20    TextWrappingValues,
21};
22use crate::{
23    StringValue,
24    reader::driver::{
25        get_attribute_value,
26        xml_read_loop,
27    },
28    writer::driver::{
29        write_end_tag,
30        write_start_tag,
31    },
32};
33
34#[derive(Clone, Default, Debug)]
35pub struct BodyProperties {
36    vert_overflow:         StringValue,
37    horz_overflow:         StringValue,
38    rtl_col:               StringValue,
39    anchor:                StringValue,
40    wrap:                  EnumValue<TextWrappingValues>,
41    rotation:              Int32Value,
42    left_inset:            Int32Value,
43    top_inset:             Int32Value,
44    right_inset:           Int32Value,
45    bottom_inset:          Int32Value,
46    use_paragraph_spacing: BooleanValue,
47    shape_auto_fit:        Option<ShapeAutoFit>,
48}
49
50impl BodyProperties {
51    #[inline]
52    #[must_use]
53    pub fn vert_overflow(&self) -> Option<&str> {
54        self.vert_overflow.value()
55    }
56
57    #[inline]
58    #[must_use]
59    #[deprecated(since = "3.0.0", note = "Use vert_overflow()")]
60    pub fn get_vert_overflow(&self) -> Option<&str> {
61        self.vert_overflow()
62    }
63
64    #[inline]
65    pub fn set_vert_overflow<S: Into<String>>(&mut self, value: S) -> &mut BodyProperties {
66        self.vert_overflow.set_value(value);
67        self
68    }
69
70    #[inline]
71    #[must_use]
72    pub fn horz_overflow(&self) -> Option<&str> {
73        self.horz_overflow.value()
74    }
75
76    #[inline]
77    #[must_use]
78    #[deprecated(since = "3.0.0", note = "Use horz_overflow()")]
79    pub fn get_horz_overflow(&self) -> Option<&str> {
80        self.horz_overflow()
81    }
82
83    #[inline]
84    pub fn set_horz_overflow<S: Into<String>>(&mut self, value: S) -> &mut BodyProperties {
85        self.horz_overflow.set_value(value);
86        self
87    }
88
89    #[inline]
90    #[must_use]
91    pub fn rtl_col(&self) -> Option<&str> {
92        self.rtl_col.value()
93    }
94
95    #[inline]
96    #[must_use]
97    #[deprecated(since = "3.0.0", note = "Use rtl_col()")]
98    pub fn get_rtl_col(&self) -> Option<&str> {
99        self.rtl_col()
100    }
101
102    #[inline]
103    pub fn set_rtl_col<S: Into<String>>(&mut self, value: S) -> &mut BodyProperties {
104        self.rtl_col.set_value(value);
105        self
106    }
107
108    #[inline]
109    #[must_use]
110    pub fn anchor(&self) -> Option<&str> {
111        self.anchor.value()
112    }
113
114    #[inline]
115    #[must_use]
116    #[deprecated(since = "3.0.0", note = "Use anchor()")]
117    pub fn get_anchor(&self) -> Option<&str> {
118        self.anchor()
119    }
120
121    #[inline]
122    pub fn set_anchor<S: Into<String>>(&mut self, value: S) -> &mut BodyProperties {
123        self.anchor.set_value(value);
124        self
125    }
126
127    #[inline]
128    #[must_use]
129    pub fn wrap(&self) -> &TextWrappingValues {
130        self.wrap.value()
131    }
132
133    #[inline]
134    #[must_use]
135    #[deprecated(since = "3.0.0", note = "Use wrap()")]
136    pub fn get_wrap(&self) -> &TextWrappingValues {
137        self.wrap()
138    }
139
140    #[inline]
141    pub fn set_wrap(&mut self, value: TextWrappingValues) -> &mut BodyProperties {
142        self.wrap.set_value(value);
143        self
144    }
145
146    #[inline]
147    #[must_use]
148    pub fn rotation(&self) -> i32 {
149        self.rotation.value()
150    }
151
152    #[inline]
153    #[must_use]
154    #[deprecated(since = "3.0.0", note = "Use rotation()")]
155    pub fn get_rotation(&self) -> i32 {
156        self.rotation()
157    }
158
159    #[inline]
160    pub fn set_rotation(&mut self, value: i32) {
161        self.rotation.set_value(value);
162    }
163
164    #[inline]
165    #[must_use]
166    pub fn left_inset(&self) -> i32 {
167        self.left_inset.value()
168    }
169
170    #[inline]
171    #[must_use]
172    #[deprecated(since = "3.0.0", note = "Use left_inset()")]
173    pub fn get_left_inset(&self) -> i32 {
174        self.left_inset()
175    }
176
177    #[inline]
178    pub fn set_left_inset(&mut self, value: i32) {
179        self.left_inset.set_value(value);
180    }
181
182    #[inline]
183    #[must_use]
184    pub fn top_inset(&self) -> i32 {
185        self.top_inset.value()
186    }
187
188    #[inline]
189    #[must_use]
190    #[deprecated(since = "3.0.0", note = "Use top_inset()")]
191    pub fn get_top_inset(&self) -> i32 {
192        self.top_inset()
193    }
194
195    #[inline]
196    pub fn set_top_inset(&mut self, value: i32) {
197        self.top_inset.set_value(value);
198    }
199
200    #[inline]
201    #[must_use]
202    pub fn right_inset(&self) -> i32 {
203        self.right_inset.value()
204    }
205
206    #[inline]
207    #[must_use]
208    #[deprecated(since = "3.0.0", note = "Use right_inset()")]
209    pub fn get_right_inset(&self) -> i32 {
210        self.right_inset()
211    }
212
213    #[inline]
214    pub fn set_right_inset(&mut self, value: i32) {
215        self.right_inset.set_value(value);
216    }
217
218    #[inline]
219    #[must_use]
220    pub fn bottom_inset(&self) -> i32 {
221        self.bottom_inset.value()
222    }
223
224    #[inline]
225    #[must_use]
226    #[deprecated(since = "3.0.0", note = "Use bottom_inset()")]
227    pub fn get_bottom_inset(&self) -> i32 {
228        self.bottom_inset()
229    }
230
231    #[inline]
232    pub fn set_bottom_inset(&mut self, value: i32) {
233        self.bottom_inset.set_value(value);
234    }
235
236    #[inline]
237    #[must_use]
238    pub fn shape_auto_fit(&self) -> Option<&ShapeAutoFit> {
239        self.shape_auto_fit.as_ref()
240    }
241
242    #[inline]
243    #[must_use]
244    pub fn use_paragraph_spacing(&self) -> bool {
245        self.use_paragraph_spacing.value()
246    }
247
248    #[inline]
249    #[must_use]
250    #[deprecated(since = "3.0.0", note = "Use use_paragraph_spacing()")]
251    pub fn get_use_paragraph_spacing(&self) -> bool {
252        self.use_paragraph_spacing()
253    }
254
255    #[inline]
256    pub fn set_use_paragraph_spacing(&mut self, value: bool) {
257        self.use_paragraph_spacing.set_value(value);
258    }
259
260    #[inline]
261    #[must_use]
262    #[deprecated(since = "3.0.0", note = "Use shape_auto_fit()")]
263    pub fn get_shape_auto_fit(&self) -> Option<&ShapeAutoFit> {
264        self.shape_auto_fit()
265    }
266
267    #[inline]
268    pub fn set_shape_auto_fit(&mut self, value: ShapeAutoFit) -> &mut BodyProperties {
269        self.shape_auto_fit = Some(value);
270        self
271    }
272
273    pub(crate) fn set_attributes<R: std::io::BufRead>(
274        &mut self,
275        reader: &mut Reader<R>,
276        e: &BytesStart,
277        empty_flag: bool,
278    ) {
279        for attr in e.attributes().with_checks(false).flatten() {
280            let key = attr.key.into_inner();
281            let value = get_attribute_value(&attr).unwrap();
282            match key {
283                b"rot" => {
284                    self.rotation.set_value_string(value);
285                }
286                b"vertOverflow" => {
287                    self.set_vert_overflow(value);
288                }
289                b"horzOverflow" => {
290                    self.set_horz_overflow(value);
291                }
292                b"rtlCol" => {
293                    self.set_rtl_col(value);
294                }
295                b"anchor" => {
296                    self.set_anchor(value);
297                }
298                b"wrap" => {
299                    self.wrap.set_value_string(value);
300                }
301                b"lIns" => {
302                    self.left_inset.set_value_string(value);
303                }
304                b"tIns" => {
305                    self.top_inset.set_value_string(value);
306                }
307                b"rIns" => {
308                    self.right_inset.set_value_string(value);
309                }
310                b"bIns" => {
311                    self.bottom_inset.set_value_string(value);
312                }
313                b"spcFirstLastPara" => {
314                    self.use_paragraph_spacing.set_value_string(value);
315                }
316                _ => {}
317            }
318        }
319
320        if empty_flag {
321            return;
322        }
323
324        xml_read_loop!(
325            reader,
326            Event::Empty(ref e) => {
327                if e.name().into_inner() == b"a:spAutoFit" {
328                    let obj = ShapeAutoFit::default();
329                    ShapeAutoFit::set_attributes(reader, e);
330                    self.set_shape_auto_fit(obj);
331                }
332            },
333            Event::End(ref e) => {
334                if e.name().into_inner() == b"a:bodyPr" {
335                     return
336                }
337            },
338            Event::Eof => panic!("Error: Could not find {} end element", "a:bodyPr")
339        );
340    }
341
342    pub(crate) fn write_to(&self, writer: &mut Writer<Cursor<Vec<u8>>>) {
343        let empty_flag = &self.shape_auto_fit.is_none();
344
345        // a:bodyPr
346        let mut attributes: crate::structs::AttrCollection = Vec::new();
347        if let Some(v) = self.vert_overflow.value() {
348            attributes.push(("vertOverflow", v).into());
349        }
350        if let Some(v) = self.horz_overflow.value() {
351            attributes.push(("horzOverflow", v).into());
352        }
353        if let Some(v) = self.rtl_col.value() {
354            attributes.push(("rtlCol", v).into());
355        }
356        if let Some(v) = self.anchor.value() {
357            attributes.push(("anchor", v).into());
358        }
359        if self.wrap.has_value() {
360            attributes.push(("wrap", self.wrap.value_string()).into());
361        }
362        let rotation = self.rotation.value_string();
363        if self.rotation.has_value() {
364            attributes.push(("rot", &rotation).into());
365        }
366        let l_ins = self.left_inset.value_string();
367        if self.left_inset.has_value() {
368            attributes.push(("lIns", &l_ins).into());
369        }
370        let t_ins = self.top_inset.value_string();
371        if self.top_inset.has_value() {
372            attributes.push(("tIns", &t_ins).into());
373        }
374        let r_ins = self.right_inset.value_string();
375        if self.right_inset.has_value() {
376            attributes.push(("rIns", &r_ins).into());
377        }
378        let b_ins = self.bottom_inset.value_string();
379        if self.bottom_inset.has_value() {
380            attributes.push(("bIns", &b_ins).into());
381        }
382        if self.use_paragraph_spacing.has_value() {
383            attributes.push(
384                (
385                    "spcFirstLastPara",
386                    self.use_paragraph_spacing.value_string(),
387                )
388                    .into(),
389            );
390        }
391
392        write_start_tag(writer, "a:bodyPr", attributes, *empty_flag);
393
394        if !*empty_flag {
395            if self.shape_auto_fit.is_some() {
396                ShapeAutoFit::write_to(writer);
397            }
398
399            write_end_tag(writer, "a:bodyPr");
400        }
401    }
402}