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(
98 &inner,
99 self.table_id as u64,
100 crate::highlight::SnapshotHighlights {
101 kind: inner.highlight_kind,
102 mask: &crate::highlight::HighlightMask::ALL,
103 suppress_paint: false,
104 },
105 )
106 .unwrap_or_else(|| TableSnapshot {
107 table_id: self.table_id,
108 rows: 0,
109 columns: 0,
110 column_widths: Vec::new(),
111 format: TableFormat::default(),
112 cells: Vec::new(),
113 })
114 }
115}
116
117#[derive(Clone)]
119pub struct TextTableCell {
120 pub(crate) doc: Arc<Mutex<TextDocumentInner>>,
121 pub(crate) cell_id: usize,
122}
123
124impl TextTableCell {
125 pub fn id(&self) -> usize {
127 self.cell_id
128 }
129
130 pub fn row(&self) -> usize {
132 let inner = self.doc.lock();
133 table_cell_commands::get_table_cell(&inner.ctx, &(self.cell_id as u64))
134 .ok()
135 .flatten()
136 .map(|c| to_usize(c.row))
137 .unwrap_or(0)
138 }
139
140 pub fn column(&self) -> usize {
142 let inner = self.doc.lock();
143 table_cell_commands::get_table_cell(&inner.ctx, &(self.cell_id as u64))
144 .ok()
145 .flatten()
146 .map(|c| to_usize(c.column))
147 .unwrap_or(0)
148 }
149
150 pub fn row_span(&self) -> usize {
152 let inner = self.doc.lock();
153 table_cell_commands::get_table_cell(&inner.ctx, &(self.cell_id as u64))
154 .ok()
155 .flatten()
156 .map(|c| to_usize(c.row_span))
157 .unwrap_or(1)
158 }
159
160 pub fn column_span(&self) -> usize {
162 let inner = self.doc.lock();
163 table_cell_commands::get_table_cell(&inner.ctx, &(self.cell_id as u64))
164 .ok()
165 .flatten()
166 .map(|c| to_usize(c.column_span))
167 .unwrap_or(1)
168 }
169
170 pub fn format(&self) -> CellFormat {
172 let inner = self.doc.lock();
173 table_cell_commands::get_table_cell(&inner.ctx, &(self.cell_id as u64))
174 .ok()
175 .flatten()
176 .map(|c| cell_dto_to_format(&c))
177 .unwrap_or_default()
178 }
179
180 pub fn blocks(&self) -> Vec<TextBlock> {
182 let inner = self.doc.lock();
183 let cell_dto = match table_cell_commands::get_table_cell(&inner.ctx, &(self.cell_id as u64))
184 .ok()
185 .flatten()
186 {
187 Some(c) => c,
188 None => return Vec::new(),
189 };
190
191 let cell_frame_id = match cell_dto.cell_frame {
192 Some(id) => id,
193 None => return Vec::new(),
194 };
195
196 let frame_dto = match frame_commands::get_frame(&inner.ctx, &(cell_frame_id as EntityId))
197 .ok()
198 .flatten()
199 {
200 Some(f) => f,
201 None => return Vec::new(),
202 };
203
204 let mut block_dtos: Vec<_> = frame_dto
206 .blocks
207 .iter()
208 .filter_map(|&id| {
209 block_commands::get_block(&inner.ctx, &{ id })
210 .ok()
211 .flatten()
212 })
213 .collect();
214 let store = inner.ctx.db_context.get_store();
215 crate::inner::refresh_block_positions(&mut block_dtos, store);
216 block_dtos.sort_by_key(|b| b.document_position);
217
218 block_dtos
219 .iter()
220 .map(|b| TextBlock {
221 doc: Arc::clone(&self.doc),
222 block_id: b.id as usize,
223 })
224 .collect()
225 }
226
227 pub fn snapshot_blocks(&self) -> Vec<BlockSnapshot> {
229 let inner = self.doc.lock();
230 let cell_dto = match table_cell_commands::get_table_cell(&inner.ctx, &(self.cell_id as u64))
231 .ok()
232 .flatten()
233 {
234 Some(c) => c,
235 None => return Vec::new(),
236 };
237
238 match cell_dto.cell_frame {
239 Some(frame_id) => crate::text_block::build_blocks_snapshot_for_frame(
240 &inner,
241 frame_id,
242 crate::highlight::SnapshotHighlights {
243 kind: inner.highlight_kind,
244 mask: &crate::highlight::HighlightMask::ALL,
245 suppress_paint: false,
246 },
247 ),
248 None => Vec::new(),
249 }
250 }
251}