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