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, inner.highlight_kind)
98 .unwrap_or_else(|| 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#[derive(Clone)]
111pub struct TextTableCell {
112 pub(crate) doc: Arc<Mutex<TextDocumentInner>>,
113 pub(crate) cell_id: usize,
114}
115
116impl TextTableCell {
117 pub fn id(&self) -> usize {
119 self.cell_id
120 }
121
122 pub fn row(&self) -> usize {
124 let inner = self.doc.lock();
125 table_cell_commands::get_table_cell(&inner.ctx, &(self.cell_id as u64))
126 .ok()
127 .flatten()
128 .map(|c| to_usize(c.row))
129 .unwrap_or(0)
130 }
131
132 pub fn column(&self) -> usize {
134 let inner = self.doc.lock();
135 table_cell_commands::get_table_cell(&inner.ctx, &(self.cell_id as u64))
136 .ok()
137 .flatten()
138 .map(|c| to_usize(c.column))
139 .unwrap_or(0)
140 }
141
142 pub fn row_span(&self) -> usize {
144 let inner = self.doc.lock();
145 table_cell_commands::get_table_cell(&inner.ctx, &(self.cell_id as u64))
146 .ok()
147 .flatten()
148 .map(|c| to_usize(c.row_span))
149 .unwrap_or(1)
150 }
151
152 pub fn column_span(&self) -> usize {
154 let inner = self.doc.lock();
155 table_cell_commands::get_table_cell(&inner.ctx, &(self.cell_id as u64))
156 .ok()
157 .flatten()
158 .map(|c| to_usize(c.column_span))
159 .unwrap_or(1)
160 }
161
162 pub fn format(&self) -> CellFormat {
164 let inner = self.doc.lock();
165 table_cell_commands::get_table_cell(&inner.ctx, &(self.cell_id as u64))
166 .ok()
167 .flatten()
168 .map(|c| cell_dto_to_format(&c))
169 .unwrap_or_default()
170 }
171
172 pub fn blocks(&self) -> Vec<TextBlock> {
174 let inner = self.doc.lock();
175 let cell_dto = match table_cell_commands::get_table_cell(&inner.ctx, &(self.cell_id as u64))
176 .ok()
177 .flatten()
178 {
179 Some(c) => c,
180 None => return Vec::new(),
181 };
182
183 let cell_frame_id = match cell_dto.cell_frame {
184 Some(id) => id,
185 None => return Vec::new(),
186 };
187
188 let frame_dto = match frame_commands::get_frame(&inner.ctx, &(cell_frame_id as EntityId))
189 .ok()
190 .flatten()
191 {
192 Some(f) => f,
193 None => return Vec::new(),
194 };
195
196 let mut block_dtos: Vec<_> = frame_dto
198 .blocks
199 .iter()
200 .filter_map(|&id| {
201 block_commands::get_block(&inner.ctx, &{ id })
202 .ok()
203 .flatten()
204 })
205 .collect();
206 let store = inner.ctx.db_context.get_store();
207 crate::inner::refresh_block_positions(&mut block_dtos, store);
208 block_dtos.sort_by_key(|b| b.document_position);
209
210 block_dtos
211 .iter()
212 .map(|b| TextBlock {
213 doc: Arc::clone(&self.doc),
214 block_id: b.id as usize,
215 })
216 .collect()
217 }
218
219 pub fn snapshot_blocks(&self) -> Vec<BlockSnapshot> {
221 let inner = self.doc.lock();
222 let cell_dto = match table_cell_commands::get_table_cell(&inner.ctx, &(self.cell_id as u64))
223 .ok()
224 .flatten()
225 {
226 Some(c) => c,
227 None => return Vec::new(),
228 };
229
230 match cell_dto.cell_frame {
231 Some(frame_id) => crate::text_block::build_blocks_snapshot_for_frame(
232 &inner,
233 frame_id,
234 inner.highlight_kind,
235 ),
236 None => Vec::new(),
237 }
238 }
239}