mirror of
https://github.com/zaphar/sheetsui.git
synced 2025-07-22 13:00:22 -04:00
feat: x
in range mode will extend the range
This commit is contained in:
parent
2bd4b1ff83
commit
240149caba
@ -68,7 +68,8 @@ will clear the numeric prefix if you want to cancel it.
|
|||||||
|
|
||||||
**Other Keybindings**
|
**Other Keybindings**
|
||||||
|
|
||||||
* `Ctrl-r` will enter range selection mode
|
* `Ctrl-r` will enter range selection mode.
|
||||||
|
* `v` will enter range selection mode with the start of the range already selected.
|
||||||
* `Ctrl-s` will save the sheet.
|
* `Ctrl-s` will save the sheet.
|
||||||
* `Ctrl-c`, `y` Copy the cell or range contents.
|
* `Ctrl-c`, `y` Copy the cell or range contents.
|
||||||
* `Ctrl-v`, `p` Paste into the sheet.
|
* `Ctrl-v`, `p` Paste into the sheet.
|
||||||
|
Binary file not shown.
Binary file not shown.
@ -96,13 +96,29 @@ impl Book {
|
|||||||
Ok(&self.get_sheet()?.sheet_data)
|
Ok(&self.get_sheet()?.sheet_data)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Move to a specific sheel location in the current sheet
|
/// Move to a specific sheet location in the current sheet
|
||||||
pub fn move_to(&mut self, Address { row, col }: &Address) -> Result<()> {
|
pub fn move_to(&mut self, Address { row, col }: &Address) -> Result<()> {
|
||||||
// FIXME(zaphar): Check that this is safe first.
|
// FIXME(zaphar): Check that this is safe first.
|
||||||
self.location.row = *row;
|
self.location.row = *row;
|
||||||
self.location.col = *col;
|
self.location.col = *col;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Extend a cell to the rest of the range.
|
||||||
|
pub fn extend_to(&mut self, from: &Address, to: &Address) -> Result<()> {
|
||||||
|
for ri in from.row..=to.row {
|
||||||
|
for ci in from.col..=to.col {
|
||||||
|
if ri == from.row && ci == from.col {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
let contents = self.model.extend_to(self.current_sheet, from.row as i32, from.col as i32, ri as i32, ci as i32).map_err(|e| anyhow!(e))?;
|
||||||
|
self.model.set_user_input(self.current_sheet, ri as i32, ci as i32, contents)
|
||||||
|
.map_err(|e| anyhow!(e))?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.evaluate();
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
pub fn clear_current_cell(&mut self) -> Result<()> {
|
pub fn clear_current_cell(&mut self) -> Result<()> {
|
||||||
self.clear_cell_contents(self.current_sheet as u32, self.location.clone())
|
self.clear_cell_contents(self.current_sheet as u32, self.location.clone())
|
||||||
|
@ -317,6 +317,7 @@ impl<'ws> Workspace<'ws> {
|
|||||||
"Edit Mode:".to_string(),
|
"Edit Mode:".to_string(),
|
||||||
"* ENTER/RETURN: Exit edit mode and save changes".to_string(),
|
"* ENTER/RETURN: Exit edit mode and save changes".to_string(),
|
||||||
"* Ctrl-r: Enter Range Selection mode".to_string(),
|
"* Ctrl-r: Enter Range Selection mode".to_string(),
|
||||||
|
"* v: Enter Range Selection mode with the start of the range already selected".to_string(),
|
||||||
"* ESC: Exit edit mode and discard changes".to_string(),
|
"* ESC: Exit edit mode and discard changes".to_string(),
|
||||||
"Otherwise edit as normal".to_string(),
|
"Otherwise edit as normal".to_string(),
|
||||||
],
|
],
|
||||||
@ -380,7 +381,7 @@ impl<'ws> Workspace<'ws> {
|
|||||||
return Ok(None);
|
return Ok(None);
|
||||||
}
|
}
|
||||||
KeyCode::Char('r') if key.modifiers == KeyModifiers::CONTROL => {
|
KeyCode::Char('r') if key.modifiers == KeyModifiers::CONTROL => {
|
||||||
self.enter_range_select_mode();
|
self.enter_range_select_mode(false);
|
||||||
return Ok(None);
|
return Ok(None);
|
||||||
}
|
}
|
||||||
KeyCode::Char('p') if key.modifiers == KeyModifiers::CONTROL => {
|
KeyCode::Char('p') if key.modifiers == KeyModifiers::CONTROL => {
|
||||||
@ -579,6 +580,12 @@ impl<'ws> Workspace<'ws> {
|
|||||||
self.copy_range(false)?;
|
self.copy_range(false)?;
|
||||||
}
|
}
|
||||||
KeyCode::Char('y') => self.copy_range(false)?,
|
KeyCode::Char('y') => self.copy_range(false)?,
|
||||||
|
KeyCode::Char('x') => {
|
||||||
|
if let (Some(from), Some(to)) = (self.state.range_select.start.as_ref(), self.state.range_select.end.as_ref()) {
|
||||||
|
self.book.extend_to(from, to)?;
|
||||||
|
}
|
||||||
|
self.exit_range_select_mode()?;
|
||||||
|
}
|
||||||
_ => {
|
_ => {
|
||||||
// moop
|
// moop
|
||||||
}
|
}
|
||||||
@ -670,7 +677,7 @@ impl<'ws> Workspace<'ws> {
|
|||||||
self.enter_edit_mode();
|
self.enter_edit_mode();
|
||||||
}
|
}
|
||||||
KeyCode::Char('r') if key.modifiers == KeyModifiers::CONTROL => {
|
KeyCode::Char('r') if key.modifiers == KeyModifiers::CONTROL => {
|
||||||
self.enter_range_select_mode();
|
self.enter_range_select_mode(false);
|
||||||
}
|
}
|
||||||
KeyCode::Char('c') if key.modifiers == KeyModifiers::CONTROL => {
|
KeyCode::Char('c') if key.modifiers == KeyModifiers::CONTROL => {
|
||||||
self.state.clipboard = Some(ClipboardContents::Cell(
|
self.state.clipboard = Some(ClipboardContents::Cell(
|
||||||
@ -697,7 +704,7 @@ impl<'ws> Workspace<'ws> {
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
KeyCode::Char('v') if key.modifiers != KeyModifiers::CONTROL => {
|
KeyCode::Char('v') if key.modifiers != KeyModifiers::CONTROL => {
|
||||||
self.enter_range_select_mode()
|
self.enter_range_select_mode(true)
|
||||||
}
|
}
|
||||||
KeyCode::Char('p') if key.modifiers != KeyModifiers::CONTROL => {
|
KeyCode::Char('p') if key.modifiers != KeyModifiers::CONTROL => {
|
||||||
self.paste_range()?;
|
self.paste_range()?;
|
||||||
@ -810,6 +817,7 @@ impl<'ws> Workspace<'ws> {
|
|||||||
})?;
|
})?;
|
||||||
}
|
}
|
||||||
KeyCode::Char('g') => {
|
KeyCode::Char('g') => {
|
||||||
|
// TODO(zaphar): This really needs a better state machine.
|
||||||
if self.state.char_queue.first().map(|c| *c == 'g').unwrap_or(false) {
|
if self.state.char_queue.first().map(|c| *c == 'g').unwrap_or(false) {
|
||||||
self.state.char_queue.pop();
|
self.state.char_queue.pop();
|
||||||
self.move_to_top()?;
|
self.move_to_top()?;
|
||||||
@ -819,6 +827,7 @@ impl<'ws> Workspace<'ws> {
|
|||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
// noop
|
// noop
|
||||||
|
self.state.char_queue.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -829,6 +838,7 @@ impl<'ws> Workspace<'ws> {
|
|||||||
match &self.state.clipboard {
|
match &self.state.clipboard {
|
||||||
Some(ClipboardContents::Cell(contents)) => {
|
Some(ClipboardContents::Cell(contents)) => {
|
||||||
self.book.edit_current_cell(contents)?;
|
self.book.edit_current_cell(contents)?;
|
||||||
|
self.book.evaluate();
|
||||||
}
|
}
|
||||||
Some(ClipboardContents::Range(ref rows)) => {
|
Some(ClipboardContents::Range(ref rows)) => {
|
||||||
let Address { row, col } = self.book.location.clone();
|
let Address { row, col } = self.book.location.clone();
|
||||||
@ -846,6 +856,7 @@ impl<'ws> Workspace<'ws> {
|
|||||||
)?;
|
)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
self.book.evaluate();
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
// NOOP
|
// NOOP
|
||||||
@ -878,11 +889,15 @@ impl<'ws> Workspace<'ws> {
|
|||||||
self.state.modality_stack.push(Modality::Dialog);
|
self.state.modality_stack.push(Modality::Dialog);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn enter_range_select_mode(&mut self) {
|
fn enter_range_select_mode(&mut self, init_start: bool) {
|
||||||
self.state.range_select.sheet = Some(self.book.current_sheet);
|
self.state.range_select.sheet = Some(self.book.current_sheet);
|
||||||
self.state.range_select.original_sheet = Some(self.book.current_sheet);
|
self.state.range_select.original_sheet = Some(self.book.current_sheet);
|
||||||
self.state.range_select.original_location = Some(self.book.location.clone());
|
self.state.range_select.original_location = Some(self.book.location.clone());
|
||||||
self.state.range_select.start = None;
|
if init_start {
|
||||||
|
self.state.range_select.start = Some(self.book.location.clone());
|
||||||
|
} else {
|
||||||
|
self.state.range_select.start = None;
|
||||||
|
}
|
||||||
self.state.range_select.end = None;
|
self.state.range_select.end = None;
|
||||||
self.state.modality_stack.push(Modality::RangeSelect);
|
self.state.modality_stack.push(Modality::RangeSelect);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user