use super::{TextBox, Placeholder, AutoShape};
use super::shape::{ShapeType, Shape};
use crate::ole::ppt::package::Result;
#[derive(Debug, Clone)]
pub enum ShapeEnum {
TextBox(TextBox),
Placeholder(Placeholder),
AutoShape(AutoShape),
Picture(PictureShape),
Table(TableShape),
Group(GroupShape),
Line(LineShape),
}
impl ShapeEnum {
pub fn shape_type(&self) -> ShapeType {
match self {
ShapeEnum::TextBox(_) => ShapeType::TextBox,
ShapeEnum::Placeholder(_) => ShapeType::Placeholder,
ShapeEnum::AutoShape(_) => ShapeType::AutoShape,
ShapeEnum::Picture(_) => ShapeType::Picture,
ShapeEnum::Table(_) => ShapeType::Table,
ShapeEnum::Group(_) => ShapeType::Group,
ShapeEnum::Line(_) => ShapeType::Line,
}
}
pub fn text(&self) -> Result<String> {
match self {
ShapeEnum::TextBox(tb) => Shape::text(tb),
ShapeEnum::Placeholder(ph) => Shape::text(ph),
ShapeEnum::AutoShape(as_) => Shape::text(as_),
ShapeEnum::Table(table) => {
let mut text_parts = Vec::new();
for row in 0..table.rows() {
for col in 0..table.columns() {
if let Some(cell_text) = table.cell(row, col) {
if !cell_text.is_empty() {
text_parts.push(cell_text.to_string());
}
}
}
}
Ok(text_parts.join(" "))
}
ShapeEnum::Group(group) => {
let mut text_parts = Vec::new();
for child in group.children() {
if let Ok(child_text) = child.text() {
if !child_text.is_empty() {
text_parts.push(child_text);
}
}
}
Ok(text_parts.join("\n"))
}
ShapeEnum::Picture(_) | ShapeEnum::Line(_) => Ok(String::new()),
}
}
#[inline]
pub fn as_textbox(&self) -> Option<&TextBox> {
match self {
ShapeEnum::TextBox(tb) => Some(tb),
_ => None,
}
}
#[inline]
pub fn as_placeholder(&self) -> Option<&Placeholder> {
match self {
ShapeEnum::Placeholder(ph) => Some(ph),
_ => None,
}
}
#[inline]
pub fn as_autoshape(&self) -> Option<&AutoShape> {
match self {
ShapeEnum::AutoShape(as_) => Some(as_),
_ => None,
}
}
}
#[derive(Debug, Clone)]
pub struct PictureShape {
id: u32,
blip_id: Option<u32>,
name: Option<String>,
left: i32,
top: i32,
width: i32,
height: i32,
}
impl PictureShape {
pub fn new(id: u32) -> Self {
Self {
id,
blip_id: None,
name: None,
left: 0,
top: 0,
width: 0,
height: 0,
}
}
pub fn set_bounds(&mut self, left: i32, top: i32, width: i32, height: i32) {
self.left = left;
self.top = top;
self.width = width;
self.height = height;
}
pub fn set_blip_id(&mut self, blip_id: u32) {
self.blip_id = Some(blip_id);
}
pub fn set_name(&mut self, name: String) {
self.name = Some(name);
}
pub fn id(&self) -> u32 {
self.id
}
pub fn blip_id(&self) -> Option<u32> {
self.blip_id
}
}
#[derive(Debug, Clone)]
pub struct TableShape {
id: u32,
rows: usize,
columns: usize,
cells: Vec<Vec<String>>,
}
impl TableShape {
pub fn new(id: u32, rows: usize, columns: usize) -> Self {
let cells = vec![vec![String::new(); columns]; rows];
Self { id, rows, columns, cells }
}
pub fn id(&self) -> u32 {
self.id
}
pub fn rows(&self) -> usize {
self.rows
}
pub fn columns(&self) -> usize {
self.columns
}
pub fn cell(&self, row: usize, col: usize) -> Option<&str> {
self.cells.get(row).and_then(|r| r.get(col)).map(|s| s.as_str())
}
}
#[derive(Debug, Clone)]
pub struct GroupShape {
id: u32,
children: Vec<ShapeEnum>,
left: i32,
top: i32,
width: i32,
height: i32,
}
impl GroupShape {
pub fn new(id: u32) -> Self {
Self {
id,
children: Vec::new(),
left: 0,
top: 0,
width: 0,
height: 0,
}
}
pub fn add_child(&mut self, shape: ShapeEnum) {
self.children.push(shape);
}
pub fn children(&self) -> &[ShapeEnum] {
&self.children
}
pub fn set_bounds(&mut self, left: i32, top: i32, width: i32, height: i32) {
self.left = left;
self.top = top;
self.width = width;
self.height = height;
}
pub fn id(&self) -> u32 {
self.id
}
}
#[derive(Debug, Clone)]
pub struct LineShape {
id: u32,
x1: i32,
y1: i32,
x2: i32,
y2: i32,
width: i32,
color: Option<u32>,
}
impl LineShape {
pub fn new(id: u32, x1: i32, y1: i32, x2: i32, y2: i32) -> Self {
Self {
id,
x1,
y1,
x2,
y2,
width: 1,
color: None,
}
}
pub fn set_width(&mut self, width: i32) {
self.width = width;
}
pub fn set_color(&mut self, color: u32) {
self.color = Some(color);
}
pub fn id(&self) -> u32 {
self.id
}
pub fn length(&self) -> f64 {
let dx = (self.x2 - self.x1) as f64;
let dy = (self.y2 - self.y1) as f64;
(dx * dx + dy * dy).sqrt()
}
}