tree_table/api/
move_rows.rs1use crate::Change;
2use crate::EventData;
3use crate::Table;
4use crate::args::MoveArgs;
5use crate::statics::default_emit_event_for_api;
6use crate::statics::default_save_selection_for_api;
7use crate::statics::default_undo_for_api;
8use crate::str_err;
9use alloc::rc::Rc;
10use alloc::string::String;
11use alloc::vec;
12use alloc::vec::Vec;
13use core::cell::RefCell;
14use hashbrown::HashMap;
15use hashbrown::HashSet;
16
17impl Table {
18 pub fn move_rows(
19 &mut self,
20 kwargs: Option<MoveArgs>,
21 ) -> Result<Option<Rc<RefCell<EventData>>>, String> {
22 let num_rows = Self::acr_total_rows(&self.grid.index.cells) as u64;
23 if num_rows == 0 {
24 return Ok(None);
25 }
26
27 let kwargs: MoveArgs = kwargs.unwrap_or(MoveArgs {
28 old_to_new: Some(vec![(0, num_rows.saturating_sub(1))]),
29 select: false,
30 emit: default_emit_event_for_api(),
31 undo: default_undo_for_api(),
32 save_selection: default_save_selection_for_api(),
33 });
34
35 let mut seen_old: HashSet<usize> = HashSet::new();
37 let mut seen_new: HashSet<usize> = HashSet::new();
38 let mut old_to_new: Vec<(usize, usize)> = Vec::new();
39 let mut new_to_old: HashMap<usize, usize> = HashMap::new();
40
41 for (old_pos, new_pos) in kwargs
42 .old_to_new
43 .unwrap_or(vec![(0, num_rows.saturating_sub(1))])
44 {
45 let old = old_pos as usize;
46 let new = new_pos as usize;
47
48 if old >= num_rows as usize {
49 return Err(str_err!(
50 "Old pos {} is out of bounds. Number of rows: {}",
51 old,
52 num_rows
53 ));
54 }
55 if new >= num_rows as usize {
56 return Err(str_err!(
57 "New pos {} exceeds number of rows. Number of rows: {}",
58 new,
59 num_rows
60 ));
61 }
62 if !seen_old.insert(old) {
63 return Err(str_err!("Duplicate old pos: {}", old));
64 }
65 if !seen_new.insert(new) {
66 return Err(str_err!("Duplicate new pos: {}", new));
67 }
68
69 old_to_new.push((old, new));
70 new_to_old.insert(new, old);
71 }
72
73 if old_to_new.is_empty() {
74 return Ok(None);
75 }
76
77 let mut event_data = self.cr_new_event(kwargs.save_selection);
78
79 match self.cr_move_rows(
80 &mut event_data,
81 seen_old,
82 old_to_new,
83 new_to_old,
84 None,
85 true,
86 ) {
87 Err(e) => {
88 self.cr_roll_back(Rc::new(RefCell::new(event_data)));
89 return Err(e);
90 }
91 _ => {}
92 };
93
94 if kwargs.select {
95 Self::acr_deselect_all(&mut self.sel, None);
96 let mut moved: Vec<usize> = self.extract_disp_moved_rows(&event_data);
97 if !moved.is_empty() {
98 moved.sort_unstable();
99 self.cr_select_rows_from(moved);
100 }
101 }
102
103 self.cr_finalize_event(event_data, kwargs.undo, kwargs.emit)
104 }
105
106 pub(crate) fn extract_disp_moved_rows(&self, event_data: &EventData) -> Vec<usize> {
107 let moved: Vec<usize> = event_data
108 .changes
109 .iter()
110 .filter_map(|change| match change {
111 Change::MoveRows(moves) => Some(moves.iter().map(|&(_, to)| to)),
112 _ => None,
113 })
114 .flatten()
115 .filter_map(|n| Self::acr_data_to_disp_row_opt(&self.grid.disp_rows, n))
116 .collect();
117 moved
118 }
119}