sql_cli/ui/traits/
column_ops.rs1use crate::app_state_container::AppStateContainer;
2use crate::buffer::{AppMode, BufferAPI};
3use crate::ui::viewport_manager::{ColumnOperationResult, NavigationResult, ViewportManager};
4use std::cell::RefCell;
5pub trait ColumnBehavior {
10 fn viewport_manager(&self) -> &RefCell<Option<ViewportManager>>;
12 fn buffer_mut(&mut self) -> &mut dyn BufferAPI;
13 fn buffer(&self) -> &dyn BufferAPI;
14 fn state_container(&self) -> &AppStateContainer;
15
16 fn is_in_results_mode(&self) -> bool {
18 self.buffer().get_mode() == AppMode::Results
20 }
21
22 fn apply_column_navigation_result(&mut self, result: NavigationResult, direction: &str) {
24 let visual_position = result.column_position;
27
28 tracing::debug!(
29 "[COLUMN_OPS] apply_column_navigation_result: direction={}, visual_position={}",
30 direction,
31 visual_position
32 );
33
34 self.buffer_mut().set_current_column(visual_position);
36 tracing::debug!(
37 "[COLUMN_OPS] apply_column_navigation_result: set buffer column to {}",
38 visual_position
39 );
40
41 self.state_container().navigation_mut().selected_column = visual_position;
43 tracing::debug!(
44 "[COLUMN_OPS] apply_column_navigation_result: set navigation column to {}",
45 visual_position
46 );
47
48 if result.viewport_changed {
50 let mut offset = self.buffer().get_scroll_offset();
51 offset.1 = result.scroll_offset;
52 self.buffer_mut().set_scroll_offset(offset);
53
54 self.state_container().navigation_mut().scroll_offset.1 = result.scroll_offset;
56 }
57
58 let message = match direction {
60 "first" => "Moved to first column".to_string(),
61 "last" => "Moved to last column".to_string(),
62 _ => format!("Moved to column {visual_position}"),
63 };
64 self.buffer_mut().set_status_message(message);
65 }
66
67 fn apply_column_operation_result(&mut self, result: ColumnOperationResult) {
69 if !result.success {
70 if !result.description.is_empty() {
71 self.buffer_mut().set_status_message(result.description);
72 }
73 return;
74 }
75
76 if let Some(dataview) = result.updated_dataview {
78 self.buffer_mut().set_dataview(Some(dataview));
79 }
80
81 if let Some(new_col) = result.new_column_position {
83 self.state_container().navigation_mut().selected_column = new_col;
85
86 if let Some(viewport) = result.new_viewport {
88 let pinned_count = self
89 .buffer()
90 .get_dataview()
91 .as_ref()
92 .map_or(0, |dv| dv.get_pinned_columns().len());
93 self.state_container().navigation_mut().scroll_offset.1 =
94 viewport.start.saturating_sub(pinned_count);
95 }
96
97 self.buffer_mut().set_current_column(new_col);
98 }
99
100 self.buffer_mut().set_status_message(result.description);
102 }
103
104 fn hide_current_column(&mut self) {
108 if !self.is_in_results_mode() {
109 return;
110 }
111
112 let result = self.viewport_manager().borrow_mut().as_mut().map_or_else(
113 || ColumnOperationResult::failure("No viewport manager"),
114 crate::ui::viewport_manager::ViewportManager::hide_current_column_with_result,
115 );
116
117 self.apply_column_operation_result(result);
118 }
119
120 fn unhide_all_columns(&mut self) {
122 let result = self.viewport_manager().borrow_mut().as_mut().map_or_else(
123 || ColumnOperationResult::failure("No viewport manager"),
124 crate::ui::viewport_manager::ViewportManager::unhide_all_columns_with_result,
125 );
126
127 self.apply_column_operation_result(result);
128 }
129
130 fn move_current_column_left(&mut self) {
132 if !self.is_in_results_mode() {
133 return;
134 }
135
136 let result = self.viewport_manager().borrow_mut().as_mut().map_or_else(
137 || ColumnOperationResult::failure("No viewport manager"),
138 crate::ui::viewport_manager::ViewportManager::reorder_column_left_with_result,
139 );
140
141 self.apply_column_operation_result(result);
142 }
143
144 fn move_current_column_right(&mut self) {
146 if !self.is_in_results_mode() {
147 return;
148 }
149
150 let result = self.viewport_manager().borrow_mut().as_mut().map_or_else(
151 || ColumnOperationResult::failure("No viewport manager"),
152 crate::ui::viewport_manager::ViewportManager::reorder_column_right_with_result,
153 );
154
155 self.apply_column_operation_result(result);
156 }
157
158 fn move_column_left(&mut self) {
160 let nav_result = {
162 let mut viewport_borrow = self.viewport_manager().borrow_mut();
163 let vm = viewport_borrow
164 .as_mut()
165 .expect("ViewportManager must exist for navigation");
166 let current_visual = vm.get_crosshair_col();
167 vm.navigate_column_left(current_visual)
168 };
169
170 self.apply_column_navigation_result(nav_result, "left");
171 }
172
173 fn move_column_right(&mut self) {
175 let nav_result = {
177 let mut viewport_borrow = self.viewport_manager().borrow_mut();
178 let vm = viewport_borrow
179 .as_mut()
180 .expect("ViewportManager must exist for navigation");
181 let current_visual = vm.get_crosshair_col();
182 tracing::debug!(
183 "[COLUMN_OPS] move_column_right: current_visual from VM = {}",
184 current_visual
185 );
186 let result = vm.navigate_column_right(current_visual);
187 tracing::debug!(
188 "[COLUMN_OPS] move_column_right: navigation result column_position = {}",
189 result.column_position
190 );
191 result
192 };
193
194 tracing::debug!(
195 "[COLUMN_OPS] move_column_right: applying result with column_position = {}",
196 nav_result.column_position
197 );
198 self.apply_column_navigation_result(nav_result, "right");
199 }
200
201 fn goto_first_column(&mut self) {
203 let nav_result = {
205 let mut viewport_borrow = self.viewport_manager().borrow_mut();
206 viewport_borrow
207 .as_mut()
208 .expect("ViewportManager must exist for navigation")
209 .navigate_to_first_column()
210 };
211
212 self.apply_column_navigation_result(nav_result, "first");
214 }
215
216 fn goto_last_column(&mut self) {
218 let nav_result = {
220 let mut viewport_borrow = self.viewport_manager().borrow_mut();
221 viewport_borrow
222 .as_mut()
223 .expect("ViewportManager must exist for navigation")
224 .navigate_to_last_column()
225 };
226
227 self.apply_column_navigation_result(nav_result, "last");
229 }
230}