Skip to main content

tree_table/api/
move_items.rs

1use crate::EventData;
2use crate::Table;
3use crate::TreeMove;
4use crate::args::MoveItemsArgs;
5use crate::str_err;
6use alloc::rc::Rc;
7use alloc::string::String;
8use alloc::string::ToString;
9use alloc::vec::Vec;
10use core::cell::RefCell;
11use hashbrown::HashMap;
12use hashbrown::HashSet;
13
14impl Table {
15    pub fn move_items(
16        &mut self,
17        kwargs: MoveItemsArgs,
18    ) -> Result<Option<Rc<RefCell<EventData>>>, String> {
19        let num_rows = Self::acr_total_rows(&self.grid.index.cells);
20        if num_rows == 0 {
21            return Ok(None);
22        }
23        let Some(items) = kwargs.items else {
24            return Ok(None);
25        };
26
27        // Item ids
28        // Parent
29        let new_par: String = match kwargs.par {
30            Some(par) => par,
31            None => "".to_string(),
32        };
33        if !new_par.is_empty() && !Self::acr_tree_exists(&self.grid.index.iid_to_row, &new_par) {
34            return Err(str_err!("Parent does not exist: {}", new_par));
35        };
36
37        // Check items
38        let mut hash_items: HashSet<Rc<str>> = HashSet::new();
39        for iid in items.into_iter() {
40            if !Self::acr_tree_exists(&self.grid.index.iid_to_row, &iid) {
41                return Err(str_err!("iid does not exist: {}", &iid));
42            }
43            if Self::acr_tree_move_pid_causes_recursive_loop(
44                &self.grid.index.cells,
45                &self.grid.index.iid_to_row,
46                &iid,
47                &new_par,
48            )? {
49                return Err(str_err!(
50                    "Moving '{}' to '{}' would cause a recursive loop",
51                    &iid,
52                    new_par
53                ));
54            }
55            hash_items.insert(Rc::from(iid));
56        }
57
58        // Create a new event
59        let mut event_data = self.cr_new_event(kwargs.save_selection);
60
61        // Set up TreeMove object
62        let move_op: TreeMove = TreeMove {
63            iids: hash_items,
64            new_par: Rc::from(new_par),
65            pos: kwargs.pos,
66        };
67
68        // Perform move operation
69        match self.cr_move_rows(
70            &mut event_data,
71            HashSet::new(),
72            Vec::new(),
73            HashMap::new(),
74            Some(move_op),
75            true,
76        ) {
77            Err(e) => {
78                self.cr_roll_back(Rc::new(RefCell::new(event_data)));
79                return Err(e);
80            }
81            _ => {}
82        };
83
84        // Select moved rows if true
85        if kwargs.select {
86            Self::acr_deselect_all(&mut self.sel, None);
87            let mut moved: Vec<usize> = self.extract_disp_moved_rows(&event_data);
88            if !moved.is_empty() {
89                moved.sort_unstable();
90                self.cr_select_rows_from(moved);
91            }
92        }
93
94        self.cr_finalize_event(event_data, kwargs.undo, kwargs.emit)
95    }
96}