umya_spreadsheet/structs/drawing/
body_properties.rs1use 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 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}