umya_spreadsheet/structs/drawing/
body_properties.rs

1// a:bodyPr
2use super::super::EnumValue;
3use super::super::Int32Value;
4use super::ShapeAutoFit;
5use super::TextWrappingValues;
6use crate::reader::driver::*;
7use crate::writer::driver::*;
8use crate::BooleanValue;
9use crate::StringValue;
10use quick_xml::events::{BytesStart, Event};
11use quick_xml::Reader;
12use quick_xml::Writer;
13use std::io::Cursor;
14
15#[derive(Clone, Default, Debug)]
16pub struct BodyProperties {
17    vert_overflow: StringValue,
18    horz_overflow: StringValue,
19    rtl_col: StringValue,
20    anchor: StringValue,
21    wrap: EnumValue<TextWrappingValues>,
22    rotation: Int32Value,
23    left_inset: Int32Value,
24    top_inset: Int32Value,
25    right_inset: Int32Value,
26    bottom_inset: Int32Value,
27    use_paragraph_spacing: BooleanValue,
28    shape_auto_fit: Option<ShapeAutoFit>,
29}
30
31impl BodyProperties {
32    #[inline]
33    pub fn get_vert_overflow(&self) -> Option<&str> {
34        self.vert_overflow.get_value()
35    }
36
37    #[inline]
38    pub fn set_vert_overflow<S: Into<String>>(&mut self, value: S) -> &mut BodyProperties {
39        self.vert_overflow.set_value(value);
40        self
41    }
42
43    #[inline]
44    pub fn get_horz_overflow(&self) -> Option<&str> {
45        self.horz_overflow.get_value()
46    }
47
48    #[inline]
49    pub fn set_horz_overflow<S: Into<String>>(&mut self, value: S) -> &mut BodyProperties {
50        self.horz_overflow.set_value(value);
51        self
52    }
53
54    #[inline]
55    pub fn get_rtl_col(&self) -> Option<&str> {
56        self.rtl_col.get_value()
57    }
58
59    #[inline]
60    pub fn set_rtl_col<S: Into<String>>(&mut self, value: S) -> &mut BodyProperties {
61        self.rtl_col.set_value(value);
62        self
63    }
64
65    #[inline]
66    pub fn get_anchor(&self) -> Option<&str> {
67        self.anchor.get_value()
68    }
69
70    #[inline]
71    pub fn set_anchor<S: Into<String>>(&mut self, value: S) -> &mut BodyProperties {
72        self.anchor.set_value(value);
73        self
74    }
75
76    #[inline]
77    pub fn get_wrap(&self) -> &TextWrappingValues {
78        self.wrap.get_value()
79    }
80
81    #[inline]
82    pub fn set_wrap(&mut self, value: TextWrappingValues) -> &mut BodyProperties {
83        self.wrap.set_value(value);
84        self
85    }
86
87    #[inline]
88    pub fn get_rotation(&self) -> &i32 {
89        self.rotation.get_value()
90    }
91
92    #[inline]
93    pub fn set_rotation(&mut self, value: i32) {
94        self.rotation.set_value(value);
95    }
96
97    #[inline]
98    pub fn get_left_inset(&self) -> &i32 {
99        self.left_inset.get_value()
100    }
101
102    #[inline]
103    pub fn set_left_inset(&mut self, value: i32) {
104        self.left_inset.set_value(value);
105    }
106
107    #[inline]
108    pub fn get_top_inset(&self) -> &i32 {
109        self.top_inset.get_value()
110    }
111
112    #[inline]
113    pub fn set_top_inset(&mut self, value: i32) {
114        self.top_inset.set_value(value);
115    }
116
117    #[inline]
118    pub fn get_right_inset(&self) -> &i32 {
119        self.right_inset.get_value()
120    }
121
122    #[inline]
123    pub fn set_right_inset(&mut self, value: i32) {
124        self.right_inset.set_value(value);
125    }
126
127    #[inline]
128    pub fn get_bottom_inset(&self) -> &i32 {
129        self.bottom_inset.get_value()
130    }
131
132    #[inline]
133    pub fn set_bottom_inset(&mut self, value: i32) {
134        self.bottom_inset.set_value(value);
135    }
136
137    #[inline]
138    pub fn get_use_paragraph_spacing(&self) -> &bool {
139        self.use_paragraph_spacing.get_value()
140    }
141
142    #[inline]
143    pub fn set_use_paragraph_spacing(&mut self, value: bool) {
144        self.use_paragraph_spacing.set_value(value);
145    }
146
147    #[inline]
148    pub fn get_shape_auto_fit(&self) -> Option<&ShapeAutoFit> {
149        self.shape_auto_fit.as_ref()
150    }
151
152    #[inline]
153    pub fn set_shape_auto_fit(&mut self, value: ShapeAutoFit) -> &mut BodyProperties {
154        self.shape_auto_fit = Some(value);
155        self
156    }
157
158    pub(crate) fn set_attributes<R: std::io::BufRead>(
159        &mut self,
160        reader: &mut Reader<R>,
161        e: &BytesStart,
162        empty_flag: bool,
163    ) {
164        for attr in e.attributes().with_checks(false) {
165            if let Ok(attr) = attr {
166                let key = attr.key.into_inner();
167                let value = get_attribute_value(&attr).unwrap();
168                match key {
169                    b"rot" => {
170                        self.rotation.set_value_string(value);
171                    }
172                    b"vertOverflow" => {
173                        self.set_vert_overflow(value);
174                    }
175                    b"horzOverflow" => {
176                        self.set_horz_overflow(value);
177                    }
178                    b"rtlCol" => {
179                        self.set_rtl_col(value);
180                    }
181                    b"anchor" => {
182                        self.set_anchor(value);
183                    }
184                    b"wrap" => {
185                        self.wrap.set_value_string(value);
186                    }
187                    b"lIns" => {
188                        self.left_inset.set_value_string(value);
189                    }
190                    b"tIns" => {
191                        self.top_inset.set_value_string(value);
192                    }
193                    b"rIns" => {
194                        self.right_inset.set_value_string(value);
195                    }
196                    b"bIns" => {
197                        self.bottom_inset.set_value_string(value);
198                    }
199                    b"spcFirstLastPara" => {
200                        self.use_paragraph_spacing.set_value_string(value);
201                    }
202                    _ => {}
203                }
204            }
205        }
206
207        if empty_flag {
208            return;
209        }
210
211        xml_read_loop!(
212            reader,
213            Event::Empty(ref e) => {
214                if e.name().into_inner() == b"a:spAutoFit" {
215                    let mut obj = ShapeAutoFit::default();
216                    obj.set_attributes(reader, e);
217                    self.set_shape_auto_fit(obj);
218                }
219            },
220            Event::End(ref e) => {
221                if e.name().into_inner() == b"a:bodyPr" {
222                     return
223                }
224            },
225            Event::Eof => panic!("Error: Could not find {} end element", "a:bodyPr")
226        );
227    }
228
229    pub(crate) fn write_to(&self, writer: &mut Writer<Cursor<Vec<u8>>>) {
230        let empty_flag = &self.shape_auto_fit.is_none();
231
232        // a:bodyPr
233        let mut attributes: Vec<(&str, &str)> = Vec::new();
234        if let Some(v) = self.vert_overflow.get_value() {
235            attributes.push(("vertOverflow", v));
236        }
237        if let Some(v) = self.horz_overflow.get_value() {
238            attributes.push(("horzOverflow", v));
239        }
240        if let Some(v) = self.rtl_col.get_value() {
241            attributes.push(("rtlCol", v));
242        }
243        if let Some(v) = self.anchor.get_value() {
244            attributes.push(("anchor", v));
245        }
246        if self.wrap.has_value() {
247            attributes.push(("wrap", self.wrap.get_value_string()));
248        }
249        let rotation = self.rotation.get_value_string();
250        if self.rotation.has_value() {
251            attributes.push(("rot", &rotation));
252        }
253        let l_ins = self.left_inset.get_value_string();
254        if self.left_inset.has_value() {
255            attributes.push(("lIns", &l_ins));
256        }
257        let t_ins = self.top_inset.get_value_string();
258        if self.top_inset.has_value() {
259            attributes.push(("tIns", &t_ins));
260        }
261        let r_ins = self.right_inset.get_value_string();
262        if self.right_inset.has_value() {
263            attributes.push(("rIns", &r_ins));
264        }
265        let b_ins = self.bottom_inset.get_value_string();
266        if self.bottom_inset.has_value() {
267            attributes.push(("bIns", &b_ins));
268        }
269        if self.use_paragraph_spacing.has_value() {
270            attributes.push((
271                "spcFirstLastPara",
272                self.use_paragraph_spacing.get_value_string(),
273            ));
274        }
275
276        write_start_tag(writer, "a:bodyPr", attributes, *empty_flag);
277
278        if !*empty_flag {
279            if let Some(v) = &self.shape_auto_fit {
280                v.write_to(writer);
281            }
282
283            write_end_tag(writer, "a:bodyPr");
284        }
285    }
286}