Skip to main content

tree_table/api/
selection_boxes.rs

1use alloc::string::ToString;
2use alloc::{rc::Rc, string::String, vec::Vec};
3use core::cell::RefCell;
4use hashbrown::HashSet;
5
6use crate::args::{AddSelectionArgs, SelectRowsColsArgs, SelectionClearArgs};
7use crate::utils::consecutive_ranges::consecutive_ranges_owned;
8use crate::{Change, EventData, NO_END, Table};
9
10impl Table {
11    /// Clear all selections.
12    pub fn selection_clear(
13        &mut self,
14        kwargs: Option<SelectionClearArgs>,
15    ) -> Result<Option<Rc<RefCell<EventData>>>, String> {
16        if self.sel.selected.is_none() && self.sel.selection_boxes.is_empty() {
17            return Ok(None);
18        }
19        let kwargs: SelectionClearArgs = kwargs.unwrap_or_default();
20        let mut event_data: EventData = self.cr_new_event(false);
21        Self::acr_deselect_all(&mut self.sel, Some(&mut event_data));
22        self.cr_finalize_event(event_data, kwargs.undo, kwargs.emit)
23    }
24
25    /// Create a selection box using a span. Uses displayed indices.
26    pub fn select(
27        &mut self,
28        kwargs: Option<AddSelectionArgs>,
29    ) -> Result<Option<Rc<RefCell<EventData>>>, String> {
30        let kwargs: AddSelectionArgs = kwargs.unwrap_or_default();
31        let span = self.cr_key_to_span(kwargs.key)?;
32        let mut event_data: EventData = self.cr_new_event(false);
33        let change = Change::add_selection_boxes(1, self.sel.selected.clone());
34        Self::acr_add_selection_box(
35            &mut self.sel,
36            &self.grid,
37            span.row,
38            span.end_row,
39            span.col,
40            span.end_col,
41            kwargs.current,
42        );
43        event_data.changes.push(change);
44        self.cr_finalize_event(event_data, kwargs.undo, kwargs.emit)
45    }
46
47    /// Select rows using either item ids or row numbers. Uses data indices.
48    pub fn select_rows(
49        &mut self,
50        kwargs: Option<SelectRowsColsArgs>,
51    ) -> Result<Option<Rc<RefCell<EventData>>>, String> {
52        let kwargs: SelectRowsColsArgs = kwargs.unwrap_or(SelectRowsColsArgs {
53            items: self
54                .grid
55                .index
56                .cells
57                .iter()
58                .map(|c| c.iid.to_string())
59                .collect(),
60            replace: false,
61            current: true,
62            emit: true,
63            undo: true,
64        });
65        if kwargs.items.is_empty() {
66            return Ok(None);
67        }
68
69        // Convert iids / numbers to numbers
70        let mut row_nums = Vec::new();
71        for iid in kwargs.items.into_iter() {
72            row_nums.push(Self::acr_pos(&self.grid.index.iid_to_row, &iid)?);
73        }
74        row_nums.sort_unstable();
75        row_nums.dedup();
76
77        let mut event_data: EventData = self.cr_new_event(false);
78
79        // If we're using tree mode then we need to expand rows
80        if self.opts.tree_mode {
81            let mut to_open: HashSet<usize> = HashSet::new();
82            for rn in row_nums.iter() {
83                // Is not visible and has a parent then add ancestors to to_open
84                if !Self::acr_row_is_vis(&self.grid.index.cells, *rn)?
85                    && Self::acr_row_has_par(&self.grid.index.cells, *rn)?
86                {
87                    let iid = Self::acr_borrow_riid(&self.grid.index.cells, *rn)?;
88                    for anc_res in self.grid.index.ancestor_rows(&iid) {
89                        to_open.insert(anc_res?);
90                    }
91                }
92            }
93            if !to_open.is_empty() {
94                let to_show =
95                    self.cr_tree_open_close(to_open.into_iter(), true, Some(&mut event_data))?;
96                Self::acr_set_row_vis(
97                    &mut self.grid.index.cells,
98                    to_show.into_iter(),
99                    true,
100                    Some(&mut event_data),
101                )?;
102            }
103        // If we're not using tree mode we just need to show items
104        } else {
105            Self::acr_set_row_vis(
106                &mut self.grid.index.cells,
107                row_nums.iter().map(|n| *n),
108                true,
109                Some(&mut event_data),
110            )?;
111        }
112
113        // We have to remake canvas positions because items may have been unhidden
114        Self::acr_remake_rows(
115            &mut self.grid.canvas_rows,
116            &mut self.grid.disp_rows,
117            &self.grid.index.cells,
118            self.opts.horizontal_grid_line_width.clone(),
119        );
120
121        let old_selected = self.sel.selected.clone();
122
123        // Clear current selections if kwargs.replace
124        if kwargs.replace {
125            Self::acr_deselect_all(&mut self.sel, Some(&mut event_data));
126        }
127
128        let old_len = self.sel.selection_boxes.len();
129
130        // Select the items, converting data item indices to displayed
131        for (start, end) in consecutive_ranges_owned(
132            row_nums
133                .iter()
134                .filter_map(|n| Self::acr_data_to_disp_opt(&self.grid.disp_rows, *n)),
135        ) {
136            Self::acr_add_selection_box(
137                &mut self.sel,
138                &self.grid,
139                start,
140                end,
141                0,
142                NO_END,
143                kwargs.current,
144            );
145        }
146
147        let num_added = self.sel.selection_boxes.len() - old_len;
148        event_data
149            .changes
150            .push(Change::add_selection_boxes(num_added, old_selected));
151        self.cr_finalize_event(event_data, kwargs.undo, kwargs.emit)
152    }
153
154    /// Select cols using either item ids or col numbers. Uses data indices.
155    pub fn select_cols(
156        &mut self,
157        kwargs: Option<SelectRowsColsArgs>,
158    ) -> Result<Option<Rc<RefCell<EventData>>>, String> {
159        // Deserialize kwargs
160        let kwargs: SelectRowsColsArgs = kwargs.unwrap_or(SelectRowsColsArgs {
161            items: self
162                .grid
163                .header
164                .cells
165                .iter()
166                .map(|c| c.iid.to_string())
167                .collect(),
168            replace: false,
169            current: true,
170            emit: true,
171            undo: true,
172        });
173        if kwargs.items.is_empty() {
174            return Ok(None);
175        }
176
177        // Convert iids / numbers to numbers
178        let mut items = Vec::new();
179        for iid in kwargs.items.into_iter() {
180            items.push(Self::acr_pos(&self.grid.header.iid_to_col, &iid)?);
181        }
182        items.sort_unstable();
183        items.dedup();
184
185        let mut event_data: EventData = self.cr_new_event(false);
186
187        // Unhide any currently hidden items
188        Self::acr_set_col_vis(
189            &mut self.grid.header.cells,
190            items.iter().map(|n| *n),
191            true,
192            Some(&mut event_data),
193        )?;
194
195        // We have to remake canvas positions because items may have been unhidden
196        Self::acr_remake_cols(
197            &mut self.grid.canvas_cols,
198            &mut self.grid.disp_cols,
199            &self.grid.header.cells,
200            self.opts.vertical_grid_line_width.clone(),
201        );
202
203        let old_selected = self.sel.selected.clone();
204
205        // Clear current selections if kwargs.replace
206        if kwargs.replace {
207            Self::acr_deselect_all(&mut self.sel, Some(&mut event_data));
208        }
209
210        let old_len = self.sel.selection_boxes.len();
211
212        // Select the items, converting data item indices to displayed
213        for (start, end) in consecutive_ranges_owned(
214            items
215                .iter()
216                .filter_map(|n| Self::acr_data_to_disp_opt(&self.grid.disp_cols, *n)),
217        ) {
218            Self::acr_add_selection_box(
219                &mut self.sel,
220                &self.grid,
221                0,
222                NO_END,
223                start,
224                end,
225                kwargs.current,
226            );
227        }
228
229        let num_added = self.sel.selection_boxes.len() - old_len;
230        event_data
231            .changes
232            .push(Change::add_selection_boxes(num_added, old_selected));
233
234        self.cr_finalize_event(event_data, kwargs.undo, kwargs.emit)
235    }
236}