1use std::io::Cursor;
3
4use quick_xml::{
5 Reader,
6 Writer,
7 events::{
8 BytesStart,
9 Event,
10 },
11};
12
13use super::{
14 super::super::EnumValue,
15 ConnectionShape,
16 EditAsValues,
17 GraphicFrame,
18 GroupShape,
19 MarkerType,
20 Picture,
21 Shape,
22};
23use crate::{
24 helper::const_str::{
25 DRAWING_MAIN_NS,
26 MC_NS,
27 },
28 reader::driver::{
29 get_attribute,
30 set_string_from_xml,
31 xml_read_loop,
32 },
33 structs::{
34 BooleanValue,
35 raw::RawRelationships,
36 },
37 traits::{
38 AdjustmentCoordinate,
39 AdjustmentCoordinateWithSheet,
40 },
41 writer::driver::{
42 write_end_tag,
43 write_start_tag,
44 },
45};
46
47#[derive(Clone, Default, Debug)]
48pub struct TwoCellAnchor {
49 edit_as: EnumValue<EditAsValues>,
50 from_marker: MarkerType,
51 to_marker: MarkerType,
52 group_shape: Option<Box<GroupShape>>,
53 graphic_frame: Option<Box<GraphicFrame>>,
54 shape: Option<Box<Shape>>,
55 connection_shape: Option<Box<ConnectionShape>>,
56 picture: Option<Box<Picture>>,
57 is_alternate_content: BooleanValue,
58}
59
60impl TwoCellAnchor {
61 #[inline]
62 #[must_use]
63 pub fn edit_as(&self) -> &EditAsValues {
64 self.edit_as.value()
65 }
66
67 #[inline]
68 #[must_use]
69 #[deprecated(since = "3.0.0", note = "Use edit_as()")]
70 pub fn get_edit_as(&self) -> &EditAsValues {
71 self.edit_as()
72 }
73
74 #[inline]
75 pub fn set_edit_as(&mut self, value: EditAsValues) -> &mut Self {
76 self.edit_as.set_value(value);
77 self
78 }
79
80 #[inline]
81 #[must_use]
82 pub fn from_marker(&self) -> &MarkerType {
83 &self.from_marker
84 }
85
86 #[inline]
87 #[must_use]
88 #[deprecated(since = "3.0.0", note = "Use from_marker()")]
89 pub fn get_from_marker(&self) -> &MarkerType {
90 self.from_marker()
91 }
92
93 #[inline]
94 pub fn from_marker_mut(&mut self) -> &mut MarkerType {
95 &mut self.from_marker
96 }
97
98 #[inline]
99 #[deprecated(since = "3.0.0", note = "Use from_marker_mut()")]
100 pub fn get_from_marker_mut(&mut self) -> &mut MarkerType {
101 self.from_marker_mut()
102 }
103
104 #[inline]
105 pub fn set_from_marker(&mut self, value: MarkerType) -> &mut Self {
106 self.from_marker = value;
107 self
108 }
109
110 #[inline]
111 #[must_use]
112 pub fn to_marker(&self) -> &MarkerType {
113 &self.to_marker
114 }
115
116 #[inline]
117 #[must_use]
118 #[deprecated(since = "3.0.0", note = "Use to_marker()")]
119 pub fn get_to_marker(&self) -> &MarkerType {
120 self.to_marker()
121 }
122
123 #[inline]
124 pub fn to_marker_mut(&mut self) -> &mut MarkerType {
125 &mut self.to_marker
126 }
127
128 #[inline]
129 #[deprecated(since = "3.0.0", note = "Use to_marker_mut()")]
130 pub fn get_to_marker_mut(&mut self) -> &mut MarkerType {
131 self.to_marker_mut()
132 }
133
134 #[inline]
135 pub fn set_to_marker(&mut self, value: MarkerType) -> &mut Self {
136 self.to_marker = value;
137 self
138 }
139
140 #[inline]
141 #[must_use]
142 pub fn group_shape(&self) -> Option<&GroupShape> {
143 self.group_shape.as_deref()
144 }
145
146 #[inline]
147 #[must_use]
148 #[deprecated(since = "3.0.0", note = "Use group_shape()")]
149 pub fn get_group_shape(&self) -> Option<&GroupShape> {
150 self.group_shape()
151 }
152
153 #[inline]
154 pub fn group_shape_mut(&mut self) -> Option<&mut GroupShape> {
155 self.group_shape.as_deref_mut()
156 }
157
158 #[inline]
159 #[deprecated(since = "3.0.0", note = "Use group_shape_mut()")]
160 pub fn get_group_shape_mut(&mut self) -> Option<&mut GroupShape> {
161 self.group_shape_mut()
162 }
163
164 #[inline]
165 pub fn set_group_shape(&mut self, value: GroupShape) -> &mut Self {
166 self.group_shape = Some(Box::new(value));
167 self
168 }
169
170 #[inline]
171 #[must_use]
172 pub fn graphic_frame(&self) -> Option<&GraphicFrame> {
173 self.graphic_frame.as_deref()
174 }
175
176 #[inline]
177 #[must_use]
178 #[deprecated(since = "3.0.0", note = "Use graphic_frame()")]
179 pub fn get_graphic_frame(&self) -> Option<&GraphicFrame> {
180 self.graphic_frame()
181 }
182
183 #[inline]
184 pub fn graphic_frame_mut(&mut self) -> Option<&mut GraphicFrame> {
185 self.graphic_frame.as_deref_mut()
186 }
187
188 #[inline]
189 #[deprecated(since = "3.0.0", note = "Use graphic_frame_mut()")]
190 pub fn get_graphic_frame_mut(&mut self) -> Option<&mut GraphicFrame> {
191 self.graphic_frame_mut()
192 }
193
194 #[inline]
195 pub fn set_graphic_frame(&mut self, value: GraphicFrame) -> &mut Self {
196 self.graphic_frame = Some(Box::new(value));
197 self
198 }
199
200 #[inline]
201 #[must_use]
202 pub fn shape(&self) -> Option<&Shape> {
203 self.shape.as_deref()
204 }
205
206 #[inline]
207 #[must_use]
208 #[deprecated(since = "3.0.0", note = "Use shape()")]
209 pub fn get_shape(&self) -> Option<&Shape> {
210 self.shape()
211 }
212
213 #[inline]
214 pub fn shape_mut(&mut self) -> Option<&mut Shape> {
215 self.shape.as_deref_mut()
216 }
217
218 #[inline]
219 #[deprecated(since = "3.0.0", note = "Use shape_mut()")]
220 pub fn get_shape_mut(&mut self) -> Option<&mut Shape> {
221 self.shape_mut()
222 }
223
224 #[inline]
225 pub fn set_shape(&mut self, value: Shape) -> &mut Self {
226 self.shape = Some(Box::new(value));
227 self
228 }
229
230 #[inline]
231 #[must_use]
232 pub fn connection_shape(&self) -> Option<&ConnectionShape> {
233 self.connection_shape.as_deref()
234 }
235
236 #[inline]
237 #[must_use]
238 #[deprecated(since = "3.0.0", note = "Use connection_shape()")]
239 pub fn get_connection_shape(&self) -> Option<&ConnectionShape> {
240 self.connection_shape()
241 }
242
243 #[inline]
244 pub fn connection_shape_mut(&mut self) -> Option<&mut ConnectionShape> {
245 self.connection_shape.as_deref_mut()
246 }
247
248 #[inline]
249 #[deprecated(since = "3.0.0", note = "Use connection_shape_mut()")]
250 pub fn get_connection_shape_mut(&mut self) -> Option<&mut ConnectionShape> {
251 self.connection_shape_mut()
252 }
253
254 #[inline]
255 pub fn set_connection_shape(&mut self, value: ConnectionShape) -> &mut Self {
256 self.connection_shape = Some(Box::new(value));
257 self
258 }
259
260 #[inline]
261 #[must_use]
262 pub fn picture(&self) -> Option<&Picture> {
263 self.picture.as_deref()
264 }
265
266 #[inline]
267 #[must_use]
268 #[deprecated(since = "3.0.0", note = "Use picture()")]
269 pub fn get_picture(&self) -> Option<&Picture> {
270 self.picture()
271 }
272
273 #[inline]
274 pub fn picture_mut(&mut self) -> Option<&mut Picture> {
275 self.picture.as_deref_mut()
276 }
277
278 #[inline]
279 #[deprecated(since = "3.0.0", note = "Use picture_mut()")]
280 pub fn get_picture_mut(&mut self) -> Option<&mut Picture> {
281 self.picture_mut()
282 }
283
284 #[inline]
285 pub fn set_picture(&mut self, value: Picture) -> &mut Self {
286 self.picture = Some(Box::new(value));
287 self
288 }
289
290 #[inline]
291 #[must_use]
292 pub fn is_alternate_content(&self) -> bool {
293 self.is_alternate_content.value()
294 }
295
296 #[inline]
297 #[must_use]
298 #[deprecated(since = "3.0.0", note = "Use is_alternate_content()")]
299 pub fn get_is_alternate_content(&self) -> bool {
300 self.is_alternate_content()
301 }
302
303 #[inline]
304 pub fn set_is_alternate_content(&mut self, value: bool) -> &mut Self {
305 self.is_alternate_content.set_value(value);
306 self
307 }
308
309 #[inline]
310 pub(crate) fn is_support(&self) -> bool {
311 match self.graphic_frame.as_ref() {
312 Some(v) => v
313 .graphic()
314 .graphic_data()
315 .chart_space()
316 .chart()
317 .plot_area()
318 .is_support(),
319 None => true,
320 }
321 }
322
323 #[inline]
324 pub(crate) fn is_chart(&self) -> bool {
325 self.graphic_frame.is_some()
326 }
327
328 #[inline]
329 pub(crate) fn is_image(&self) -> bool {
330 self.picture.is_some() || self.group_shape.is_some()
331 }
332
333 pub(crate) fn set_attributes<R: std::io::BufRead>(
334 &mut self,
335 reader: &mut Reader<R>,
336 e: &BytesStart,
337 drawing_relationships: Option<&RawRelationships>,
338 ) {
339 set_string_from_xml!(self, e, edit_as, "editAs");
340
341 xml_read_loop!(
342 reader,
343 Event::Start(ref e) => {
344 match e.name().into_inner() {
345 b"xdr:from" | b"from" => {
346 self.from_marker.set_attributes(reader, e);
347 }
348 b"xdr:to" | b"to" => {
349 self.to_marker.set_attributes(reader, e);
350 }
351 b"xdr:grpSp" | b"grpSp" => {
352 let mut obj = GroupShape::default();
353 obj.set_attributes(reader, e, drawing_relationships);
354 self.set_group_shape(obj);
355 }
356 b"xdr:graphicFrame" | b"graphicFrame" => {
357 let mut obj = GraphicFrame::default();
358 obj.set_attributes(reader, e, drawing_relationships);
359 self.set_graphic_frame(obj);
360 }
361 b"xdr:sp" | b"sp" => {
362 let mut obj = Shape::default();
363 obj.set_attributes(reader, e, drawing_relationships);
364 self.set_shape(obj);
365 }
366 b"xdr:cxnSp" | b"cxnSp" => {
367 let mut obj = ConnectionShape::default();
368 obj.set_attributes(reader, e, drawing_relationships);
369 self.set_connection_shape(obj);
370 }
371 b"xdr:pic" | b"pic" => {
372 let mut obj = Picture::default();
373 obj.set_attributes(reader, e, drawing_relationships);
374 self.set_picture(obj);
375 }
376 _ => (),
377 }
378 },
379 Event::End(ref e) => {
380 if matches!(e.name().into_inner(), b"xdr:twoCellAnchor" | b"twoCellAnchor") {
381 return
382 }
383 },
384 Event::Eof => panic!("Error: Could not find {} end element", "twoCellAnchor")
385 );
386 }
387
388 pub(crate) fn write_to(
389 &self,
390 writer: &mut Writer<Cursor<Vec<u8>>>,
391 rel_list: &mut Vec<(String, String)>,
392 ole_id: usize,
393 ) {
394 if self.is_alternate_content() {
395 write_start_tag(
397 writer,
398 "mc:AlternateContent",
399 vec![("xmlns:mc", MC_NS).into()],
400 false,
401 );
402
403 write_start_tag(
405 writer,
406 "mc:Choice",
407 vec![
408 ("xmlns:a14", DRAWING_MAIN_NS).into(),
409 ("Requires", "a14").into(),
410 ],
411 false,
412 );
413 }
414
415 let mut attributes: crate::structs::AttrCollection = Vec::new();
417 if self.edit_as.has_value() {
418 attributes.push(("editAs", self.edit_as.value_string()).into());
419 }
420 write_start_tag(writer, "xdr:twoCellAnchor", attributes, false);
421
422 self.from_marker.write_to_from(writer);
424
425 self.to_marker.write_to_to(writer);
427
428 if let Some(v) = &self.group_shape {
430 v.write_to(writer, rel_list);
431 }
432
433 if let Some(v) = &self.graphic_frame {
435 v.write_to(writer, rel_list);
436 }
437
438 if let Some(v) = &self.shape {
440 v.write_to(writer, rel_list, ole_id);
441 }
442
443 if let Some(v) = &self.connection_shape {
445 v.write_to(writer, rel_list);
446 }
447
448 if let Some(v) = &self.picture {
450 v.write_to(writer, rel_list);
451 }
452
453 write_start_tag(writer, "xdr:clientData", vec![], true);
455
456 write_end_tag(writer, "xdr:twoCellAnchor");
457
458 if self.is_alternate_content() {
459 write_end_tag(writer, "mc:Choice");
460
461 write_start_tag(writer, "mc:Fallback", vec![], true);
463
464 write_end_tag(writer, "mc:AlternateContent");
465 }
466 }
467}
468impl AdjustmentCoordinate for TwoCellAnchor {
469 #[inline]
470 fn adjustment_insert_coordinate(
471 &mut self,
472 root_col_num: u32,
473 offset_col_num: u32,
474 root_row_num: u32,
475 offset_row_num: u32,
476 ) {
477 self.from_marker.adjustment_insert_coordinate(
478 root_col_num,
479 offset_col_num,
480 root_row_num,
481 offset_row_num,
482 );
483 self.to_marker.adjustment_insert_coordinate(
484 root_col_num,
485 offset_col_num,
486 root_row_num,
487 offset_row_num,
488 );
489 }
490
491 #[inline]
492 fn adjustment_remove_coordinate(
493 &mut self,
494 root_col_num: u32,
495 offset_col_num: u32,
496 root_row_num: u32,
497 offset_row_num: u32,
498 ) {
499 self.from_marker.adjustment_remove_coordinate(
500 root_col_num,
501 offset_col_num,
502 root_row_num,
503 offset_row_num,
504 );
505 self.to_marker.adjustment_remove_coordinate(
506 root_col_num,
507 offset_col_num,
508 root_row_num,
509 offset_row_num,
510 );
511 }
512
513 #[inline]
514 fn is_remove_coordinate(
515 &self,
516 root_col_num: u32,
517 offset_col_num: u32,
518 root_row_num: u32,
519 offset_row_num: u32,
520 ) -> bool {
521 self.from_marker.is_remove_coordinate(
522 root_col_num,
523 offset_col_num,
524 root_row_num,
525 offset_row_num,
526 ) || self.to_marker.is_remove_coordinate(
527 root_col_num,
528 offset_col_num,
529 root_row_num,
530 offset_row_num,
531 )
532 }
533}
534impl AdjustmentCoordinateWithSheet for TwoCellAnchor {
535 #[inline]
536 fn adjustment_insert_coordinate_with_sheet(
537 &mut self,
538 sheet_name: &str,
539 root_col_num: u32,
540 offset_col_num: u32,
541 root_row_num: u32,
542 offset_row_num: u32,
543 ) {
544 if let Some(v) = &mut self.graphic_frame {
545 v.adjustment_insert_coordinate_with_sheet(
546 sheet_name,
547 root_col_num,
548 offset_col_num,
549 root_row_num,
550 offset_row_num,
551 );
552 }
553 }
554
555 #[inline]
556 fn adjustment_remove_coordinate_with_sheet(
557 &mut self,
558 sheet_name: &str,
559 root_col_num: u32,
560 offset_col_num: u32,
561 root_row_num: u32,
562 offset_row_num: u32,
563 ) {
564 if let Some(v) = &mut self.graphic_frame {
565 v.adjustment_remove_coordinate_with_sheet(
566 sheet_name,
567 root_col_num,
568 offset_col_num,
569 root_row_num,
570 offset_row_num,
571 );
572 }
573 }
574}