umya_spreadsheet/structs/drawing/spreadsheet/
worksheet_drawing.rs

1// xdr:wsDr
2use super::ConnectionShape;
3use super::GraphicFrame;
4use super::OneCellAnchor;
5use super::Picture;
6use super::Shape;
7use super::TwoCellAnchor;
8use crate::helper::const_str::*;
9use crate::reader::driver::*;
10use crate::structs::raw::RawRelationships;
11use crate::structs::Chart;
12use crate::structs::Image;
13use crate::structs::OleObjects;
14use crate::traits::AdjustmentCoordinate;
15use crate::traits::AdjustmentCoordinateWithSheet;
16use crate::writer::driver::*;
17use quick_xml::events::{BytesStart, Event};
18use quick_xml::Reader;
19use quick_xml::Writer;
20use std::io::Cursor;
21use thin_vec::ThinVec;
22
23#[derive(Clone, Default, Debug)]
24pub struct WorksheetDrawing {
25    image_collection: ThinVec<Image>,
26    chart_collection: ThinVec<Chart>,
27    one_cell_anchor_collection: ThinVec<OneCellAnchor>,
28    two_cell_anchor_collection: ThinVec<TwoCellAnchor>,
29}
30
31impl WorksheetDrawing {
32    #[inline]
33    pub fn get_image_collection(&self) -> &[Image] {
34        &self.image_collection
35    }
36
37    #[inline]
38    pub fn get_image_collection_mut(&mut self) -> &mut ThinVec<Image> {
39        &mut self.image_collection
40    }
41
42    #[inline]
43    pub fn add_image(&mut self, value: Image) -> &mut Self {
44        self.image_collection.push(value);
45        self
46    }
47
48    #[inline]
49    pub fn get_image(&self, col: &u32, row: &u32) -> Option<&Image> {
50        self.image_collection
51            .iter()
52            .find(|&image| image.get_col() == &(col - 1) && image.get_row() == &(row - 1))
53    }
54
55    #[inline]
56    pub fn get_image_mut(&mut self, col: &u32, row: &u32) -> Option<&mut Image> {
57        self.image_collection
58            .iter_mut()
59            .find(|image| image.get_col() == &(col - 1) && image.get_row() == &(row - 1))
60    }
61
62    pub fn get_images(&self, col: &u32, row: &u32) -> Vec<&Image> {
63        self.image_collection
64            .iter()
65            .filter(|image| image.get_col() == &(col - 1) && image.get_row() == &(row - 1))
66            .collect()
67    }
68
69    pub fn get_images_mut(&mut self, col: &u32, row: &u32) -> Vec<&mut Image> {
70        self.image_collection
71            .iter_mut()
72            .filter(|image| image.get_col() == &(col - 1) && image.get_row() == &(row - 1))
73            .collect()
74    }
75
76    #[inline]
77    pub fn get_chart_collection(&self) -> &[Chart] {
78        &self.chart_collection
79    }
80
81    #[inline]
82    pub fn get_chart_collection_mut(&mut self) -> &mut ThinVec<Chart> {
83        &mut self.chart_collection
84    }
85
86    #[inline]
87    pub fn add_chart_collection(&mut self, value: Chart) -> &mut Self {
88        self.chart_collection.push(value);
89        self
90    }
91
92    #[inline]
93    pub fn get_chart(&self, col: &u32, row: &u32) -> Option<&Chart> {
94        self.chart_collection
95            .iter()
96            .find(|&chart| chart.get_col() == &(col - 1) && chart.get_row() == &(row - 1))
97    }
98
99    #[inline]
100    pub fn get_chart_mut(&mut self, col: &u32, row: &u32) -> Option<&mut Chart> {
101        self.chart_collection
102            .iter_mut()
103            .find(|chart| chart.get_col() == &(col - 1) && chart.get_row() == &(row - 1))
104    }
105
106    pub fn get_charts(&self, col: &u32, row: &u32) -> Vec<&Chart> {
107        self.chart_collection
108            .iter()
109            .filter(|chart| chart.get_col() == &(col - 1) && chart.get_row() == &(row - 1))
110            .collect()
111    }
112
113    pub fn get_charts_mut(&mut self, col: &u32, row: &u32) -> Vec<&mut Chart> {
114        self.chart_collection
115            .iter_mut()
116            .filter(|chart| chart.get_col() == &(col - 1) && chart.get_row() == &(row - 1))
117            .collect()
118    }
119
120    #[inline]
121    pub fn get_one_cell_anchor_collection(&self) -> &[OneCellAnchor] {
122        &self.one_cell_anchor_collection
123    }
124
125    #[inline]
126    pub fn get_one_cell_anchor_collection_mut(&mut self) -> &mut ThinVec<OneCellAnchor> {
127        &mut self.one_cell_anchor_collection
128    }
129
130    #[inline]
131    pub fn add_one_cell_anchor_collection(&mut self, value: OneCellAnchor) -> &mut Self {
132        self.one_cell_anchor_collection.push(value);
133        self
134    }
135
136    #[inline]
137    pub fn get_two_cell_anchor_collection(&self) -> &[TwoCellAnchor] {
138        &self.two_cell_anchor_collection
139    }
140
141    #[inline]
142    pub fn get_two_cell_anchor_collection_mut(&mut self) -> &mut ThinVec<TwoCellAnchor> {
143        &mut self.two_cell_anchor_collection
144    }
145
146    #[inline]
147    pub fn add_two_cell_anchor_collection(&mut self, value: TwoCellAnchor) -> &mut Self {
148        self.two_cell_anchor_collection.push(value);
149        self
150    }
151
152    #[inline]
153    pub fn has_drawing_object(&self) -> bool {
154        !self.chart_collection.is_empty()
155            || !self.image_collection.is_empty()
156            || !self.one_cell_anchor_collection.is_empty()
157            || !self.two_cell_anchor_collection.is_empty()
158    }
159
160    pub fn get_graphic_frame_collection(&self) -> Vec<&GraphicFrame> {
161        self.two_cell_anchor_collection
162            .iter()
163            .filter_map(|two_cell_anchor| two_cell_anchor.get_graphic_frame())
164            .collect()
165    }
166
167    pub fn get_graphic_frame_collection_mut(&mut self) -> Vec<&mut GraphicFrame> {
168        self.two_cell_anchor_collection
169            .iter_mut()
170            .filter_map(|two_cell_anchor| two_cell_anchor.get_graphic_frame_mut())
171            .collect()
172    }
173
174    pub fn get_shape_collection(&self) -> Vec<&Shape> {
175        self.two_cell_anchor_collection
176            .iter()
177            .filter_map(|two_cell_anchor| two_cell_anchor.get_shape())
178            .collect()
179    }
180
181    pub fn get_shape_collection_mut(&mut self) -> Vec<&mut Shape> {
182        self.two_cell_anchor_collection
183            .iter_mut()
184            .filter_map(|two_cell_anchor| two_cell_anchor.get_shape_mut())
185            .collect()
186    }
187
188    pub fn get_connection_shape_collection(&self) -> Vec<&ConnectionShape> {
189        self.two_cell_anchor_collection
190            .iter()
191            .filter_map(|two_cell_anchor| two_cell_anchor.get_connection_shape())
192            .collect()
193    }
194
195    pub fn get_connection_shape_collection_mut(&mut self) -> Vec<&mut ConnectionShape> {
196        self.two_cell_anchor_collection
197            .iter_mut()
198            .filter_map(|two_cell_anchor| two_cell_anchor.get_connection_shape_mut())
199            .collect()
200    }
201
202    pub fn get_picture_collection(&self) -> Vec<&Picture> {
203        self.two_cell_anchor_collection
204            .iter()
205            .filter_map(|two_cell_anchor| two_cell_anchor.get_picture())
206            .collect()
207    }
208
209    pub fn get_one_cell_anchor_all_list(&mut self) -> Vec<&mut OneCellAnchor> {
210        self.one_cell_anchor_collection
211            .iter_mut()
212            .chain(
213                self.image_collection
214                    .iter_mut()
215                    .filter_map(|image| image.get_one_cell_anchor_mut()),
216            )
217            .collect()
218    }
219
220    pub fn get_two_cell_anchor_all_list(&mut self) -> Vec<&mut TwoCellAnchor> {
221        self.two_cell_anchor_collection
222            .iter_mut()
223            .chain(
224                self.chart_collection
225                    .iter_mut()
226                    .map(|chart| chart.get_two_cell_anchor_mut()),
227            )
228            .chain(
229                self.image_collection
230                    .iter_mut()
231                    .filter_map(|image| image.get_two_cell_anchor_mut()),
232            )
233            .collect()
234    }
235
236    pub fn get_picture_collection_mut(&mut self) -> Vec<&mut Picture> {
237        self.two_cell_anchor_collection
238            .iter_mut()
239            .filter_map(|two_cell_anchor| two_cell_anchor.get_picture_mut())
240            .collect()
241    }
242
243    pub(crate) fn set_attributes<R: std::io::BufRead>(
244        &mut self,
245        reader: &mut Reader<R>,
246        _e: &BytesStart,
247        drawing_relationships: Option<&RawRelationships>,
248        ole_objects: &mut OleObjects,
249    ) {
250        let mut ole_index = 0;
251        let mut is_alternate_content = false;
252
253        xml_read_loop!(
254            reader,
255            Event::Start(ref e) => {
256                match e.name().into_inner() {
257                    b"mc:AlternateContent" => {
258                        is_alternate_content = true;
259                    }
260                    b"xdr:oneCellAnchor" => {
261                        if is_alternate_content {
262                            continue;
263                        }
264                        let mut obj = OneCellAnchor::default();
265                        obj.set_attributes(reader, e, drawing_relationships);
266                        if obj.is_image() {
267                            let mut image = Image::default();
268                            image.set_one_cell_anchor(obj);
269                            self.add_image(image);
270                        } else {
271                            self.add_one_cell_anchor_collection(obj);
272                        }
273                    }
274                    b"xdr:twoCellAnchor" => {
275                        let os = ole_objects.get_ole_object_mut();
276                        if is_alternate_content && !os.is_empty() {
277                            os[ole_index]
278                                .get_two_cell_anchor_mut()
279                                .set_is_alternate_content(true);
280                            os[ole_index].get_two_cell_anchor_mut().set_attributes(
281                                reader,
282                                e,
283                                drawing_relationships,
284                            );
285                            ole_index += 1;
286                            continue;
287                        }
288                        let mut obj = TwoCellAnchor::default();
289                        obj.set_attributes(reader, e, drawing_relationships);
290                        if obj.is_support() {
291                            if obj.is_chart() {
292                                let mut chart = Chart::default();
293                                chart.set_two_cell_anchor(obj);
294                                self.add_chart_collection(chart);
295                            } else if obj.is_image() {
296                                let mut image = Image::default();
297                                image.set_two_cell_anchor(obj);
298                                self.add_image(image);
299                            } else {
300                                self.add_two_cell_anchor_collection(obj);
301                            }
302                        }
303                    }
304                    _ => (),
305                }
306            },
307
308            Event::End(ref e) => {
309                match e.name().into_inner() {
310                    b"mc:AlternateContent" => {
311                        is_alternate_content = false;
312                    }
313                    b"xdr:wsDr" => return,
314                    _ => (),
315                }
316            },
317
318            Event::Eof => panic!("Error: Could not find {} end element", "xdr:wsDr")
319        );
320    }
321
322    pub(crate) fn write_to(
323        &self,
324        writer: &mut Writer<Cursor<Vec<u8>>>,
325        ole_objects: &OleObjects,
326        rel_list: &mut Vec<(String, String)>,
327    ) {
328        // xdr:wsDr
329        write_start_tag(
330            writer,
331            "xdr:wsDr",
332            vec![
333                ("xmlns:xdr", SHEET_DRAWING_NS),
334                ("xmlns:a", DRAWINGML_MAIN_NS),
335            ],
336            false,
337        );
338
339        // xdr:twoCellAnchor
340        for chart in &self.chart_collection {
341            chart.get_two_cell_anchor().write_to(writer, rel_list, &0);
342        }
343        for image in &self.image_collection {
344            image.write_to(writer, rel_list);
345        }
346        for two_cell_anchor in &self.two_cell_anchor_collection {
347            two_cell_anchor.write_to(writer, rel_list, &0);
348        }
349
350        // xdr:oneCellAnchor
351        for one_cell_anchor in &self.one_cell_anchor_collection {
352            one_cell_anchor.write_to(writer, rel_list);
353        }
354
355        // mc:AlternateContent
356        let mut ole_id = 1000 + 25;
357        for ole_object in ole_objects.get_ole_object() {
358            ole_object
359                .get_two_cell_anchor()
360                .write_to(writer, rel_list, &0);
361            ole_id += 1;
362        }
363
364        write_end_tag(writer, "xdr:wsDr");
365    }
366}
367impl AdjustmentCoordinate for WorksheetDrawing {
368    fn adjustment_insert_coordinate(
369        &mut self,
370        root_col_num: &u32,
371        offset_col_num: &u32,
372        root_row_num: &u32,
373        offset_row_num: &u32,
374    ) {
375        for anchor in &mut self.one_cell_anchor_collection {
376            anchor.adjustment_insert_coordinate(
377                root_col_num,
378                offset_col_num,
379                root_row_num,
380                offset_row_num,
381            );
382        }
383        for anchor in &mut self.two_cell_anchor_collection {
384            anchor.adjustment_insert_coordinate(
385                root_col_num,
386                offset_col_num,
387                root_row_num,
388                offset_row_num,
389            );
390        }
391        for chart in &mut self.chart_collection {
392            chart.adjustment_insert_coordinate(
393                root_col_num,
394                offset_col_num,
395                root_row_num,
396                offset_row_num,
397            );
398        }
399        for image in &mut self.image_collection {
400            image.adjustment_insert_coordinate(
401                root_col_num,
402                offset_col_num,
403                root_row_num,
404                offset_row_num,
405            );
406        }
407    }
408
409    fn adjustment_remove_coordinate(
410        &mut self,
411        root_col_num: &u32,
412        offset_col_num: &u32,
413        root_row_num: &u32,
414        offset_row_num: &u32,
415    ) {
416        &mut self.one_cell_anchor_collection.retain(|k| {
417            !(k.is_remove_coordinate(root_col_num, offset_col_num, root_row_num, offset_row_num))
418        });
419        for anchor in &mut self.one_cell_anchor_collection {
420            anchor.adjustment_remove_coordinate(
421                root_col_num,
422                offset_col_num,
423                root_row_num,
424                offset_row_num,
425            );
426        }
427        &mut self.two_cell_anchor_collection.retain(|k| {
428            !(k.is_remove_coordinate(root_col_num, offset_col_num, root_row_num, offset_row_num))
429        });
430        for anchor in &mut self.two_cell_anchor_collection {
431            anchor.adjustment_remove_coordinate(
432                root_col_num,
433                offset_col_num,
434                root_row_num,
435                offset_row_num,
436            );
437        }
438        &mut self.chart_collection.retain(|k| {
439            !(k.is_remove_coordinate(root_col_num, offset_col_num, root_row_num, offset_row_num))
440        });
441        for chart in &mut self.chart_collection {
442            chart.adjustment_remove_coordinate(
443                root_col_num,
444                offset_col_num,
445                root_row_num,
446                offset_row_num,
447            );
448        }
449        &mut self.image_collection.retain(|k| {
450            !(k.is_remove_coordinate(root_col_num, offset_col_num, root_row_num, offset_row_num))
451        });
452        for image in &mut self.image_collection {
453            image.adjustment_remove_coordinate(
454                root_col_num,
455                offset_col_num,
456                root_row_num,
457                offset_row_num,
458            );
459        }
460    }
461}
462impl AdjustmentCoordinateWithSheet for WorksheetDrawing {
463    fn adjustment_insert_coordinate_with_sheet(
464        &mut self,
465        sheet_name: &str,
466        root_col_num: &u32,
467        offset_col_num: &u32,
468        root_row_num: &u32,
469        offset_row_num: &u32,
470    ) {
471        // chart
472        for chart in &mut self.chart_collection {
473            chart.adjustment_insert_coordinate_with_sheet(
474                sheet_name,
475                root_col_num,
476                offset_col_num,
477                root_row_num,
478                offset_row_num,
479            );
480        }
481    }
482
483    fn adjustment_remove_coordinate_with_sheet(
484        &mut self,
485        sheet_name: &str,
486        root_col_num: &u32,
487        offset_col_num: &u32,
488        root_row_num: &u32,
489        offset_row_num: &u32,
490    ) {
491        // chart
492        for chart in &mut self.chart_collection {
493            chart.adjustment_remove_coordinate_with_sheet(
494                sheet_name,
495                root_col_num,
496                offset_col_num,
497                root_row_num,
498                offset_row_num,
499            );
500        }
501    }
502}