mirror of
https://github.com/storytold/gridcraft.git
synced 2026-11-07 02:51:33 +00:00
Form controls: model and commands for buttons, sliders and spin buttons
A sheet holds form controls as floating objects of a new kind (ObjKind::Control): buttons that run a macro or one command, and sliders and spin buttons that hold a whole number from 0 to 30000 and write it to a linked cell. They take part in everything other objects do: ids from the workbook sequence, object.move, object.delete and object.setAnchorMode, the Selection Pane and Bring Forward / Send Backward, anchors that follow row and column edits, fresh ids on a copied sheet, and links that follow inserts, deletes, cut-moves, sheet renames and sheet deletes like chart series. Commands (cmd/controls.rs): insert.button, insert.slider, insert.spinButton, control.format, control.assign, control.setValue, control.press and the control.list query. Each numeric rule (0 <= min < max <= 30000, 1 <= step <= max - min, page >= step for sliders) is refused with its own message, and values are clamped and snapped to the step. control.setValue writes the linked cell through cell.set inside one undo group, so dependents recalculate and one Undo restores both; every commit moves linked controls to what their cells hold. control.press runs a button's macro through macro.run, or its command through the macro policy with the document's trust, so a button in a workbook opened from a file asks before it runs anything. Like a macro step, the command runs inside the scripts' file sandbox unless it is an approved file command. Macros never press controls, and macro.rename keeps buttons pointing at the renamed macro. macro.run, macro.check and the debugger take `output`, which replaces the macro's output anchor for that run (a button that sends the output elsewhere). The policy and the approval go by the stored macro; the footprint, the conflict rule and the per-step check work on the cells `output` names. A value that isn't reference text of at most 1,024 characters, or names no cell, is refused before anything runs.
This commit is contained in:
1 parent
548e5345ee
commit
a0d991e903
19 files changed
+1220
-41
No files matched your search
+22
-4
@@ -1,6 +1,6 @@
|
||||
# Macros
|
||||
|
||||
> **Last updated:** 2026-10-25 · **Change:** minor (recording macros and the management commands; Record Macro takes a name, shortcut and description; the macro interface: Automate › Macros, the Macros and Record Macro dialogs, the step editor, shortcuts)
|
||||
> **Last updated:** 2026-10-31 · **Change:** minor (form buttons run macros; `macro.run` takes `output`)
|
||||
|
||||
GridCraft macros are typed, declarative lists of commands, not VBA. Every step runs a GridCraft
|
||||
command (the same ids the ribbon, CLI and MCP use) or one of three bounded control steps. A macro
|
||||
@@ -98,12 +98,18 @@ refused rather than read as the header.
|
||||
|
||||
## Running
|
||||
|
||||
`macro.run {name, inputs?, onConflict?, overwrite?, approve?, timeLimit?}`:
|
||||
`macro.run {name, inputs?, output?, onConflict?, overwrite?, approve?, timeLimit?}` (`output`
|
||||
replaces the macro's output anchor for this run, as a form button that sends the output elsewhere
|
||||
does; `macro.check` and the debugger take it too). The policy and the approval go by the macro as
|
||||
it is stored; the footprint, the conflict rule and the check of each step work on the cells
|
||||
`output` names, so data there is protected as at the macro's own anchor. An `output` that isn't
|
||||
reference text of at most 1,024 characters, or that names no cell (a bad reference, a sheet that
|
||||
doesn't exist, a cell outside the grid), is refused before anything runs:
|
||||
|
||||
1. **Policy.** File commands other than Properties, exports and printing (such as Open, Save
|
||||
and Close), app, window (including New Window, Hide and Unhide), automate and macro commands,
|
||||
and Undo and Redo, never run in a macro. File › Properties runs, and so do exports and
|
||||
printing (`file.exportPdf`, `exportCsv`, `exportHtml`, `print`, `printPreview`, `saveBytes`)
|
||||
Undo and Redo, and pressing a form control (`control.press`), never run in a macro. File ›
|
||||
Properties runs, and so do exports and printing (`file.exportPdf`, `exportCsv`, `exportHtml`, `print`, `printPreview`, `saveBytes`)
|
||||
that only produce bytes. Reading or writing a file (`data.getData`, `data.fromTextCsv`,
|
||||
`insert.picture` or `pageLayout.background` with a `path`, or an export or print with a
|
||||
`path`) needs the command in the macro's `permissions`. Any `path` other than `null` counts,
|
||||
@@ -246,6 +252,18 @@ kept but does not run the macro.
|
||||
{name, to}`. Saving under a name a macro has is refused unless `replace: true` is passed, and
|
||||
renaming to one is refused; names compare ignoring the case of the letters A to Z. A renamed macro is checked
|
||||
against every limit again, its size included. Saving, renaming and deleting are undoable.
|
||||
Renaming a macro also renames it in the form buttons that run it.
|
||||
|
||||
## Form buttons
|
||||
|
||||
A form button (Insert › Controls › Button, `insert.button`) runs a macro or one command when it is
|
||||
pressed (`control.press {id, approve?, onConflict?}`). `control.assign {id, macro, input?,
|
||||
output?}` makes it run a macro, on the selection when it is pressed (`input: "selection"`, the
|
||||
default) or always on one range (`input: "B2:D9"`), with an optional output cell; `control.assign
|
||||
{id, command, params}` makes it run a command with fixed parameters. A macro runs through
|
||||
`macro.run` with its checks; a command goes through the same policy as a macro step and runs, as
|
||||
a step does, inside the scripts' file sandbox unless it is an approved file command, so a button
|
||||
in a workbook opened from a file asks before it runs anything.
|
||||
|
||||
Macros are saved in the workbook: as a field in GridCraft's JSON format, and in xlsx as hidden
|
||||
defined names (`_gc_macro_<n>_<k>`, the macro's JSON split into string literals within Excel's
|
||||
|
||||
Reference in new issue
Block a user