mirror of
https://github.com/storytold/gridcraft.git
synced 2026-10-29 13:16:50 -06:00
G4: two windows on one workbook without copying it; Arrange All
- The workbook's active sheet is an atomic set in place (Workbook::active_sheet /
set_active_sheet), so a window swap or sheet switch never clones the
Arc<Workbook> or marks it dirty. Selections already live in DocState and the
window views. Save records the sheet of the most recently active window.
- A dialog taken out of its window while it runs goes back to that window when
a command run from it switched windows (dialogs::show, ui.dialog.confirm).
- view.arrangeAll {arrange?: tiled|horizontal|vertical|cascade, activeWorkbook?}
returns the visible windows, active first; the desktop moves and sizes the
native windows over the main window's monitor. New Window and Arrange All
buttons on the View ribbon; Arrange Windows dialog.
- Docs: ui-parity, hardware-parity, gaps #20, target-app-parity, ROADMAP.
This commit is contained in:
@@ -158,7 +158,7 @@ fn data_target(s: &Session, p: &Json, cmd: &str) -> Result<(usize, RangeRef)> {
|
||||
{
|
||||
return Err(bad(cmd, format!("`{t}` names a sheet other than `sheet`")));
|
||||
}
|
||||
if sheet != d.wb.active_sheet && p.get("range").is_none() {
|
||||
if sheet != d.wb.active_sheet() && p.get("range").is_none() {
|
||||
return Err(bad(cmd, "missing `range`: the selection is on the active sheet"));
|
||||
}
|
||||
Ok((sheet, data_range(s, p)?))
|
||||
@@ -210,7 +210,7 @@ fn sort_target(s: &Session, p: &Json) -> Result<(usize, RangeRef)> {
|
||||
{
|
||||
return Err(bad("data.sort", format!("`{t}` names a sheet other than `sheet`")));
|
||||
}
|
||||
if sheet != d.wb.active_sheet && p.get("range").is_none() {
|
||||
if sheet != d.wb.active_sheet() && p.get("range").is_none() {
|
||||
return Err(bad("data.sort", "missing `range`: the selection is on the active sheet"));
|
||||
}
|
||||
Ok((sheet, data_range(s, p)?))
|
||||
@@ -502,7 +502,7 @@ fn toggle_filter(s: &mut Session, p: &Json) -> Result<Json> {
|
||||
let (sheet, r) = data_target(s, p, "data.filter")?;
|
||||
super::refuse_unless_allowed(s, sheet, "Filtering", |p| p.autofilter)?;
|
||||
// The active cell belongs to the active sheet: on another sheet the table is the one at `range`.
|
||||
let at = if sheet == s.doc()?.wb.active_sheet { s.doc()?.selection.active } else { r.start };
|
||||
let at = if sheet == s.doc()?.wb.active_sheet() { s.doc()?.selection.active } else { r.start };
|
||||
let has = s.doc()?.wb.sheet(sheet).is_some_and(|sh| sh.autofilter.is_some());
|
||||
let in_table = s.doc()?.wb.sheet(sheet).and_then(|sh| sh.table_at(at).map(|t| t.name.clone()));
|
||||
if let Some(name) = in_table {
|
||||
@@ -554,7 +554,7 @@ fn install_filter(s: &mut Session, p: &Json) -> Result<Json> {
|
||||
}
|
||||
|
||||
fn filter_by(s: &mut Session, p: &Json) -> Result<Json> {
|
||||
let sheet = s.doc()?.wb.active_sheet;
|
||||
let sheet = s.doc()?.wb.active_sheet();
|
||||
super::refuse_unless_allowed(s, sheet, "Filtering", |p| p.autofilter)?;
|
||||
let Some(sh) = s.doc()?.wb.sheet(sheet) else { return Err(EngineError::NoDocument) };
|
||||
let af = match &sh.autofilter {
|
||||
@@ -741,7 +741,7 @@ pub(crate) fn apply_filter(wb: &mut Workbook, sheet: usize) {
|
||||
}
|
||||
|
||||
fn clear_filter(s: &mut Session, _: &Json) -> Result<Json> {
|
||||
let sheet = s.doc()?.wb.active_sheet;
|
||||
let sheet = s.doc()?.wb.active_sheet();
|
||||
edit(s, |cx| {
|
||||
let sh = cx.sheet_mut(sheet)?;
|
||||
if let Some(a) = sh.autofilter.as_mut() {
|
||||
@@ -754,7 +754,7 @@ fn clear_filter(s: &mut Session, _: &Json) -> Result<Json> {
|
||||
}
|
||||
|
||||
fn reapply(s: &mut Session, _: &Json) -> Result<Json> {
|
||||
let sheet = s.doc()?.wb.active_sheet;
|
||||
let sheet = s.doc()?.wb.active_sheet();
|
||||
edit(s, |cx| {
|
||||
apply_filter(&mut cx.wb, sheet);
|
||||
cx.structural = true;
|
||||
@@ -1258,7 +1258,7 @@ fn validate_cmd(s: &mut Session, p: &Json) -> Result<Json> {
|
||||
let d = s.doc()?;
|
||||
let at = cell_param(s, p, "cell")?.unwrap_or(d.selection.active);
|
||||
let input = str_param(p, "input").unwrap_or("");
|
||||
match check_validation(&d.wb, d.wb.active_sheet, at, input) {
|
||||
match check_validation(&d.wb, d.wb.active_sheet(), at, input) {
|
||||
None => Ok(json!({"ok": true})),
|
||||
Some((dv, msg)) => Ok(json!({"ok": false, "message": msg, "title": dv.error_title, "style": format!("{:?}", dv.error_style)})),
|
||||
}
|
||||
@@ -1266,7 +1266,7 @@ fn validate_cmd(s: &mut Session, p: &Json) -> Result<Json> {
|
||||
|
||||
fn circle_invalid(s: &mut Session, _: &Json) -> Result<Json> {
|
||||
let d = s.doc()?;
|
||||
let sheet = d.wb.active_sheet;
|
||||
let sheet = d.wb.active_sheet();
|
||||
let Some(sh) = d.wb.sheet(sheet) else { return Err(EngineError::NoDocument) };
|
||||
let mut bad_cells = Vec::new();
|
||||
for dv in &sh.validations {
|
||||
@@ -1305,7 +1305,7 @@ fn outline_lines(s: &Session, p: &Json) -> Result<(bool, u32, u32)> {
|
||||
fn group(s: &mut Session, p: &Json, on: bool) -> Result<Json> {
|
||||
let si = target_sheet(s, p)?;
|
||||
// The selection belongs to the active sheet, so another sheet needs its lines.
|
||||
if si != s.doc()?.wb.active_sheet && p.get("rows").is_none() && p.get("cols").is_none() {
|
||||
if si != s.doc()?.wb.active_sheet() && p.get("rows").is_none() && p.get("cols").is_none() {
|
||||
return Err(bad(if on { "data.group" } else { "data.ungroup" }, "missing `rows` or `cols`: the selection is on the active sheet"));
|
||||
}
|
||||
let (rows, a, b) = outline_lines(s, p)?;
|
||||
|
||||
Reference in New Issue
Block a user