umya_spreadsheet/structs/drawing/spreadsheet/
worksheet_drawing.rs1use 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 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 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 for one_cell_anchor in &self.one_cell_anchor_collection {
352 one_cell_anchor.write_to(writer, rel_list);
353 }
354
355 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 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 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}