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