use crate::oxml::ole::OleObject as OxmlOleObject;
use crate::oxml::shape::{Graphic as OxmlGraphic, GraphicFrame as OxmlFrame};
use crate::shape::base::Shape;
use crate::units::Emu;
#[derive(Clone, Debug, Default)]
pub struct OleObjectShape {
pub(crate) frame: OxmlFrame,
}
impl OleObjectShape {
pub fn new(prog_id: impl Into<String>, name: impl Into<String>) -> Self {
let ole = OxmlOleObject::new(prog_id, name);
let frame = OxmlFrame {
graphic: OxmlGraphic::OleObject(ole),
..Default::default()
};
OleObjectShape { frame }
}
pub fn from_frame(frame: OxmlFrame) -> Self {
OleObjectShape { frame }
}
pub fn ole(&self) -> Option<&OxmlOleObject> {
match &self.frame.graphic {
OxmlGraphic::OleObject(o) => Some(o),
_ => None,
}
}
pub fn ole_mut(&mut self) -> Option<&mut OxmlOleObject> {
match &mut self.frame.graphic {
OxmlGraphic::OleObject(o) => Some(o),
_ => None,
}
}
pub fn rid(&self) -> &str {
match &self.frame.graphic {
OxmlGraphic::OleObject(o) => &o.rid,
_ => "",
}
}
pub fn set_rid(&mut self, rid: impl Into<String>) {
if let Some(o) = self.ole_mut() {
o.rid = rid.into();
}
}
pub fn image_rid(&self) -> &str {
match &self.frame.graphic {
OxmlGraphic::OleObject(o) => &o.image_rid,
_ => "",
}
}
pub fn set_image_rid(&mut self, rid: impl Into<String>) {
if let Some(o) = self.ole_mut() {
o.image_rid = rid.into();
}
}
pub fn prog_id(&self) -> &str {
match &self.frame.graphic {
OxmlGraphic::OleObject(o) => &o.prog_id,
_ => "Package",
}
}
pub fn set_prog_id(&mut self, prog_id: impl Into<String>) {
if let Some(o) = self.ole_mut() {
o.prog_id = prog_id.into();
}
}
pub fn ole_name(&self) -> &str {
match &self.frame.graphic {
OxmlGraphic::OleObject(o) => &o.name,
_ => "",
}
}
pub fn set_ole_name(&mut self, name: impl Into<String>) {
if let Some(o) = self.ole_mut() {
o.name = name.into();
}
}
pub fn show_as_icon(&self) -> bool {
match &self.frame.graphic {
OxmlGraphic::OleObject(o) => o.show_as_icon,
_ => true,
}
}
pub fn set_show_as_icon(&mut self, show: bool) {
if let Some(o) = self.ole_mut() {
o.show_as_icon = show;
}
}
pub fn set_icon_size(&mut self, width: Emu, height: Emu) {
if let Some(o) = self.ole_mut() {
o.image_width = width;
o.image_height = height;
}
}
pub fn set_pic_id_name(&mut self, id: u32, name: impl Into<String>) {
if let Some(o) = self.ole_mut() {
o.pic_id = id;
o.pic_name = name.into();
}
}
pub fn set_placeholder(&mut self, ph_idx: u32, ph_type: Option<&str>) {
self.frame.is_placeholder = true;
self.frame.ph_idx = Some(ph_idx);
self.frame.ph_type = ph_type.map(|s| s.to_string());
}
pub fn clear_placeholder(&mut self) {
self.frame.is_placeholder = false;
self.frame.ph_idx = None;
self.frame.ph_type = None;
}
pub fn is_placeholder(&self) -> bool {
self.frame.is_placeholder
}
pub fn ph_idx(&self) -> Option<u32> {
self.frame.ph_idx
}
pub fn ph_type(&self) -> Option<&str> {
self.frame.ph_type.as_deref()
}
}
impl Shape for OleObjectShape {
fn id(&self) -> u32 {
self.frame.id
}
fn set_id(&mut self, id: u32) {
self.frame.id = id;
}
fn name(&self) -> &str {
&self.frame.name
}
fn set_name(&mut self, name: String) {
self.frame.name = name;
}
fn shape_type(&self) -> &'static str {
"ole_object"
}
fn left(&self) -> Emu {
self.frame.properties.xfrm.off_x.unwrap_or_default()
}
fn set_left(&mut self, emu: Emu) {
self.frame.properties.xfrm.off_x = Some(emu);
}
fn top(&self) -> Emu {
self.frame.properties.xfrm.off_y.unwrap_or_default()
}
fn set_top(&mut self, emu: Emu) {
self.frame.properties.xfrm.off_y = Some(emu);
}
fn width(&self) -> Emu {
self.frame.properties.xfrm.ext_cx.unwrap_or_default()
}
fn set_width(&mut self, emu: Emu) {
self.frame.properties.xfrm.ext_cx = Some(emu);
}
fn height(&self) -> Emu {
self.frame.properties.xfrm.ext_cy.unwrap_or_default()
}
fn set_height(&mut self, emu: Emu) {
self.frame.properties.xfrm.ext_cy = Some(emu);
}
fn rotation(&self) -> f64 {
0.0
}
fn set_rotation(&mut self, _deg: f64) {}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn new_ole_shape_basics() {
let s = OleObjectShape::new("Excel.Sheet.12", "Worksheet");
assert_eq!(s.prog_id(), "Excel.Sheet.12");
assert_eq!(s.ole_name(), "Worksheet");
assert_eq!(s.rid(), "");
assert_eq!(s.image_rid(), "");
assert!(s.show_as_icon());
}
#[test]
fn set_rids_propagate() {
let mut s = OleObjectShape::new("Package", "Object");
s.set_rid("rIdOle1");
s.set_image_rid("rIdImg1");
assert_eq!(s.rid(), "rIdOle1");
assert_eq!(s.image_rid(), "rIdImg1");
}
#[test]
fn set_show_as_icon() {
let mut s = OleObjectShape::new("Package", "Object");
s.set_show_as_icon(false);
assert!(!s.show_as_icon());
}
#[test]
fn set_placeholder_works() {
let mut s = OleObjectShape::new("Package", "Object");
assert!(!s.is_placeholder());
s.set_placeholder(0, Some("obj"));
assert!(s.is_placeholder());
assert_eq!(s.ph_idx(), Some(0));
assert_eq!(s.ph_type(), Some("obj"));
s.clear_placeholder();
assert!(!s.is_placeholder());
}
}