chore: sync upstream (256 Commits) #12
No reviewers
Labels
No labels
herkunft/alpha-feedback
status
blockiert
status
zu-testen
typ
bug
typ
docs
typ
enhancement
typ
feature
typ
idea
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
iris/gridcraft!12
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "chore/sync-upstream-20261030"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Upstream-Sync von
upstream/main(256 Commits). Fast-Forward.68a4b1a1UPD.1: honor app pretend versions in update checks (#2934)f6bcd77bUpdate prompt shows the app icon and accent color instead of a letter (#2928)400e5acdCI: workflows only call craft-common-actions at @main (#2921)39a10b13packaging: Flatpak finds and prints to CUPS printers (#2913)6ba1e198Merge pull request #1422 from switch87/fix/1419-clear-skips-filtered-rows2ff75179Merge pull request #478 from prxnvt/pr/macros-ui355840a2Merge branch 'prxnvt/pr/macros-ui' into stack/record3fc35e5dMerge branch 'stack/debug' into stack/record3923ab3dMerge branch 'stack/check' into stack/debug70bcab56Merge branch 'stack/run' into stack/check708481b6Merge branch 'stack/tokens' into stack/runa1a491b1Merge branch 'stack/engine' into stack/tokens7bf8ed74Merge remote-tracking branch 'origin/main' into stack/engine146161b4Honor CARGO_BUILD_TARGET in FreeBSD packaging for aarch64 release builds (#2847)70327cd3Grant network access so update checks can reach GitHub (#2841)With chunk _gc_k_2 but no _gc_k_0, get returned Some("") and never looked at _sc_k. It now takes the legacy path unless chunk 0 exists.macro.run runs a macro as one undo step ("Run Macro: <name>"); an error at any step rolls everything back and names the step and its path (3, 2.1 inside a Repeat, 4.then.1 inside an If). It works in four parts: - Policy (macro_policy). File, app, window, automate and macro commands and Undo and Redo never run in a macro. Reading or writing files (data.getData, data.fromTextCsv, insert.picture, Page Layout Background, or an export with a path) needs the command in the macro's permissions and the person's approval. A macro in a workbook opened from a file asks before it runs. Approval holds for the session until the macro's content changes; it is asked for with the new EngineError::Approve and given with approve: true. A step that would open a dialog or a web page fails instead. - Inputs. Each declared input is bound (given, its default, or the selection for the first one), whole columns shrink to the used range, and the shape and column types are checked with messages that name the cells: "Input column 2 (Amount) must hold numbers; C4 holds text". - Footprint. Unless the macro may overwrite, it first runs in dry-run mode on the real workbook inside an undo group that is rolled back, with the session's clipboard, journal, windows and the document's trust put back. CellStore::diff on every sheet, plus the cells commands wrote (DocState::touched), sheets and objects, gives what it would write outside its inputs; cells that only recalculated do not count. Writing over data, deleting a sheet or deleting an object is a conflict: ask (the new EngineError::Confirm, so programmatic runs fail unless they pass onConflict or overwrite), fail, overwrite, or shift the data down or right with Insert Cells and check again. A step that would fail, for example past the edge of the sheet, fails the run before anything changes. File steps and Solver stop the dry run early and are reported. - Steps run on a machine with an explicit frame stack: Repeat over the rows or columns of a range with Row or Column bound, If on one cell with Excel's comparisons, and Stop, which keeps the changes or rolls them back. A run executes at most 100,000 steps within a time limit (60 s by default, timeLimit to change; the web build has no clock, so only the step limit applies there). macro.check reports the bound inputs, the output anchor, the approval needed, the footprint and the conflicts without changing anything; nothing from an unapproved macro runs, not even as a dry run.A path given as a token (`{"$ref": "Input"}` or `{{Input}}`) became a file name only when the step ran, after the policy had passed it, so a macro without permissions or approval could write a file, even from macro.check. Exports also wrote to blank paths the policy ignored. Any `path` other than null now needs the permission and approval, and the runner checks the policy again on the resolved parameters before the command runs.Commands: macro.list, macro.get, macro.save (a macro object or its fields; replace defaults to true), macro.delete, macro.rename and macro.record, beside macro.run, macro.check and macro.debug. Saving, renaming and deleting are undoable. The catalog gains View › Macros › Record Macro (parity 275 / 291). The recorder builds on the recording buffer of top-level commands, so nested commands are never recorded twice and trimming the journal loses nothing. When it stops, commands a macro may not run are left out and listed; a macro run while recording is replaced by its steps when it has no inputs, and an Automate script run by the script's steps; sheet.activate and selection.set steps are added where the sheet or selection changed between commands without one, and runs of them collapse to the last. With relative references (the default) the selection when recording started is the example input: references in and near it become tokens (Input.col(2), Input.rows(2..), Input.col(2).below, Input.row(4).right, Input.cell(r,c)), exact references in formulas become {{...}}, and the input's width, header and column types are inferred from the example. A recording replayed on a longer block of data writes in the matching places. A toggle such as Bold is recorded with the state it set ("on": true), as Excel records Bold = True, so a replay sets it instead of flipping it again. Automate scripts are unchanged: automate.* keep their commands, parameters, storage and results, and View › Macros still lists the scripts and a preserved VBA project.Step parameters can name where they act through tokens that are worked out when the step runs, so a macro made on one block of data works on another: a declared input (Input, or any other input's name), Output (the output rule's anchor), Row or Column (the current item of the Repeat step around the step) and Name:Total (a defined name or a table's data). Methods narrow or move the range: col(n) or col("Header"), row(n), cols(a..b), rows(2..), cell(r,c) relative to the top-left cell, offset(r,c), resize(h,w), data (without the header row), below(n) and right(n). Methods chain. A token is written as {"$ref": "..."} anywhere, as the whole string of a reference parameter (cell, range, target, keys ending in Cell or Range and similar), or as {{...}} inside any string, which is how a formula refers to its input. Other text parameters are never read as tokens, so a cell can still hold the word Row and a chart can still be of type column. Every token becomes A1 text, sheet-qualified when it is on another sheet, before the command runs, so no existing command changes. Plain A1 references in a step stay absolute. A reference that runs past the edge of the sheet is reported apart from other mistakes, so the footprint check can tell the two apart.is_token looked only at the leading identifier, so on a workbook with a sheet called Output (or Row, Column, or the name of a declared input), "Output!A1:B2" was read as the Output token, and the step failed with "the macro has no output anchor" or "unexpected '!A1:B2'". This hit reference keys, $ref and {{...}} alike, including references the recorder writes for other sheets. A base followed by '!' is now a sheet name, and the text resolves as a plain reference.col("...") always matched against the first row of the range, whatever its header flag. On an input declared without a header row, Input.col("Amount") silently picked the first column whose first data cell read "Amount". After .data, the natural Input.data.col("Amount") failed, because the first row was then a data row. The header row is now carried through data, and col("...") is refused with a message when there is none (an input without a header, a Name: base, or after any other method).`Name:` read a name only up to the first period, so `Name:Sales.Q1` looked up `Sales` and treated `Q1` as a method, and a workbook name called Sales.Q1 could not be used in a macro, alone or as `Name:Sales.Q1.cell(1,1)`. The name now runs through periods, and the longest defined name or table that exists and ends at a period (or the end) is used; what follows is read as methods. So `Name:Data.row` is a name called Data.row, and `Name:Sales.offset(1,0)` still moves Sales. When no name matches, the error names the text before the first method, and a bad method after a dotted name is still refused. Tests cover direct resolution, reference parameters, `$ref` and `{{...}}`, with and without a chained method.`col("Amount")` read the header through the cell's display text, which is the formula while Show Formulas is on, so a header such as ="Amo"&"unt" matched nothing. The header is now the cell's value as formatted, whatever the sheet shows.Stopping a recording with a name that a macro already has (in any case) saved over that macro's steps, inputs and description, with only Undo to get them back. A taken name now gets a suffix ("Tidy (2)"), and the save passes replace: false as a backstop.d7c3c183, with main at530a8cc8) into #465 cef58da39e712bb766) into #465 673af7ecdcSix fixes from a review of the resolver, each with a regression test that fails without it: - A bare Row or Column under a general reference key (to, from, at, area, source, target, destination, location) stays text: Change Spelling's replacement word and a pivot field's area were being rewritten into the current row's A1 range. Row.col(2), {{Row}} and {"$ref": "Row"} still resolve there, and the bare word still resolves under cell and range keys. - {{{{ in a string is a literal {{, so text that needs the braces can be written; an unknown token is still an error. - Input.data on a range that is only a header row, and Name: of a table with no data rows, are refused instead of reading the header. - below(0), below(-3) and right(0) are refused like resize(0, 1) is, instead of becoming 1. - A defined name on a sheet whose name holds a dollar sign resolves: the dollar anchors are stripped from the reference part only. - quote_sheet is the engine's one rule (gridcraft_core::quote_sheet), which quotes a sheet named like a cell reference, an R1C1 token or a boolean and leaves a period unquoted. docs/macros.md says which keys take a bare token and how to write a literal brace.673af7ec, with #462 at712bb766and main at530a8cc8) into #2151 44a2f4e2f144a2f4e2, with #465 at673af7ec, #462 at712bb766and main at530a8cc8) into #2144 0df540f166Input.col("date").data resolved to the whole column, header included, because every method cleared the header state. col and cols keep it; the other methods still clear it, and only data keeps the header row for col("…"). The token test asks for D3:D11, cols(2..3).data and col(2).data.col(1).Six fixes from a review of the recorder, each with a regression test (four fail against the old recorder; the other two bound work that grew with the input): - A step that names another sheet with its sheet parameter (cell.set and about fifty other commands) was tokenized as if on the input's sheet, so a recorded cell.set {sheet: Two, cell: C4} ran on Two at the input's relative place. Such a step keeps its references, like a sheet-qualified one. - Inlining recorded runs of other macros and scripts stops at the macro's step limit and counts the rest in dropped, instead of expanding every run first (a thousand runs of a long macro made millions of steps). - macro.record {cancel: true} ends a recording without saving it: the way out of a recording whose macro is too large for the workbook, which could neither be saved nor ended. - Formula tokenization reads each reference in the formula and matches it, instead of listing every column and row of the example (an example as large as a sheet made a million candidates per formula). - A selection of several areas keeps its active cell as it is; a token for the active cell alone put it outside the areas on playback. - Steps recorded in another workbook are counted in dropped.2215934c, with #2151 at44a2f4e2, #465 at673af7ec, #462 at712bb766and main at530a8cc8) into #2145 bac5b9c66ebac5b9c6, with #2144 at2215934c, #2151 at44a2f4e2, #465 at673af7ec, #462 at712bb766and main at530a8cc8) into #2152 ee8e5d35c0A menu-style call with no parameters, such as `file.open`, `data.fromTextCsv` or `home.formatCells` with `{}`, only queues its dialog and succeeds. The recorder kept it as a step with empty parameters, and then kept the dialog's confirming call as well, so playing the recording back ran the command twice, or failed on the empty step when played back headless. Only `execute_headless` took the step back, and only for the open and save-as dialogs. `execute` now compares the queued UI requests before and after a top-level command and does not record one that queued a dialog. The special case in `execute_headless` goes (it keeps turning a missing file into an error), and with it `Recorder::truncate`, which had no other caller.`formulas.defineName {"name": "_gc_macro_1_0"}` replaced the hidden chunk of a stored item with a visible name: the item vanished from `stash::get` and `stash::keys`, and its other chunks stayed behind as orphan hidden names. `formulas.deleteName` could remove chunks the same way, and `formulas.createFromSelection` with `replace` could replace one from a cell label. `stash::set` refused a clash with a visible name, but nothing guarded the other direction. Defining, renaming or deleting a name that `stash::item_key` recognises (`_gc_<key>_<n>` and legacy `_sc_<key>`) is now refused with an error that names `force: true`, which lets the call go ahead. Create from Selection lists such labels in `skipped` unless `force` is true. The params docs of the three commands say so.3b25aa0d, with main atb8771d51) into #465 95c7e70ce66ead1fb5(#462 merged) into #465 fddf2d9a31stash::items and stash::keys listed the first 10,000 items and let the rest vanish without a word. They return a Listing { found, more } now, so a caller can say what it did not list.3f8e6c28, with main at6ead1fb5, where #462 is merged) into #2151 9fdf03cfb59fdf03cf, with #465 at3f8e6c28and main at6ead1fb5, where #462 is merged) into #2144 9331b05f629331b05f, with #2151, #465 at3f8e6c28and main at6ead1fb5, where #462 is merged) into #2145 c225caf30ac225caf3, with #2144, #2151, #465 at3f8e6c28and main at6ead1fb5, where #462 is merged) into #2152 1e34a7642817b9f6ffinto #2151 63a29800a363a29800, with main at17b9f6ff) into #2144 8ea4e279188ea4e279, with main at17b9f6ff) into #2145 2fb31f11f22fb31f11, with main at17b9f6ff) into #2152 b40fa4e06565cbcdd6) into the footprint pull request 567ed0abc92cf5b808) into the footprint pull request c715c36c07c715c36c, with #2144) into #2145 ce2ab9a473ce2ab9a4, with the footprint pull request and #2144) into #2152 60e0039524`automate.stopAction` rolls back the undo groups open on the workbook. While a macro was being debugged it rolled back the debugger's own group and left the debugger set, pointing at a group that was gone. It is now refused under the debugger's lock with "Finish or stop the macro first", as edits are; `macro.debug {action: "stop"}` ends the run. - Test: `stop_action_waits_while_a_macro_is_being_debugged`.- A script step that only opened a dialog (a menu-style call that left the workbook unchanged) is left out of the script run's steps, by the recorder hook's rule; a script run whose steps the recording couldn't keep is left out and listed in `skipped`, not read from the workbook as the script stands when recording stops (a_script_step_that_only_opened_a_dialog_is_left_out_of_the_recording). - A script's toggles keep the state they set (`"on": true`), as a top-level Bold does (a_script_run_records_the_state_its_toggles_set). - A recorded macro.run keeps the steps it ran, as a script run does, so saving or deleting the macro before the recording stops changes nothing (a_recorded_macro_run_keeps_the_steps_that_ran). - The example input's shape and column types are inferred when recording starts, not from the data the recording changed (the_recorded_input_is_inferred_as_it_was_when_recording_started). - Recorded text that playback would read as a token stays text: a reference parameter that reads as one becomes {"$text": …}, and `{{` becomes `{{{{` (recorded_text_that_reads_as_a_token_plays_back_as_text). The resolver (below #2152) gains `{"$text": …}`, text passed as it is (text_marked_as_text_is_never_a_token). - A recording over the macro size limit is cut at the limit and the steps left out are counted in `dropped` (a_recording_past_the_macro_size_is_cut_and_counted). - A macro recorded in a workbook opened from a file is approved for the session, since the person recorded it (a_macro_recorded_in_a_workbook_from_a_file_runs_without_asking). - macro.record refuses parameters it would ignore: name or description when starting, relative when stopping, stop: false while recording, others beside cancel: true, and wrong kinds (record_refuses_parameters_it_would_ignore). - Undo while recording keeps the undone step, as in Excel; documented (undo_while_recording_keeps_the_undone_step_as_excel_does). - Docs: macros.md Recording and Tokens; module comments no longer say scripts are read.198fe482) into the footprint pull request e9effe5dbddadffdb3, with #2144) into #2145 227078f56a227078f5, with the footprint pull request and #2144) into #2152 fdd26876fb90a46da4) into the footprint pull request 267d5bc50391bb5ede, with the footprint pull request and #2144) into #2152 5aa10132aaf6f4585c, with #2144) into #2145 91bb5eded8f225cd10) into #2152 9fe25835d4fe14c0d8) into the footprint pull request 891986bf660aae1ffe) into #2144 fe14c0d86ef0b667aa) into #2152 ec58ec5f4b361fff98, with #2144 and #2151) into #2145 f0b667aa029a22c4b2) into #2152 0a9305f7840a929eaf) into #2144 1a00ce19fb1a00ce19) into the footprint pull request 24f0c3df9224f0c3df, with #2144 and #2151) into #2145 9a22c4b2f20533480c) into #2144 b9aa4a6a9cb9aa4a6a) into the footprint pull request 65634c2bb765634c2b, with #2144 and #2151) into #2145 bf6a8520b8bf6a8520) into #2152 299beb50853772f2c6, with main at42bbf6ba) into #2151 483276f719f6b0cec6) into #2151 6781aa49276781aa49, with main atf6b0cec6) into #2144 34eee8605334eee860, with main atf6b0cec6) into #2550 d4096eee5ad4096eee, with main atf6b0cec6) into #2145 4d26e395fc4d26e395, with main atf6b0cec6) into #2152 f8e1f8dfc0f8e1f8df, with main atf6b0cec6) into #478 c801e50e40