1use std::{
2 cell::{Cell, RefCell},
3 rc::{Rc, Weak},
4};
5
6use crate::{
7 format::{FormatChangeResult, IsFormat},
8 ElementUuid,
9};
10use crate::{
11 format::{FormattedElement, ImageFormat},
12 text_document::{Element, ElementManager, ElementTrait, ModelError},
13 Block,
14};
15
16#[derive(Default, Clone, Debug)]
17pub struct Image {
18 uuid: Cell<ElementUuid>,
19 element_manager: Weak<ElementManager>,
20 text: RefCell<String>,
21 image_format: RefCell<ImageFormat>,
22}
23
24impl PartialEq for Image {
25 fn eq(&self, other: &Self) -> bool {
26 self.uuid == other.uuid && self.image_format == other.image_format
27 }
28}
29
30impl Image {
31 pub(crate) fn new(element_manager: Weak<ElementManager>) -> Self {
32 Image {
33 element_manager,
34 uuid: Default::default(),
35 text: RefCell::new("\u{FFFC}".to_string()),
36 ..Default::default()
37 }
38 }
39
40 pub fn uuid(&self) -> ElementUuid {
41 self.uuid.get()
42 }
43
44 pub(crate) fn image_format(&self) -> ImageFormat {
45 self.format()
46 }
47
48 pub fn plain_text(&self) -> String {
49 " ".to_string()
50 }
51
52 pub fn text_length(&self) -> usize {
53 1
54 }
55
56 fn parent_bloc_rc(&self) -> Rc<Block> {
57 let element_manager = self.element_manager.upgrade().unwrap();
58
59 match element_manager
60 .get_parent_element_using_uuid(self.uuid())
61 .unwrap()
62 {
63 Element::BlockElement(block) => block,
64 _ => unreachable!(),
65 }
66 }
67 pub fn position_in_block(&self) -> usize {
68 let parent_block = self.parent_bloc_rc();
69 parent_block.position_of_child(self.uuid())
70 }
71
72 pub fn start(&self) -> usize {
73 let parent_block = self.parent_bloc_rc();
74
75 parent_block.position() + self.position_in_block()
76 }
77
78 pub fn end(&self) -> usize {
79 self.start() + self.text_length()
80 }
81}
82
83impl ElementTrait for Image {
84 fn set_uuid(&self, uuid: usize) {
85 self.uuid.set(uuid);
86 }
87
88 fn verify_rule_with_parent(&self, parent_element: &Element) -> Result<(), ModelError> {
89 match parent_element {
90 Element::FrameElement(_) => Err(ModelError::WrongParent),
91 Element::BlockElement(_) => Ok(()),
92 Element::TextElement(_) => Err(ModelError::WrongParent),
93 Element::ImageElement(_) => Err(ModelError::WrongParent),
94 }
95 }
96}
97
98impl FormattedElement<ImageFormat> for Image {
99 fn format(&self) -> ImageFormat {
100 self.image_format.borrow().clone()
101 }
102
103 fn set_format(&self, format: &ImageFormat) -> FormatChangeResult {
104 if &*self.image_format.borrow() == format {
105 Ok(None)
106 } else {
107 self.image_format.replace(format.clone());
108 Ok(Some(()))
109 }
110 }
111
112 fn merge_format(&self, format: &ImageFormat) -> FormatChangeResult {
113 self.image_format.borrow_mut().merge_with(format)
114 }
115}
116
117#[cfg(test)]
118mod tests {
119
120 use crate::InsertMode;
121
122 use super::*;
123
124 #[test]
125 fn basics() {
126 let image = Image::new(Weak::new());
127
128 assert_eq!(image.uuid(), 0);
129 assert_eq!(image.plain_text(), " ");
130 assert_eq!(image.text_length(), 1);
131 assert_eq!(image.image_format(), ImageFormat::new());
132
133 let image_bis = Image::new(Weak::new());
134
135 assert_eq!(image, image_bis);
136 }
137
138 #[test]
139 fn position() {
140 let element_manager_rc = ElementManager::new_rc();
141 ElementManager::create_root_frame(element_manager_rc.clone());
142
143 let image = element_manager_rc
144 .insert_new_image(1, InsertMode::AsChild)
145 .unwrap();
146
147 assert_eq!(image.parent_bloc_rc().uuid(), 1);
148 assert_eq!(image.start(), 0);
149 assert_eq!(image.end(), 1);
150 }
151}