pptx_rs/shape/
oleshape.rs1use crate::oxml::ole::OleObject as OxmlOleObject;
27use crate::oxml::shape::{Graphic as OxmlGraphic, GraphicFrame as OxmlFrame};
28use crate::shape::base::Shape;
29use crate::units::Emu;
30
31#[derive(Clone, Debug, Default)]
43pub struct OleObjectShape {
44 pub(crate) frame: OxmlFrame,
46}
47
48impl OleObjectShape {
49 pub fn new(prog_id: impl Into<String>, name: impl Into<String>) -> Self {
55 let ole = OxmlOleObject::new(prog_id, name);
56 let frame = OxmlFrame {
57 graphic: OxmlGraphic::OleObject(ole),
58 ..Default::default()
59 };
60 OleObjectShape { frame }
61 }
62
63 pub fn from_frame(frame: OxmlFrame) -> Self {
65 OleObjectShape { frame }
66 }
67
68 pub fn ole(&self) -> Option<&OxmlOleObject> {
72 match &self.frame.graphic {
73 OxmlGraphic::OleObject(o) => Some(o),
74 _ => None,
75 }
76 }
77
78 pub fn ole_mut(&mut self) -> Option<&mut OxmlOleObject> {
80 match &mut self.frame.graphic {
81 OxmlGraphic::OleObject(o) => Some(o),
82 _ => None,
83 }
84 }
85
86 pub fn rid(&self) -> &str {
91 match &self.frame.graphic {
92 OxmlGraphic::OleObject(o) => &o.rid,
93 _ => "",
94 }
95 }
96
97 pub fn set_rid(&mut self, rid: impl Into<String>) {
100 if let Some(o) = self.ole_mut() {
101 o.rid = rid.into();
102 }
103 }
104
105 pub fn image_rid(&self) -> &str {
110 match &self.frame.graphic {
111 OxmlGraphic::OleObject(o) => &o.image_rid,
112 _ => "",
113 }
114 }
115
116 pub fn set_image_rid(&mut self, rid: impl Into<String>) {
118 if let Some(o) = self.ole_mut() {
119 o.image_rid = rid.into();
120 }
121 }
122
123 pub fn prog_id(&self) -> &str {
127 match &self.frame.graphic {
128 OxmlGraphic::OleObject(o) => &o.prog_id,
129 _ => "Package",
130 }
131 }
132
133 pub fn set_prog_id(&mut self, prog_id: impl Into<String>) {
135 if let Some(o) = self.ole_mut() {
136 o.prog_id = prog_id.into();
137 }
138 }
139
140 pub fn ole_name(&self) -> &str {
144 match &self.frame.graphic {
145 OxmlGraphic::OleObject(o) => &o.name,
146 _ => "",
147 }
148 }
149
150 pub fn set_ole_name(&mut self, name: impl Into<String>) {
152 if let Some(o) = self.ole_mut() {
153 o.name = name.into();
154 }
155 }
156
157 pub fn show_as_icon(&self) -> bool {
161 match &self.frame.graphic {
162 OxmlGraphic::OleObject(o) => o.show_as_icon,
163 _ => true,
164 }
165 }
166
167 pub fn set_show_as_icon(&mut self, show: bool) {
169 if let Some(o) = self.ole_mut() {
170 o.show_as_icon = show;
171 }
172 }
173
174 pub fn set_icon_size(&mut self, width: Emu, height: Emu) {
177 if let Some(o) = self.ole_mut() {
178 o.image_width = width;
179 o.image_height = height;
180 }
181 }
182
183 pub fn set_pic_id_name(&mut self, id: u32, name: impl Into<String>) {
186 if let Some(o) = self.ole_mut() {
187 o.pic_id = id;
188 o.pic_name = name.into();
189 }
190 }
191
192 pub fn set_placeholder(&mut self, ph_idx: u32, ph_type: Option<&str>) {
202 self.frame.is_placeholder = true;
203 self.frame.ph_idx = Some(ph_idx);
204 self.frame.ph_type = ph_type.map(|s| s.to_string());
205 }
206
207 pub fn clear_placeholder(&mut self) {
209 self.frame.is_placeholder = false;
210 self.frame.ph_idx = None;
211 self.frame.ph_type = None;
212 }
213
214 pub fn is_placeholder(&self) -> bool {
216 self.frame.is_placeholder
217 }
218
219 pub fn ph_idx(&self) -> Option<u32> {
221 self.frame.ph_idx
222 }
223
224 pub fn ph_type(&self) -> Option<&str> {
226 self.frame.ph_type.as_deref()
227 }
228}
229
230impl Shape for OleObjectShape {
231 fn id(&self) -> u32 {
232 self.frame.id
233 }
234 fn set_id(&mut self, id: u32) {
235 self.frame.id = id;
236 }
237 fn name(&self) -> &str {
238 &self.frame.name
239 }
240 fn set_name(&mut self, name: String) {
241 self.frame.name = name;
242 }
243 fn shape_type(&self) -> &'static str {
244 "ole_object"
245 }
246
247 fn left(&self) -> Emu {
248 self.frame.properties.xfrm.off_x.unwrap_or_default()
249 }
250 fn set_left(&mut self, emu: Emu) {
251 self.frame.properties.xfrm.off_x = Some(emu);
252 }
253 fn top(&self) -> Emu {
254 self.frame.properties.xfrm.off_y.unwrap_or_default()
255 }
256 fn set_top(&mut self, emu: Emu) {
257 self.frame.properties.xfrm.off_y = Some(emu);
258 }
259 fn width(&self) -> Emu {
260 self.frame.properties.xfrm.ext_cx.unwrap_or_default()
261 }
262 fn set_width(&mut self, emu: Emu) {
263 self.frame.properties.xfrm.ext_cx = Some(emu);
264 }
265 fn height(&self) -> Emu {
266 self.frame.properties.xfrm.ext_cy.unwrap_or_default()
267 }
268 fn set_height(&mut self, emu: Emu) {
269 self.frame.properties.xfrm.ext_cy = Some(emu);
270 }
271
272 fn rotation(&self) -> f64 {
274 0.0
275 }
276 fn set_rotation(&mut self, _deg: f64) {}
277}
278
279#[cfg(test)]
280mod tests {
281 use super::*;
282
283 #[test]
285 fn new_ole_shape_basics() {
286 let s = OleObjectShape::new("Excel.Sheet.12", "Worksheet");
287 assert_eq!(s.prog_id(), "Excel.Sheet.12");
288 assert_eq!(s.ole_name(), "Worksheet");
289 assert_eq!(s.rid(), "");
290 assert_eq!(s.image_rid(), "");
291 assert!(s.show_as_icon());
292 }
293
294 #[test]
296 fn set_rids_propagate() {
297 let mut s = OleObjectShape::new("Package", "Object");
298 s.set_rid("rIdOle1");
299 s.set_image_rid("rIdImg1");
300 assert_eq!(s.rid(), "rIdOle1");
301 assert_eq!(s.image_rid(), "rIdImg1");
302 }
303
304 #[test]
306 fn set_show_as_icon() {
307 let mut s = OleObjectShape::new("Package", "Object");
308 s.set_show_as_icon(false);
309 assert!(!s.show_as_icon());
310 }
311
312 #[test]
314 fn set_placeholder_works() {
315 let mut s = OleObjectShape::new("Package", "Object");
316 assert!(!s.is_placeholder());
317 s.set_placeholder(0, Some("obj"));
318 assert!(s.is_placeholder());
319 assert_eq!(s.ph_idx(), Some(0));
320 assert_eq!(s.ph_type(), Some("obj"));
321 s.clear_placeholder();
322 assert!(!s.is_placeholder());
323 }
324}