Skip to main content

tree_table/api/
item.rs

1use crate::EventData;
2use crate::Table;
3use crate::Val;
4use crate::args::{ItemArgs, ItemResult};
5use crate::args::{ItemColArgs, ItemColResult};
6use crate::str_err;
7use alloc::rc::Rc;
8use alloc::string::String;
9use alloc::vec::Vec;
10use core::cell::RefCell;
11
12impl Table {
13    /// Modify a table item (row).
14    pub fn item(&mut self, kwargs: ItemArgs) -> Result<Option<Rc<RefCell<EventData>>>, String> {
15        let mut iid: String = kwargs.item;
16        let row = Self::acr_pos(&self.grid.index.iid_to_row, &iid)?;
17        let mut event_data = self.cr_new_event(kwargs.save_selection);
18        let normalize = kwargs.fmt_normalize;
19        let ignore_fmt_errs = kwargs.ignore_fmt_errs;
20        let mut need_remake_rows = false;
21
22        let result = (|| -> Result<(), String> {
23            // Deal with open parameter
24            if let Some(open) = kwargs.open {
25                Self::acr_tree_iid_set_open(
26                    &mut self.grid.index.cells,
27                    &self.grid.index.iid_to_row,
28                    &iid,
29                    open,
30                    Some(&mut event_data),
31                )?;
32                if !Self::acr_tree_iid_chn(
33                    &self.grid.index.cells,
34                    &self.grid.index.iid_to_row,
35                    &iid,
36                )?
37                .is_empty()
38                    && Self::acr_row_iid_is_vis(
39                        &self.grid.index.cells,
40                        &self.grid.index.iid_to_row,
41                        &iid,
42                    )?
43                {
44                    Self::acr_tree_descendants_set_vis(
45                        &mut self.grid.index.cells,
46                        &self.grid.index.iid_to_row,
47                        &iid,
48                        open,
49                        Some(&mut event_data),
50                    )?;
51                    need_remake_rows = true;
52                }
53            }
54
55            // Deal with val parameter
56            if let Some(val) = kwargs.val {
57                Self::acr_event_data_fmt_set_ival(
58                    &mut self.grid.index.cells,
59                    row,
60                    val,
61                    normalize,
62                    ignore_fmt_errs,
63                    &mut event_data,
64                )?;
65            }
66
67            // Deal with row values parameter
68            if let Some(vals) = kwargs.vals {
69                let empty_val = &self.opts.empty_val;
70                let table_ncols = Self::acr_total_cols(&self.grid.header.cells);
71                for (key, val) in vals.into_iter() {
72                    let col = Self::acr_pos(&self.grid.header.iid_to_col, &key)?;
73                    if col >= table_ncols {
74                        return Err(str_err!(
75                            "Col does not exist. Col: {}, Table total: {}",
76                            col,
77                            table_ncols,
78                        ));
79                    }
80                    Self::acr_event_data_fmt_set_tval(
81                        &mut self.grid.index.cells,
82                        row,
83                        col,
84                        val,
85                        normalize,
86                        ignore_fmt_errs,
87                        empty_val,
88                        &mut event_data,
89                    )?;
90                }
91            }
92
93            // Deal with iid parameter, id rename
94            if let Some(new_name) = kwargs.iid {
95                if self.grid.index.iid_to_row.get(new_name.as_str()).is_some() {
96                    return Err(str_err!(
97                        "Cannot rename iid, new name already exists: {}",
98                        new_name
99                    ));
100                }
101                iid = new_name.clone();
102                Self::acr_tree_rename_iid(
103                    &mut self.grid.index,
104                    &iid,
105                    Rc::from(new_name),
106                    &mut event_data,
107                )?;
108            }
109            Ok(())
110        })();
111
112        match result {
113            Err(e) => {
114                self.cr_roll_back(Rc::new(RefCell::new(event_data)));
115                return Err(e);
116            }
117            _ => {}
118        }
119
120        if need_remake_rows {
121            Self::acr_remake_rows(
122                &mut self.grid.canvas_rows,
123                &mut self.grid.disp_rows,
124                &self.grid.index.cells,
125                self.opts.horizontal_grid_line_width.clone(),
126            );
127        }
128
129        self.cr_finalize_event_if_any_non_selection_change(
130            event_data,
131            kwargs.undo,
132            kwargs.emit,
133            true,
134        )
135    }
136
137    /// Get information about an item (row).
138    pub fn get_item(&mut self, iid: String) -> Result<ItemResult, String> {
139        let row = Self::acr_pos(&self.grid.index.iid_to_row, &iid)?;
140        let empty_val = &self.opts.empty_val;
141        Ok(ItemResult {
142            pos: row as u64,
143            val: (*Self::acr_icell_val(
144                &self.grid.index.cells,
145                Self::acr_pos(&self.grid.index.iid_to_row, &iid)?,
146            )?)
147            .clone(),
148            values: (0..Self::acr_total_cols(&self.grid.header.cells))
149                .map(|col| {
150                    Self::acr_tcell_val(&self.grid.index.cells, row, col)
151                        .map_or(empty_val.clone(), |r| (*r).clone())
152                })
153                .collect::<Vec<Val>>(),
154            open: Self::acr_tree_iid_is_open(
155                &self.grid.index.cells,
156                &self.grid.index.iid_to_row,
157                &iid,
158            )?,
159        })
160    }
161
162    /// Modify a table column (header item).
163    pub fn col(&mut self, kwargs: ItemColArgs) -> Result<Option<Rc<RefCell<EventData>>>, String> {
164        let iid: String = kwargs.item;
165        let col = Self::acr_pos(&self.grid.header.iid_to_col, &iid)?;
166        let mut event_data = self.cr_new_event(kwargs.save_selection);
167        let normalize = kwargs.fmt_normalize;
168        let ignore_fmt_errs = kwargs.ignore_fmt_errs;
169
170        let result = (|| -> Result<(), String> {
171            // Deal with val parameter (header cell value / column label)
172            if let Some(val) = kwargs.val {
173                Self::acr_event_data_fmt_set_hval(
174                    &mut self.grid.header.cells,
175                    col,
176                    val,
177                    normalize,
178                    ignore_fmt_errs,
179                    &mut event_data,
180                )?;
181            }
182
183            // Deal with vals parameter — set table values *down this column*
184            if let Some(vals) = kwargs.vals {
185                let empty_val = &self.opts.empty_val;
186                let table_nrows = Self::acr_total_rows(&self.grid.index.cells);
187                for (key, val) in vals.into_iter() {
188                    let row = Self::acr_pos(&self.grid.index.iid_to_row, &key)?;
189                    if row >= table_nrows {
190                        return Err(str_err!(
191                            "Row does not exist. Row: {}, Table total: {}",
192                            row,
193                            table_nrows,
194                        ));
195                    }
196                    Self::acr_event_data_fmt_set_tval(
197                        &mut self.grid.index.cells,
198                        row,
199                        col,
200                        val,
201                        normalize,
202                        ignore_fmt_errs,
203                        empty_val,
204                        &mut event_data,
205                    )?;
206                }
207            }
208
209            // Deal with iid parameter (rename)
210            if let Some(new_name) = kwargs.iid {
211                if self.grid.header.iid_to_col.get(new_name.as_str()).is_some() {
212                    return Err(str_err!(
213                        "Cannot rename col, new name already exists: {}",
214                        new_name
215                    ));
216                }
217                Self::acr_header_rename_iid(
218                    &mut self.grid.header,
219                    col,
220                    &iid,
221                    Rc::from(new_name.clone()),
222                    &mut event_data,
223                )?;
224            }
225            Ok(())
226        })();
227
228        match result {
229            Err(e) => {
230                self.cr_roll_back(Rc::new(RefCell::new(event_data)));
231                return Err(e);
232            }
233            _ => {}
234        }
235
236        self.cr_finalize_event_if_any_non_selection_change(
237            event_data,
238            kwargs.undo,
239            kwargs.emit,
240            true,
241        )
242
243        // TODO: roll back in event of error
244    }
245
246    /// Get information about a column.
247    pub fn get_col(&mut self, iid: String) -> Result<ItemColResult, String> {
248        let col = Self::acr_pos(&self.grid.header.iid_to_col, &iid)?;
249        let empty_val = &self.opts.empty_val;
250        Ok(ItemColResult {
251            pos: col as u64,
252            val: (*Self::acr_hcell_val(&self.grid.header.cells, col)?).clone(),
253            values: (0..Self::acr_total_rows(&self.grid.index.cells))
254                .map(|row| {
255                    Self::acr_tcell_val(&self.grid.index.cells, row, col)
256                        .map_or(empty_val.clone(), |r| (*r).clone())
257                })
258                .collect::<Vec<Val>>(),
259        })
260    }
261}