Commit Graph
761 Commits
Author SHA1 Message Date
aiongg 8724f6b1a5 Merge r2 track t05: forms
# Conflicts:
#	crates/engine/src/tests.rs
#	crates/ui-egui/src/canvas.rs
#	crates/ui-egui/src/forms_ui.rs
#	docs/ui-parity.md
2026-10-22 02:18:46 +00:00
aiongg 2bd66fbe90 Merge r2 track t03: viewer-ui
# Conflicts:
#	crates/automation/tests/automation.rs
#	crates/engine/src/tests.rs
#	crates/ui-egui/src/content_ui.rs
#	crates/ui-egui/src/edit_text_ui.rs
#	crates/ui-egui/src/fill_sign.rs
#	crates/ui-egui/src/forms_ui.rs
#	crates/ui-egui/tests/editing.rs
2026-10-22 02:18:22 +00:00
aiongg 7bf122eea8 Merge r2 track t02: edit-content
# Conflicts:
#	crates/edit/src/tests.rs
#	crates/edit/src/text.rs
#	crates/ui-egui/src/canvas.rs
#	crates/ui-egui/src/edit_text_ui.rs
2026-10-22 02:17:34 +00:00
88dad98dd4 M14: add Norwegian Bokmål interface and date language (#1836)
* M14: add Norwegian Bokmål interface and date language

A 2,592-entry `nb.tsv` covering every key the other bundled catalogs have,
written from the meaning of the English labels (clean-room); terminology
reviewed by a native-speaking contributor. Registers `nb` with the English
one/other plural rule, adds Norwegian month and weekday names for Fill &
Sign dates, resolves `no` and `nn` locales to Bokmål until a Nynorsk catalog
exists, attributes the catalog and records it in parity.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* M14: translate the strings main added since the Norwegian catalog was written

69 keys (signature appearance labels, word count, full-screen prompt, print
as image, image crop, redaction mark appearance, …) and the attribution hash.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* M14: translate the picture-menu and label-paper strings in the Norwegian catalog

Seven keys main added (Cut/Redact Image, Create Link…, Recognize Text…,
Turn upside down, the 4 x 6 in label paper) and the attribution hash.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* M14: translate the page-group folding commands in the Norwegian catalog

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* M14: drop the superseded localization summaries left beside the current ones

Concurrent merges on main left older copies of several localization
summaries next to their replacements. Review of #1836 flagged them:

- localization-parity.md: remove the 2026-10-13 status line and the
  14-language summary that still listed Norwegian as missing; the
  current summary keeps the Italian (and now Norwegian Bokmål)
  measurement dates.
- localization.md: keep one catalog-coverage paragraph (now naming
  Norwegian Bokmål, up to about 2,700 entries) and one font paragraph.
  The font paragraph folds in what only the older copies said: the
  installed Chinese face fallback (#826) and Slovenian's Latin faces and
  four plural forms.
- roadmap.md: end the M14 Missing list before the Fontconfig note.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
Co-authored-by: aiongg <67543387+aiongg@users.noreply.github.com>
Co-authored-by: aiongg <aiongtaigi@gmail.com>
2026-10-21 22:05:23 -04:00
aiongg a52b8d9f4a Merge PR #3498: i18n: add Central Kurdish (Sorani) as an interface language
crates/engine/src/dates.rs, crates/ui-egui/src/i18n/mod.rs: arrays sized 30.
ATTRIBUTION.md: both sides' rows; count regenerated after all merges.
docs/localization.md: main's text with the ckb name, code and catalog-list entry added.
2026-10-22 01:53:40 +00:00
aiongg 2250841fea Integration: #2714 Lao date names and drop the stray Preferences... key
DATE_LANGUAGES gains the lo row in the same position as in LANGUAGES, so
date_languages_are_the_interface_languages holds; lo.tsv loses a key that
matches no English source.
2026-10-22 01:53:24 +00:00
aiongg bf3a199fbb Merge PR #2505: G14: Romanian (ro) interface catalog
crates/engine/src/dates.rs, crates/ui-egui/src/i18n/mod.rs: both sides' language rows, arrays sized 28.
crates/ui-egui/tests/fonts.rs: both catalog lists.
ATTRIBUTION.md: both sides' rows; count regenerated after all merges.
ROADMAP.md: main's summary with Romanian added (15 more catalogs); both log lines.
docs/localization-parity.md: main's rows plus the ro row; 28 interface languages; both revision rows.
docs/localization.md: main's text with Română, the ro locales and code, and the PR's catalog-list edits.
2026-10-22 01:52:53 +00:00
aiongg 13b21c7f64 Merge PR #2227: M14: add Catalan interface and date localization
crates/engine/src/dates.rs, crates/ui-egui/src/i18n/mod.rs: both sides' language rows, arrays sized 27.
crates/ui-egui/tests/fonts.rs: both catalog lists; Catalan added to main's comment.
ATTRIBUTION.toml/.md: both sides' assets; hashes and counts regenerated after all merges.
ROADMAP.md: both log lines.
docs/localization-parity.md: main's rows plus the ca row; 27 interface languages; both revision rows.
docs/localization.md: main's text with Català, the ca locales, code and catalog paragraph added.
2026-10-22 01:52:24 +00:00
aiongg 2530f52d22 Merge PR #3101: feat(viewer): add optional gapless continuous page display
Conflict resolutions:
- ATTRIBUTION.toml: main's entries kept; #3101's page-gap provenance note appended to the 22 catalogs it translates (hashes recomputed separately).
- ATTRIBUTION.md: main's side kept; regenerated from ATTRIBUTION.toml separately.
- ROADMAP.md: #3101's two 2026-10-18 progress-log lines placed after the 2026-10-19 entries.
- docs/roadmap.md: both 2026-10-18 status lines kept; M3 row carries both sides' insertions.
2026-10-22 01:52:18 +00:00
aiongg b94393400d Merge PR #2141: i18n: add Thai (th) interface language
crates/engine/src/dates.rs, crates/ui-egui/src/i18n/mod.rs: both sides' language rows (fi, sq, th), arrays sized 26.
2026-10-22 01:51:26 +00:00
aiongg f0f4aeeb19 Merge PR #2079: i18n: add Albanian (sq) interface language
crates/engine/src/dates.rs, crates/ui-egui/src/i18n/mod.rs: both sides' language rows (vi, fi, sq), arrays sized 25.
crates/ui-egui/tests/fonts.rs: both catalog lists; Albanian added to main's comment.
ATTRIBUTION.toml/.md: both sides' assets; hashes and counts regenerated after all merges.
ROADMAP.md: both log lines.
docs/localization-parity.md: main's rows plus the sq row; 25 interface languages; both revision rows.
docs/localization.md: main's text with Shqip, the sq locales and code added.
2026-10-22 01:51:09 +00:00
aiongg d52247c7d7 Merge PR #1976: i18n: add Indonesian, Vietnamese, Hindi and Korean interfaces
Conflict resolutions:
- crates/ui-egui/src/system_fonts.rs: Hangul fallback kept from #2872 (U+D7A3 probe, its candidate list); #1976's duplicate probe, hangul_fallback and hangul_candidates dropped; #1976's hangul_candidates_are_font_files_without_adobe_designs test kept (checks #2872's list).
- crates/ui-egui/src/theme.rs: SYSTEM_HANGUL_FALLBACK and its fallback entry kept once, at #2872's position and doc wording.
- crates/ui-egui/tests/fonts.rs: #2872's system_fallback_covers_hangul kept, #1976's duplicate dropped.
- ATTRIBUTION.md: asset count 279 (both sides' rows).
2026-10-22 01:50:27 +00:00
aiongg 456b96d06b Merge PR #2454: M5: year-first slash dates (yyyy/mm/dd, yyyy/m/d) for Fill & Sign and headers 2026-10-22 01:49:17 +00:00
aiongg da7f592cd0 Merge PR #1648: XFA: decode BMP and TIFF pictures
crates/xfa/src/tests.rs: union of fixture imports (tiny_bmp, tiny_tiff).
parity/acrobat-features.toml: form.xfa and the XFA image entry: evidence lists unioned, notes take both sides' insertions.
2026-10-22 01:49:05 +00:00
aiongg 4949724ec8 Merge PR #3875: M4: a new bookmark goes to where the reader is (#3865) 2026-10-22 01:48:54 +00:00
aiongg a447dd3db5 Merge PR #2731: Layers panel: Reset to Initial Visibility
Conflicts:
- ATTRIBUTION.toml: ours (sha256 lines only); hashes recomputed at the end of the track
- crates/engine/Cargo.toml: main's workspace chrono entry, plus the PR's pdfcraft-testkit dev-dependency
2026-10-22 01:48:51 +00:00
aiongg be2b7ae411 Merge PR #3452: fix(engine): a reload keeps reading colours and hidden comments (#3443) 2026-10-22 01:48:35 +00:00
aiongg a663f2e9c8 Merge PR #2825: fix(cli): info, text, render and audit take the owner password of R2–R4 files 2026-10-22 01:48:29 +00:00
aiongg 9865f27d8c Merge PR #2619: fix(xfa): run click scripts for every repeated print button
ROADMAP.md, docs/roadmap.md: both status lines and progress-log lines kept; M12 row takes both 'Done since' insertions.
crates/automation/tests/automation.rs, crates/xfa/src/fixtures.rs: union of #2624's and #2619's tests and fixtures.
parity/acrobat-features.toml: form.xfa evidence lists unioned, notes take both sides' insertions.
2026-10-22 01:48:18 +00:00
aiongg ca2e7f8ffd Merge PR #2840: M6: detected form fields get no border or fill
crates/engine/src/js.rs: auto_detect_fields keeps main's comb and turn handling, builds props with no border and no fill for every field, and pushes SetFieldProps unconditionally (the review's fix)
parity/acrobat-features.toml: form.detect-fields keeps main's comb evidence and notes and adds the no-border test and sentence
2026-10-22 01:47:29 +00:00
aiongg 844e35781a Integration: #2624 doc comment of xfa_scripts_initialize_calculate_validate_toggle_and_add_rows back on its test
The #2624 merge inserted its engine tests between #3782's doc comment and the test it documents.
2026-10-22 01:47:22 +00:00
aiongg a0a9e3370e Merge PR #3408: M12: an XFA script that fails partway keeps what it changed before the error
crates/engine/src/tests.rs: union of #2624's tests and #3408's test.
parity/acrobat-features.toml: form.xfa evidence lists unioned, notes take both sides' insertions.
2026-10-22 01:47:22 +00:00
aiongg 0f0d7dcb67 Merge PR #1830: M11: remove PDF/A or PDF/X identification (optimize.remove-standards-id)
ATTRIBUTION.toml: sha256 lines taken from main, recomputed after all merges
2026-10-22 01:47:19 +00:00
aiongg a456f516d9 Merge PR #2756: M7: a paragraph number keeps naming the paragraph text_paragraphs listed (#2516)
ROADMAP.md: kept both sides' progress-log lines.
crates/edit/src/lib.rs: re-export list is the union (TextSession from #3942; BlockKey, block_overlapping from #2756).
2026-10-22 01:47:18 +00:00
aiongg 3ba586fe31 Merge PR #2624: fix(xfa): reflow growable multiline fields after filling
crates/xfa/src/script.rs: template_field and named_in moved to crate::data in #3397; field_grows_with_text calls crate::data::template_field.
parity/acrobat-features.toml: form.xfa evidence lists unioned, notes take both sides' insertions.
2026-10-22 01:46:50 +00:00
aiongg 8949d34632 Merge PR #2711: Wake idle windows for pending recovery snapshots (#2663) 2026-10-22 01:46:43 +00:00
aiongg 5f84926ad6 Merge PR #3946: M14: JPEG and TIFF export refuse a raster of the wrong length instead of panicking 2026-10-22 01:46:36 +00:00
aiongg 3f9b41246a Merge PR #1829: M10: keep dotted-leader contents entries together
ROADMAP.md: progress-log line added at the top
docs/roadmap.md: status line, M10 row note and revision row applied onto main's
parity/acrobat-features.toml: export-docx evidence and notes insertions applied onto main's
crates/edit/src/tests.rs, crates/engine/src/tests.rs: new tests appended after main's
2026-10-22 01:46:30 +00:00
aiongg 5a13228b57 Merge PR #3520: M5: a stamp grows and shrinks with its handles before release (#3518) 2026-10-22 01:46:28 +00:00
aiongg 38fdeb3f22 Merge PR #2724: fix(print): disable Print on documents whose security forbids printing
ATTRIBUTION.toml: kept main's sha256 lines; hashes recomputed after the track.
crates/ui-egui/tests/print.rs: kept both sides' tests.
2026-10-22 01:46:18 +00:00
aiongg 0b1cce39bc Merge PR #3781: Fill & Sign marks stay upright on rotated pages (#2392) 2026-10-22 01:46:17 +00:00
aiongg dbc2647f48 Merge PR #3397: M12: XFA dates are written and read in the field's data picture
crates/engine/src/tests.rs: union of #3180's new test and #3397's doc comment on the next test.
crates/xfa/src/layout.rs: kept #3782's formatted_value (it calls date_pattern, now built on date_letters) and button_action doc.
crates/xfa/src/parse.rs: parse_field doc comment from #3397 (names the data picture).
crates/xfa/src/script.rs: field() doc from #3582 with #3397's "as scripts read it".
crates/xfa/src/tests.rs: union of fixture imports and of the new tests; one doc comment each for the date-conversion and data-fill tests.
2026-10-22 01:45:58 +00:00
aiongg 8cdfe0f4e8 Merge PR #3475: fix(forms): draw fields the file leaves to the viewer, for display only (#3470) 2026-10-22 01:45:38 +00:00
aiongg 533c59cbe3 Merge PR #2994: M10: Export to Word keeps the page background colour (#2992) 2026-10-22 01:45:26 +00:00
aiongg 87f0f4bcbf Merge PR #3043: M3: layer_set shows or hides a layer, and page_render draws with the document's view settings (#2986) 2026-10-22 01:45:26 +00:00
aiongg 54ced90a7e Merge PR #3357: fix(a11y): join and splice page content streams with cross-stream rules (#3217) 2026-10-22 01:45:24 +00:00
aiongg 145a08ae96 Merge PR #3788: M5: drag a line's ends (and a polygon's corners) to change its length and angle
ROADMAP.md: union of progress-log lines.
crates/ui-egui/src/i18n/*.tsv (20 catalogs): union of appended keys.
2026-10-22 01:45:21 +00:00
aiongg 9f44f24448 Merge PR #2210: Add Finnish interface and date language
ATTRIBUTION.md: kept main's asset count; regenerated after all merges.
2026-10-22 01:45:16 +00:00
aiongg 073711cbbb Merge PR #3961: fix(engine): guard undo and redo refresh and roll back on failure (#3925) 2026-10-22 01:45:10 +00:00
aiongg 6e2a449bf7 Merge PR #3318: M6: Optimize AcroForm JavaScript snapshots and diffs
parity/acrobat-features.toml: form calculation order entry keeps main's commands, tools and notes; evidence is the union of both sides.
2026-10-22 01:44:59 +00:00
aiongg d133dfbf75 Merge PR #1989: Edit images: rotate an image by any angle with a knob (#1940) 2026-10-22 01:44:58 +00:00
aiongg 9cb8f52294 Merge PR #3782: M6: XFA formattedValue shows a date in the field's display picture 2026-10-22 01:44:53 +00:00
aiongg 5d7b9a98b3 Merge PR #3192: fix(forms): an XFA form whose config forbids dynamic rendering is static (#3180) 2026-10-22 01:44:51 +00:00
pr-keeperandClaude Sonnet 5.5 473d65da3e Merge upstream main d676fd44 into pr/attachments
Mechanical merge (ATTRIBUTION.toml): main's copy of the pinned files, hashes recomputed, both sides' catalog rows kept.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-22 01:31:45 +00:00
d676fd44ea M6: Prepare a form ▸ Text field table: rows and columns of text fields as one edit (#3479)
* M6: Prepare a form ▸ Text field table: rows and columns of text fields as one edit

Drag an area with the Text field table tool and set it up in a movable
window: rows, columns, row and column spacing, the first row number,
column widths (draggable dividers, arrow keys once focused) and a name
pattern per column, with the table previewed on the page. Add fields adds
every cell as one undoable edit ("Add text field table").

- forms: `table` lays the table out in view space and names its cells. It
  refuses the whole table for a cell under MIN_FIELD_SIDE (now one
  constant) or a name with a period, used twice or already taken, and
  free_base picks the first free TableK for default names.
- engine: `field_table::edit` maps the cells onto the page, /Rotate and
  /UserUnit included, and checks their size again there.
- automation: `form_add_field_table`, with an end-to-end test.
- ui-egui: the window belongs to one page of one document and closes when
  that stops being the one prepared; Enter commits a number instead of
  adding the table; dividers between many columns no longer panic in
  f64::clamp. Strings in all 22 catalogs, and the Spanish engine-wording
  tests cover the table's mistakes.
- parity: form.multiple-copies is partial; copying an existing field into
  a grid is still missing.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* M6: text field table: refuse corners past the page's number range, run it by its command

Review follow-up on #3479.

- engine: a corner finite as an f64 but past f32's range came back from
  the page's f32 mapping infinite. With one such corner a side was
  infinite rather than NaN, so the cell passed and add_field refused it
  only once the edit was applied ("the field is too small"). The edit now
  refuses any corner that isn't finite on the page with the table's own
  reason, before anything is added.
- automation: form.add.text_table runs form_add_field_table through
  command_run, as comment.stamp runs stamp_custom.
- ui-egui: doc comments for the window's three remaining helpers.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* M6: text field table: close on document edits, lay out once per change, keep Escape for fields

Review follow-up on #3479 (benandez).

- The window belongs to the document as it was when it opened: it closes
  when the edit generation moves (a page rotated, moved or deleted, an edit
  undone), so a table set up for one page never lands on another or off it.
- The table is laid out and checked once per change, not several times a
  frame: the window and the page preview share one `Laid` (cells and the
  edit), and the preview draws only the cells in view, naming only those
  with room for a name.
- Escape in a field of the window leaves the field and keeps the setup; a
  second Escape closes the window.
- A table placed with a click is moved in from the page's edges, so all of
  it is on the page.
- `free_base` takes one pass over the names; `{seq}` is documented as
  counting from the first row number; `form_add_field_table` takes its
  names from the batch instead of laying the table out again; the
  unreachable `Dialog::FieldTable` arm says why it is there.

Each new test fails with its fix reverted.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BfMGHQNgdq5yf5tKZHGR3z

* M6: text field table: drawn with its panel closed, the window opens Prepare a form instead of closing

With the tool picked and the Prepare a form panel closed, the form is
still prepared and a table can be drawn. Drawing sends the tool back to
Select, though, so nothing was prepared on the next frame, and the table
window, which lasts only while the form is prepared, closed itself at
once: the table couldn't be set up. Opening the window now opens the
Prepare a form panel it belongs to. Closing the panel while the window
is open still closes the window.

Found by CodeRabbit, which saw the preview stop drawing; the window
closing first was the larger effect. prepare.rs
a_table_drawn_with_the_panel_closed_opens_it_again fails without the fix
("the window stays open": (None, false)).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BfMGHQNgdq5yf5tKZHGR3z

* Drop the second generation binding the main merge left in document_area

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: aiongg <aiongtaigi@gmail.com>
2026-10-21 21:27:31 -04:00
Osvaldo Duran MelendezandClaude Opus 5.5 102f0b7bfb Merge upstream main ffaf3123 into pr/attachments
Only ATTRIBUTION.toml met this branch: main's copy, hashes recomputed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-21 20:51:29 -04:00
ffaf312358 M6: Prepare a form ▸ Calculation order: a page to reorder, check and fix the order fields calculate in (#3733)
* M6: renaming a field renames it in the calculations that read it

A rename silently broke every formula that used the field: a sum dropped
it, notation read it as 0 and a script kept a stale value. set_props now
rewrites the name in each field's Calculate script, in the same edit:
AFSimple_Calculate field lists, simplified field notation (the BVCALC
comment and its translation) and getField calls naming it in one string
literal. The rest of each script is kept as written; names built at run
time, non-UTF-8 script streams and a name another field still has are
left alone, and a self-check keeps a script whose meaning would change.

Notation is read by one lexer shared by notation_js, eval_notation and
the rename. form_set_props returns formulas_updated; Field Properties
says how many calculations now use the new name.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BfMGHQNgdq5yf5tKZHGR3z

* M6: form_set_props leaves the renamed field out of formulas_updated by object

The renamed field was matched by the name given, but set_props stores it trimmed and under
its parent's prefix. When the same call changed the field's own formula, formulas_updated
listed the field as one the rename had rewritten.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BfMGHQNgdq5yf5tKZHGR3z

* M6: calculation order: read, check, fix and set the order fields calculate in

A form's calculations run in its calculation order (/CO), which a field
joins when it gets a calculation, so a chain defined in the wrong order
shows stale values. calculation_order reads the order against the fields,
with what each formula reads (field lists, notation names, literal getField
names) and what is wrong: a field reading one that calculates later, a loop
(strongly connected components, found without recursion), a field /CO
leaves out, and /CO entries that calculate nothing. Fix order is a stable
topological sort that moves only what must move and leaves loops alone.
set_calculation_order writes /CO afresh; a name two fields share (a
malformed form) stands for the next of them in the current order.

Edit::SetCalculationOrder sets it in one undo step and recalculates, and
form_calculation_order reads, sets, moves one field or fixes the order
headlessly. An edited formula now keeps its field's place in /CO, a field
/CO lists twice calculates once, and recalculation runs each field by
object, so two fields sharing a name both calculate. The /CO code of the
Calculate tab, field scripts and recalculation goes through one place.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BfMGHQNgdq5yf5tKZHGR3z

* M6: Prepare a form ▸ Calculation order: a page to reorder, check and fix the order fields calculate in

The calculated fields in the order they calculate (/CO), each with its
formula and the value it shows, moved with Up/Down arrows (as Acrobat's Set
Field Calculation Order), Alt+Up/Down or by dragging. A card says which
fields read one calculated later, which read each other in a loop and which
/CO leaves out, and holds Fix order; a loop's card opens one of its
formulas. On the page, arrows show what the field in focus reads and what
reads it, with each linked field's step. The order is a page of the Prepare
a form panel, opened from its Fields tools, with a back arrow to Prepare a
form; opening it ends Preview and closes the page grid.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BfMGHQNgdq5yf5tKZHGR3z

* M6: form.calculation_order runs form_calculation_order headlessly

The command had no tool linked, so command_list showed none for it and
command_run refused it. form_calculation_order is now its tool: run without
a change, it reads the order.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BfMGHQNgdq5yf5tKZHGR3z

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: aiongg <aiongtaigi@gmail.com>
2026-10-21 20:30:58 -04:00
jonathanwxh-cell 895ccb90c3 fix(engine): guard undo and redo refresh and roll back on failure (#3925) 2026-10-22 08:28:37 +08:00
Osvaldo Duran MelendezandClaude Opus 5.5 f325b63c8a Merge upstream main dbc7130b into pr/attachments
Only ATTRIBUTION.toml met this branch: main's copy, hashes recomputed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-21 20:19:16 -04:00
e451934f72 M6: calculation order: read, check, fix and set the order fields calculate in (#3708)
* M6: renaming a field renames it in the calculations that read it

A rename silently broke every formula that used the field: a sum dropped
it, notation read it as 0 and a script kept a stale value. set_props now
rewrites the name in each field's Calculate script, in the same edit:
AFSimple_Calculate field lists, simplified field notation (the BVCALC
comment and its translation) and getField calls naming it in one string
literal. The rest of each script is kept as written; names built at run
time, non-UTF-8 script streams and a name another field still has are
left alone, and a self-check keeps a script whose meaning would change.

Notation is read by one lexer shared by notation_js, eval_notation and
the rename. form_set_props returns formulas_updated; Field Properties
says how many calculations now use the new name.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BfMGHQNgdq5yf5tKZHGR3z

* M6: form_set_props leaves the renamed field out of formulas_updated by object

The renamed field was matched by the name given, but set_props stores it trimmed and under
its parent's prefix. When the same call changed the field's own formula, formulas_updated
listed the field as one the rename had rewritten.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BfMGHQNgdq5yf5tKZHGR3z

* M6: calculation order: read, check, fix and set the order fields calculate in

A form's calculations run in its calculation order (/CO), which a field
joins when it gets a calculation, so a chain defined in the wrong order
shows stale values. calculation_order reads the order against the fields,
with what each formula reads (field lists, notation names, literal getField
names) and what is wrong: a field reading one that calculates later, a loop
(strongly connected components, found without recursion), a field /CO
leaves out, and /CO entries that calculate nothing. Fix order is a stable
topological sort that moves only what must move and leaves loops alone.
set_calculation_order writes /CO afresh; a name two fields share (a
malformed form) stands for the next of them in the current order.

Edit::SetCalculationOrder sets it in one undo step and recalculates, and
form_calculation_order reads, sets, moves one field or fixes the order
headlessly. An edited formula now keeps its field's place in /CO, a field
/CO lists twice calculates once, and recalculation runs each field by
object, so two fields sharing a name both calculate. The /CO code of the
Calculate tab, field scripts and recalculation goes through one place.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BfMGHQNgdq5yf5tKZHGR3z

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: aiongg <aiongtaigi@gmail.com>
2026-10-21 19:56:27 -04:00