Skip to main content

umya_spreadsheet/structs/drawing/spreadsheet/
shape_properties.rs

1// xdr:spPr
2use std::io::Cursor;
3
4use quick_xml::{
5    Reader,
6    Writer,
7    events::{
8        BytesStart,
9        Event,
10    },
11};
12
13use super::super::{
14    BlipFill,
15    EffectList,
16    ExtensionList,
17    NoFill,
18    Outline,
19    PresetGeometry,
20    SolidFill,
21    Transform2D,
22};
23use crate::{
24    EnumValue,
25    drawing::{
26        BlackWhiteModeValues,
27        GradientFill,
28    },
29    reader::driver::{
30        get_attribute,
31        set_string_from_xml,
32        xml_read_loop,
33    },
34    structs::raw::RawRelationships,
35    writer::driver::{
36        write_end_tag,
37        write_start_tag,
38    },
39};
40
41#[derive(Clone, Default, Debug)]
42pub struct ShapeProperties {
43    transform2d:      Option<Box<Transform2D>>,
44    preset_geometry:  PresetGeometry,
45    blip_fill:        Option<Box<BlipFill>>,
46    solid_fill:       Option<Box<SolidFill>>,
47    gradient_fill:    Option<Box<GradientFill>>,
48    outline:          Option<Box<Outline>>,
49    effect_list:      Option<Box<EffectList>>,
50    no_fill:          Option<NoFill>,
51    extension_list:   Option<ExtensionList>,
52    black_white_mode: EnumValue<BlackWhiteModeValues>,
53}
54impl ShapeProperties {
55    #[inline]
56    #[must_use]
57    pub fn transform2d(&self) -> Option<&Transform2D> {
58        self.transform2d.as_deref()
59    }
60
61    #[inline]
62    #[must_use]
63    #[deprecated(since = "3.0.0", note = "Use transform2d()")]
64    pub fn get_transform2d(&self) -> Option<&Transform2D> {
65        self.transform2d()
66    }
67
68    #[inline]
69    pub fn transform2d_mut(&mut self) -> Option<&mut Transform2D> {
70        self.transform2d.as_deref_mut()
71    }
72
73    #[inline]
74    #[deprecated(since = "3.0.0", note = "Use transform2d_mut()")]
75    pub fn get_transform2d_mut(&mut self) -> Option<&mut Transform2D> {
76        self.transform2d_mut()
77    }
78
79    #[inline]
80    pub fn set_transform2d(&mut self, value: Transform2D) -> &mut Self {
81        self.transform2d = Some(Box::new(value));
82        self
83    }
84
85    #[inline]
86    #[must_use]
87    pub fn geometry(&self) -> &PresetGeometry {
88        &self.preset_geometry
89    }
90
91    #[inline]
92    #[must_use]
93    #[deprecated(since = "3.0.0", note = "Use geometry()")]
94    pub fn get_geometry(&self) -> &PresetGeometry {
95        self.geometry()
96    }
97
98    #[inline]
99    pub fn geometry_mut(&mut self) -> &mut PresetGeometry {
100        &mut self.preset_geometry
101    }
102
103    #[inline]
104    #[deprecated(since = "3.0.0", note = "Use geometry_mut()")]
105    pub fn get_geometry_mut(&mut self) -> &mut PresetGeometry {
106        self.geometry_mut()
107    }
108
109    #[inline]
110    pub fn set_geometry(&mut self, value: PresetGeometry) -> &mut Self {
111        self.preset_geometry = value;
112        self
113    }
114
115    #[inline]
116    #[must_use]
117    pub fn blip_fill(&self) -> Option<&BlipFill> {
118        self.blip_fill.as_deref()
119    }
120
121    #[inline]
122    #[must_use]
123    #[deprecated(since = "3.0.0", note = "Use blip_fill()")]
124    pub fn get_blip_fill(&self) -> Option<&BlipFill> {
125        self.blip_fill()
126    }
127
128    #[inline]
129    pub fn blip_fill_mut(&mut self) -> Option<&mut BlipFill> {
130        self.blip_fill.as_deref_mut()
131    }
132
133    #[inline]
134    #[deprecated(since = "3.0.0", note = "Use blip_fill_mut()")]
135    pub fn get_blip_fill_mut(&mut self) -> Option<&mut BlipFill> {
136        self.blip_fill_mut()
137    }
138
139    #[inline]
140    pub fn set_blip_fill(&mut self, value: BlipFill) -> &mut Self {
141        self.blip_fill = Some(Box::new(value));
142        self
143    }
144
145    #[inline]
146    #[must_use]
147    pub fn solid_fill(&self) -> Option<&SolidFill> {
148        self.solid_fill.as_deref()
149    }
150
151    #[inline]
152    #[must_use]
153    #[deprecated(since = "3.0.0", note = "Use solid_fill()")]
154    pub fn get_solid_fill(&self) -> Option<&SolidFill> {
155        self.solid_fill()
156    }
157
158    #[inline]
159    pub fn solid_fill_mut(&mut self) -> Option<&mut SolidFill> {
160        self.solid_fill.as_deref_mut()
161    }
162
163    #[inline]
164    #[deprecated(since = "3.0.0", note = "Use solid_fill_mut()")]
165    pub fn get_solid_fill_mut(&mut self) -> Option<&mut SolidFill> {
166        self.solid_fill_mut()
167    }
168
169    #[inline]
170    pub fn set_solid_fill(&mut self, value: SolidFill) -> &mut Self {
171        self.solid_fill = Some(Box::new(value));
172        self
173    }
174
175    #[inline]
176    #[must_use]
177    pub fn gradient_fill(&self) -> Option<&GradientFill> {
178        self.gradient_fill.as_deref()
179    }
180
181    #[inline]
182    #[must_use]
183    #[deprecated(since = "3.0.0", note = "Use gradient_fill()")]
184    pub fn get_gradient_fill(&self) -> Option<&GradientFill> {
185        self.gradient_fill()
186    }
187
188    #[inline]
189    pub fn gradient_fill_mut(&mut self) -> Option<&mut GradientFill> {
190        self.gradient_fill.as_deref_mut()
191    }
192
193    #[inline]
194    #[deprecated(since = "3.0.0", note = "Use gradient_fill_mut()")]
195    pub fn get_gradient_fill_mut(&mut self) -> Option<&mut GradientFill> {
196        self.gradient_fill_mut()
197    }
198
199    #[inline]
200    pub fn set_gradient_fill(&mut self, value: GradientFill) -> &mut Self {
201        self.gradient_fill = Some(Box::new(value));
202        self
203    }
204
205    #[inline]
206    #[must_use]
207    pub fn outline(&self) -> Option<&Outline> {
208        self.outline.as_deref()
209    }
210
211    #[inline]
212    #[must_use]
213    #[deprecated(since = "3.0.0", note = "Use outline()")]
214    pub fn get_outline(&self) -> Option<&Outline> {
215        self.outline()
216    }
217
218    #[inline]
219    pub fn outline_mut(&mut self) -> Option<&mut Outline> {
220        self.outline.as_deref_mut()
221    }
222
223    #[inline]
224    #[deprecated(since = "3.0.0", note = "Use outline_mut()")]
225    pub fn get_outline_mut(&mut self) -> Option<&mut Outline> {
226        self.outline_mut()
227    }
228
229    #[inline]
230    pub fn set_outline(&mut self, value: Outline) -> &mut Self {
231        self.outline = Some(Box::new(value));
232        self
233    }
234
235    #[inline]
236    #[must_use]
237    pub fn effect_list(&self) -> Option<&EffectList> {
238        self.effect_list.as_deref()
239    }
240
241    #[inline]
242    #[must_use]
243    #[deprecated(since = "3.0.0", note = "Use effect_list()")]
244    pub fn get_effect_list(&self) -> Option<&EffectList> {
245        self.effect_list()
246    }
247
248    #[inline]
249    pub fn effect_list_mut(&mut self) -> Option<&mut EffectList> {
250        self.effect_list.as_deref_mut()
251    }
252
253    #[inline]
254    #[deprecated(since = "3.0.0", note = "Use effect_list_mut()")]
255    pub fn get_effect_list_mut(&mut self) -> Option<&mut EffectList> {
256        self.effect_list_mut()
257    }
258
259    #[inline]
260    pub fn set_effect_list(&mut self, value: EffectList) -> &mut Self {
261        self.effect_list = Some(Box::new(value));
262        self
263    }
264
265    #[inline]
266    #[must_use]
267    pub fn no_fill(&self) -> Option<&NoFill> {
268        self.no_fill.as_ref()
269    }
270
271    #[inline]
272    #[must_use]
273    #[deprecated(since = "3.0.0", note = "Use no_fill()")]
274    pub fn get_no_fill(&self) -> Option<&NoFill> {
275        self.no_fill()
276    }
277
278    #[inline]
279    pub fn no_fill_mut(&mut self) -> Option<&mut NoFill> {
280        self.no_fill.as_mut()
281    }
282
283    #[inline]
284    #[deprecated(since = "3.0.0", note = "Use no_fill_mut()")]
285    pub fn get_no_fill_mut(&mut self) -> Option<&mut NoFill> {
286        self.no_fill_mut()
287    }
288
289    #[inline]
290    pub fn set_no_fill(&mut self, value: NoFill) -> &mut Self {
291        self.no_fill = Some(value);
292        self
293    }
294
295    #[inline]
296    #[must_use]
297    pub fn extension_list(&self) -> Option<&ExtensionList> {
298        self.extension_list.as_ref()
299    }
300
301    #[inline]
302    #[must_use]
303    #[deprecated(since = "3.0.0", note = "Use extension_list()")]
304    pub fn get_extension_list(&self) -> Option<&ExtensionList> {
305        self.extension_list()
306    }
307
308    #[inline]
309    pub fn extension_list_mut(&mut self) -> Option<&mut ExtensionList> {
310        self.extension_list.as_mut()
311    }
312
313    #[inline]
314    #[deprecated(since = "3.0.0", note = "Use extension_list_mut()")]
315    pub fn get_extension_list_mut(&mut self) -> Option<&mut ExtensionList> {
316        self.extension_list_mut()
317    }
318
319    #[inline]
320    pub fn set_extension_list(&mut self, value: ExtensionList) -> &mut Self {
321        self.extension_list = Some(value);
322        self
323    }
324
325    #[inline]
326    #[must_use]
327    pub fn black_white_mode(&self) -> &BlackWhiteModeValues {
328        self.black_white_mode.value()
329    }
330
331    #[inline]
332    #[must_use]
333    #[deprecated(since = "3.0.0", note = "Use black_white_mode()")]
334    pub fn get_black_white_mode(&self) -> &BlackWhiteModeValues {
335        self.black_white_mode()
336    }
337
338    #[inline]
339    pub fn set_black_white_mode(&mut self, value: BlackWhiteModeValues) -> &mut Self {
340        self.black_white_mode.set_value(value);
341        self
342    }
343
344    pub(crate) fn set_attributes<R: std::io::BufRead>(
345        &mut self,
346        reader: &mut Reader<R>,
347        e: &BytesStart,
348        drawing_relationships: Option<&RawRelationships>,
349    ) {
350        set_string_from_xml!(self, e, black_white_mode, "bwMode");
351
352        xml_read_loop!(
353            reader,
354            Event::Start(ref e) => {
355                match e.name().into_inner() {
356                    b"a:xfrm" => {
357                        let mut obj = Transform2D::default();
358                        obj.set_attributes(reader, e);
359                        self.set_transform2d(obj);
360                    }
361                    b"a:prstGeom" => {
362                        self.preset_geometry.set_attributes(reader, e);
363                    }
364                    b"a:blipFill" => {
365                        let mut obj = BlipFill::default();
366                        obj.set_attributes(reader, e, drawing_relationships);
367                        self.set_blip_fill(obj);
368                    }
369                    b"a:gradFill" => {
370                        let mut obj = GradientFill::default();
371                        obj.set_attributes(reader, e);
372                        self.set_gradient_fill(obj);
373                    }
374                    b"a:ln" => {
375                        let mut outline = Outline::default();
376                        outline.set_attributes(reader, e);
377                        self.set_outline(outline);
378                    }
379                    b"a:solidFill" => {
380                        let mut solid_fill = SolidFill::default();
381                        solid_fill.set_attributes(reader, e);
382                        self.set_solid_fill(solid_fill);
383                    }
384                    b"a:effectLst" => {
385                        let mut effect_list = EffectList::default();
386                        effect_list.set_attributes(reader, e, false);
387                        self.set_effect_list(effect_list);
388                    }
389                    b"a:extLst" => {
390                        let obj = ExtensionList::default();
391                        ExtensionList::set_attributes(reader, e);
392                        self.set_extension_list(obj);
393                    }
394                    _ => (),
395                }
396            },
397            Event::Empty(ref e) => {
398                if e.name().into_inner() == b"a:noFill" {
399                    let obj = NoFill::default();
400                    NoFill::set_attributes(reader, e, true);
401                    self.set_no_fill(obj);
402                }
403            },
404            Event::End(ref e) => {
405                if matches!(e.name().into_inner(), b"xdr:spPr" | b"spPr") {
406                    return;
407                }
408            },
409            Event::Eof => panic!("Error: Could not find {} end element", "spPr")
410        );
411    }
412
413    pub(crate) fn write_to(
414        &self,
415        writer: &mut Writer<Cursor<Vec<u8>>>,
416        rel_list: &mut Vec<(String, String)>,
417    ) {
418        // xdr:spPr
419        let mut attributes: crate::structs::AttrCollection = Vec::new();
420        if self.black_white_mode.has_value() {
421            attributes.push(("bwMode", self.black_white_mode.hash_string()).into());
422        }
423        write_start_tag(writer, "xdr:spPr", attributes, false);
424
425        // a:xfrm
426        if let Some(v) = &self.transform2d {
427            v.write_to(writer);
428        }
429
430        // a:prstGeom
431        self.preset_geometry.write_to(writer);
432
433        // a:blipFill
434        if let Some(v) = &self.blip_fill {
435            v.write_to(writer, rel_list);
436        }
437
438        // a:solidFill
439        if let Some(v) = &self.solid_fill {
440            v.write_to(writer);
441        }
442
443        // a:noFill
444        if self.no_fill.is_some() {
445            NoFill::write_to(writer);
446        }
447
448        // a:ln
449        if let Some(v) = &self.outline {
450            v.write_to(writer);
451        }
452
453        // a:effectLst
454        if let Some(v) = &self.effect_list {
455            v.write_to(writer);
456        }
457
458        write_end_tag(writer, "xdr:spPr");
459    }
460}