Skip to main content

tree_table/api/
add_cols.rs

1use alloc::{rc::Rc, string::String, vec, vec::Vec};
2use core::cell::RefCell;
3use hashbrown::HashSet;
4
5use crate::args::{AddArgs, AddNumArgs};
6use crate::utils::consecutive_ranges::consecutive_ranges_owned;
7use crate::{Change, EventData, NO_END, Table, str_err};
8
9impl Table {
10    /// Add new cols with the provided item ids to the Table.
11    pub fn add_cols(
12        &mut self,
13        kwargs: Option<AddArgs>,
14    ) -> Result<Option<Rc<RefCell<EventData>>>, String> {
15        let kwargs: AddArgs = kwargs.unwrap_or_default();
16        let event_data = self.cr_new_event(kwargs.save_selection);
17        let pos = if let Some(pos) = kwargs.pos {
18            pos as usize
19        } else {
20            Self::acr_total_cols(&self.grid.header.cells)
21        };
22        let iids = kwargs.items.unwrap_or(vec![self.grid.header.new_iid()?]);
23        let mut iid_set = HashSet::new();
24        for iid in &iids {
25            if !iid_set.insert(iid.clone()) {
26                return Err(str_err!("Duplicate col iid: {}", iid));
27            }
28            if self.grid.header.iid_to_col.get(iid.as_str()).is_some() {
29                return Err(str_err!("Col iid already exists: {}", iid));
30            }
31        }
32        self._add_cols(
33            iids,
34            pos,
35            kwargs.inherit,
36            kwargs.vis,
37            kwargs.select,
38            kwargs.undo,
39            kwargs.emit,
40            kwargs.save_selection,
41            event_data,
42        )
43    }
44
45    /// Add a number of new cols with auto-generated item ids to the Table.
46    pub fn add_num_cols(
47        &mut self,
48        kwargs: Option<AddNumArgs>,
49    ) -> Result<Option<Rc<RefCell<EventData>>>, String> {
50        let kwargs: AddNumArgs = kwargs.unwrap_or_default();
51        let event_data = self.cr_new_event(false);
52        let pos = if let Some(pos) = kwargs.pos {
53            pos as usize
54        } else {
55            Self::acr_total_cols(&self.grid.header.cells)
56        };
57        let num = kwargs.num.unwrap_or(1);
58        let iids: Vec<String> = (0..num)
59            .map(|_| self.grid.header.new_iid())
60            .collect::<Result<_, _>>()?;
61        self._add_cols(
62            iids,
63            pos,
64            kwargs.inherit,
65            kwargs.vis,
66            kwargs.select,
67            kwargs.undo,
68            kwargs.emit,
69            kwargs.save_selection,
70            event_data,
71        )
72    }
73
74    #[inline]
75    fn _add_cols(
76        &mut self,
77        iids: Vec<String>,
78        pos: usize,
79        inherit: String,
80        vis: bool,
81        select: bool,
82        undo: bool,
83        emit: bool,
84        save_selection: bool,
85        mut event_data: EventData,
86    ) -> Result<Option<Rc<RefCell<EventData>>>, String> {
87        let (cols, header, sorted_seq) =
88            self.cr_add_cols_get_args(iids.clone(), pos, inherit.as_str(), vis)?;
89
90        let num_visible_added = if vis { sorted_seq.len() } else { 0 };
91        let disp_insert_pos = Self::acr_compute_disp_insert_pos(&self.grid.disp_cols, pos);
92
93        self.cr_add_cols(cols, header, sorted_seq, &mut event_data, true);
94        self.cr_adjust_selections_after_col_insert(disp_insert_pos, num_visible_added);
95
96        if select {
97            Self::acr_deselect_all(
98                &mut self.sel,
99                if save_selection {
100                    Some(&mut event_data)
101                } else {
102                    None
103                },
104            );
105            for (start, end) in consecutive_ranges_owned(
106                event_data
107                    .changes
108                    .iter()
109                    .filter_map(|change| match change {
110                        Change::AddCols(added) => Some(added.iter()),
111                        _ => None,
112                    })
113                    .flatten()
114                    .filter_map(|n| Self::acr_data_to_disp_opt(&self.grid.disp_cols, *n)),
115            ) {
116                Self::acr_add_selection_box(&mut self.sel, &self.grid, 0, NO_END, start, end, true);
117            }
118            if save_selection {
119                event_data.changes.push(Change::add_selection_boxes(
120                    self.sel.selection_boxes.len(),
121                    None,
122                ));
123            }
124        }
125
126        self.cr_finalize_event(event_data, undo, emit)
127    }
128}