text_document/
text_table.rs1use std::sync::Arc;
4
5use parking_lot::Mutex;
6
7use frontend::commands::{block_commands, frame_commands, table_cell_commands, table_commands};
8use frontend::common::types::EntityId;
9
10use crate::convert::to_usize;
11use crate::flow::{BlockSnapshot, CellFormat, TableFormat, TableSnapshot};
12use crate::inner::TextDocumentInner;
13use crate::text_block::TextBlock;
14use crate::text_frame::{cell_dto_to_format, table_dto_to_format};
15
16#[derive(Clone)]
20pub struct TextTable {
21 pub(crate) doc: Arc<Mutex<TextDocumentInner>>,
22 pub(crate) table_id: usize,
23}
24
25impl TextTable {
26 pub fn id(&self) -> usize {
28 self.table_id
29 }
30
31 pub fn rows(&self) -> usize {
33 let inner = self.doc.lock();
34 table_commands::get_table(&inner.ctx, &(self.table_id as u64))
35 .ok()
36 .flatten()
37 .map(|t| to_usize(t.rows))
38 .unwrap_or(0)
39 }
40
41 pub fn columns(&self) -> usize {
43 let inner = self.doc.lock();
44 table_commands::get_table(&inner.ctx, &(self.table_id as u64))
45 .ok()
46 .flatten()
47 .map(|t| to_usize(t.columns))
48 .unwrap_or(0)
49 }
50
51 pub fn cell(&self, row: usize, col: usize) -> Option<TextTableCell> {
53 let inner = self.doc.lock();
54 let table_dto = table_commands::get_table(&inner.ctx, &(self.table_id as u64))
55 .ok()
56 .flatten()?;
57
58 for &cell_id in &table_dto.cells {
59 if let Some(cell_dto) = table_cell_commands::get_table_cell(&inner.ctx, &{ cell_id })
60 .ok()
61 .flatten()
62 && cell_dto.row as usize == row
63 && cell_dto.column as usize == col
64 {
65 return Some(TextTableCell {
66 doc: Arc::clone(&self.doc),
67 cell_id: cell_dto.id as usize,
68 });
69 }
70 }
71 None
72 }
73
74 pub fn column_widths(&self) -> Vec<i32> {
76 let inner = self.doc.lock();
77 table_commands::get_table(&inner.ctx, &(self.table_id as u64))
78 .ok()
79 .flatten()
80 .map(|t| t.column_widths.iter().map(|&v| v as i32).collect())
81 .unwrap_or_default()
82 }
83
84 pub fn format(&self) -> TableFormat {
86 let inner = self.doc.lock();
87 table_commands::get_table(&inner.ctx, &(self.table_id as u64))
88 .ok()
89 .flatten()
90 .map(|t| table_dto_to_format(&t))
91 .unwrap_or_default()
92 }
93
94 pub fn snapshot(&self) -> TableSnapshot {
96 let inner = self.doc.lock();
97 crate::text_frame::build_table_snapshot(&inner, self.table_id as u64).unwrap_or_else(|| {
98 TableSnapshot {
99 table_id: self.table_id,
100 rows: 0,
101 columns: 0,
102 column_widths: Vec::new(),
103 format: TableFormat::default(),
104 cells: Vec::new(),
105 }
106 })
107 }
108}
109
110#[derive(Clone)]
112pub struct TextTableCell {
113 pub(crate) doc: Arc<Mutex<TextDocumentInner>>,
114 pub(crate) cell_id: usize,
115}
116
117impl TextTableCell {
118 pub fn id(&self) -> usize {
120 self.cell_id
121 }
122
123 pub fn row(&self) -> usize {
125 let inner = self.doc.lock();
126 table_cell_commands::get_table_cell(&inner.ctx, &(self.cell_id as u64))
127 .ok()
128 .flatten()
129 .map(|c| to_usize(c.row))
130 .unwrap_or(0)
131 }
132
133 pub fn column(&self) -> usize {
135 let inner = self.doc.lock();
136 table_cell_commands::get_table_cell(&inner.ctx, &(self.cell_id as u64))
137 .ok()
138 .flatten()
139 .map(|c| to_usize(c.column))
140 .unwrap_or(0)
141 }
142
143 pub fn row_span(&self) -> usize {
145 let inner = self.doc.lock();
146 table_cell_commands::get_table_cell(&inner.ctx, &(self.cell_id as u64))
147 .ok()
148 .flatten()
149 .map(|c| to_usize(c.row_span))
150 .unwrap_or(1)
151 }
152
153 pub fn column_span(&self) -> usize {
155 let inner = self.doc.lock();
156 table_cell_commands::get_table_cell(&inner.ctx, &(self.cell_id as u64))
157 .ok()
158 .flatten()
159 .map(|c| to_usize(c.column_span))
160 .unwrap_or(1)
161 }
162
163 pub fn format(&self) -> CellFormat {
165 let inner = self.doc.lock();
166 table_cell_commands::get_table_cell(&inner.ctx, &(self.cell_id as u64))
167 .ok()
168 .flatten()
169 .map(|c| cell_dto_to_format(&c))
170 .unwrap_or_default()
171 }
172
173 pub fn blocks(&self) -> Vec<TextBlock> {
175 let inner = self.doc.lock();
176 let cell_dto = match table_cell_commands::get_table_cell(&inner.ctx, &(self.cell_id as u64))
177 .ok()
178 .flatten()
179 {
180 Some(c) => c,
181 None => return Vec::new(),
182 };
183
184 let cell_frame_id = match cell_dto.cell_frame {
185 Some(id) => id,
186 None => return Vec::new(),
187 };
188
189 let frame_dto = match frame_commands::get_frame(&inner.ctx, &(cell_frame_id as EntityId))
190 .ok()
191 .flatten()
192 {
193 Some(f) => f,
194 None => return Vec::new(),
195 };
196
197 let mut block_dtos: Vec<_> = frame_dto
199 .blocks
200 .iter()
201 .filter_map(|&id| {
202 block_commands::get_block(&inner.ctx, &{ id })
203 .ok()
204 .flatten()
205 })
206 .collect();
207 block_dtos.sort_by_key(|b| b.document_position);
208
209 block_dtos
210 .iter()
211 .map(|b| TextBlock {
212 doc: Arc::clone(&self.doc),
213 block_id: b.id as usize,
214 })
215 .collect()
216 }
217
218 pub fn snapshot_blocks(&self) -> Vec<BlockSnapshot> {
220 let inner = self.doc.lock();
221 let cell_dto = match table_cell_commands::get_table_cell(&inner.ctx, &(self.cell_id as u64))
222 .ok()
223 .flatten()
224 {
225 Some(c) => c,
226 None => return Vec::new(),
227 };
228
229 match cell_dto.cell_frame {
230 Some(frame_id) => crate::text_block::build_blocks_snapshot_for_frame(&inner, frame_id),
231 None => Vec::new(),
232 }
233 }
234}