mirror of
https://github.com/storytold/pdfcraft.git
synced 2026-10-25 18:59:48 +00:00
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>
This commit is contained in:
+22
-22
@@ -7,7 +7,7 @@ licence = "MIT OR Apache-2.0"
|
||||
licence_file = "LICENSE-MIT"
|
||||
kind = "translation"
|
||||
usage = "Greek UI strings, compiled in by crates/ui-egui/src/i18n/mod.rs"
|
||||
sha256 = "18d2b88bb336ec840dc460ad28ccea620a96eeea26e427cd302eb03e964e6ed2"
|
||||
sha256 = "53b57cc89461ecc4d48350a4b2ef969c9ba138048a8e28d6a8ee45d549847e1f"
|
||||
|
||||
# ATTRIBUTION.toml: one entry per asset (AGENTS.md §1). The source of truth for provenance and licences.
|
||||
# ATTRIBUTION.md is generated from this file: `cargo xtask assets --write`. Checked by `cargo xtask assets` (part of `xtask ci`).
|
||||
@@ -30,7 +30,7 @@ licence = "MIT OR Apache-2.0"
|
||||
licence_file = "LICENSE-MIT"
|
||||
kind = "translation"
|
||||
usage = "Simplified Chinese UI strings, compiled in by crates/ui-egui/src/i18n/mod.rs"
|
||||
sha256 = "14be17199efc810682bd021ec807c6488e96dd5e1c97a009f4c31fae125da0bc"
|
||||
sha256 = "1d4b5c40d08e0c3ee328ffee487ff4133627381cf865d21bec682c247e6628dc"
|
||||
|
||||
[[asset]]
|
||||
path = "crates/ui-egui/src/i18n/zh-hant.tsv"
|
||||
@@ -41,7 +41,7 @@ licence = "MIT OR Apache-2.0"
|
||||
licence_file = "LICENSE-MIT"
|
||||
kind = "translation"
|
||||
usage = "Traditional Chinese UI strings, compiled in by crates/ui-egui/src/i18n/mod.rs"
|
||||
sha256 = "483c060d64d68431afd0a0eae3ef7b356cf29fcbd6a94c7242ef225c814a0077"
|
||||
sha256 = "11045efab47ed4a962861f0e3e9568836a8e9ece9ea2e0a4ec58ccf78d2e677f"
|
||||
|
||||
[[asset]]
|
||||
path = "crates/ui-egui/src/i18n/cs.tsv"
|
||||
@@ -52,7 +52,7 @@ licence = "MIT OR Apache-2.0"
|
||||
licence_file = "LICENSE-MIT"
|
||||
kind = "translation"
|
||||
usage = "Czech UI strings, compiled in by crates/ui-egui/src/i18n/mod.rs"
|
||||
sha256 = "7e8158add249b105d85a398dd8b5ee573f9af6631ade6e4457799d9371be747e"
|
||||
sha256 = "cb4c53d7b938a5ec8eb3a001a6c385c60b84f9f1ac36240c490d164046757c2a"
|
||||
|
||||
[[asset]]
|
||||
path = "crates/ui-egui/src/i18n/pt-br.tsv"
|
||||
@@ -63,7 +63,7 @@ licence = "MIT OR Apache-2.0"
|
||||
licence_file = "LICENSE-MIT"
|
||||
kind = "translation"
|
||||
usage = "Brazilian Portuguese UI strings, compiled in by crates/ui-egui/src/i18n/mod.rs"
|
||||
sha256 = "4b3520cb42f50e3ac221c1ccf40e86f955e900f16f5b3251b54f80b9d068df81"
|
||||
sha256 = "af4b798c568cb1bb44ef23700e2d69c1e91c7cbb81e6fb565079a797cf02c878"
|
||||
|
||||
[[asset]]
|
||||
path = "crates/ui-egui/src/i18n/es.tsv"
|
||||
@@ -74,7 +74,7 @@ licence = "MIT OR Apache-2.0"
|
||||
licence_file = "LICENSE-MIT"
|
||||
kind = "translation"
|
||||
usage = "Spanish UI strings, compiled in by crates/ui-egui/src/i18n/mod.rs"
|
||||
sha256 = "b6f566905f14d7669d8c220c5cd84886abe4b6edfa8cbdd213350f4ad1923e7a"
|
||||
sha256 = "8fe572236493148b23270ef5766ad1c7d65a58b293757f34772d01a44a2df026"
|
||||
|
||||
[[asset]]
|
||||
path = "crates/ui-egui/src/i18n/fr.tsv"
|
||||
@@ -85,7 +85,7 @@ licence = "MIT OR Apache-2.0"
|
||||
licence_file = "LICENSE-MIT"
|
||||
kind = "translation"
|
||||
usage = "French UI strings, compiled in by crates/ui-egui/src/i18n/mod.rs"
|
||||
sha256 = "383a20170ea9483c032fc40979b5b5bbd0d38b1af29b4d9153c68f2280ecb576"
|
||||
sha256 = "6af18efaa6fc8d7d9e813b4411380f1f47879c3e342d800540abec5cd6cb8f81"
|
||||
|
||||
[[asset]]
|
||||
path = "crates/ui-egui/src/i18n/de.tsv"
|
||||
@@ -96,7 +96,7 @@ licence = "MIT OR Apache-2.0"
|
||||
licence_file = "LICENSE-MIT"
|
||||
kind = "translation"
|
||||
usage = "German UI strings, compiled in by crates/ui-egui/src/i18n/mod.rs"
|
||||
sha256 = "6f0852d52d2498b1b7713dbb67b34584f365c1ec9504964f8da28c40e1875d70"
|
||||
sha256 = "2b7787232635373d44b16b93051763b01cf8fa9e6877c87c013ad42171fdc915"
|
||||
|
||||
[[asset]]
|
||||
path = "crates/ui-egui/src/i18n/te.tsv"
|
||||
@@ -107,7 +107,7 @@ licence = "MIT OR Apache-2.0"
|
||||
licence_file = "LICENSE-MIT"
|
||||
kind = "translation"
|
||||
usage = "Telugu UI strings, compiled in by crates/ui-egui/src/i18n/mod.rs"
|
||||
sha256 = "a52bad8366e4911d49deb1ba0f29f8844ae24eac372a1f0040eb1a4909dc32f3"
|
||||
sha256 = "9f67da0f5b455cf99be298e8318721ad6c8d306223e74ad42faf6edd2f8a839b"
|
||||
|
||||
[[asset]]
|
||||
path = "crates/ui-egui/src/i18n/it.tsv"
|
||||
@@ -118,7 +118,7 @@ licence = "MIT OR Apache-2.0"
|
||||
licence_file = "LICENSE-MIT"
|
||||
kind = "translation"
|
||||
usage = "Italian UI strings, compiled in by crates/ui-egui/src/i18n/mod.rs"
|
||||
sha256 = "c401a6505dadfa078cf45ee1c1fa834fe4aa21eb7656b641a10dd7da2613fd35"
|
||||
sha256 = "f7765338632fee507a907cbabc52f72d57d903839f8a4d48b34e2cdcbb28a3bc"
|
||||
|
||||
[[asset]]
|
||||
path = "crates/ui-egui/src/i18n/pl.tsv"
|
||||
@@ -129,7 +129,7 @@ licence = "MIT OR Apache-2.0"
|
||||
licence_file = "LICENSE-MIT"
|
||||
kind = "translation"
|
||||
usage = "Polish UI strings, compiled in by crates/ui-egui/src/i18n/mod.rs"
|
||||
sha256 = "a1e65941b372579a4f1bb63cac4d350620715357fd24e457a8e649ff611b5e25"
|
||||
sha256 = "62517afff28af384a42aa377b86582ecddfe8dc8453f06c481246e96184add59"
|
||||
|
||||
[[asset]]
|
||||
path = "crates/ui-egui/src/i18n/ru.tsv"
|
||||
@@ -140,7 +140,7 @@ licence = "MIT OR Apache-2.0"
|
||||
licence_file = "LICENSE-MIT"
|
||||
kind = "translation"
|
||||
usage = "Russian UI strings, compiled in by crates/ui-egui/src/i18n/mod.rs"
|
||||
sha256 = "518c3db5cfef1bd1f3cd6249b2faf783b2301d2a77931315a77e28bfab8250e3"
|
||||
sha256 = "d46ff4a0505c6374008d55fc4112d4a41508c333411551dad8f6102243bbcccd"
|
||||
|
||||
[[asset]]
|
||||
path = "crates/ui-egui/src/i18n/hu.tsv"
|
||||
@@ -151,7 +151,7 @@ licence = "MIT OR Apache-2.0"
|
||||
licence_file = "LICENSE-MIT"
|
||||
kind = "translation"
|
||||
usage = "Hungarian UI strings, compiled in by crates/ui-egui/src/i18n/mod.rs"
|
||||
sha256 = "c22f0dab633f832d0ed9d7ad9c97f5d1b636505144593917fc18bc4dff40458c"
|
||||
sha256 = "61f9efbc72c1e597cdb9a2892bb87e4d0b64c1a7736bc8f7d719e9f18c85da12"
|
||||
|
||||
[[asset]]
|
||||
path = "crates/ui-egui/src/i18n/bg.tsv"
|
||||
@@ -162,7 +162,7 @@ licence = "MIT OR Apache-2.0"
|
||||
licence_file = "LICENSE-MIT"
|
||||
kind = "translation"
|
||||
usage = "Bulgarian UI strings, compiled in by crates/ui-egui/src/i18n/mod.rs"
|
||||
sha256 = "90226cb9e54441a926da35eeaa3f8272dcf0b7da4e269ba5ccb37c0404291778"
|
||||
sha256 = "90fac37b3f4c69d16841fec2bc30b66aa3cd0964a493ebdac4f71e40dc424164"
|
||||
|
||||
[[asset]]
|
||||
path = "crates/ui-egui/src/i18n/kk.tsv"
|
||||
@@ -173,7 +173,7 @@ licence = "MIT OR Apache-2.0"
|
||||
licence_file = "LICENSE-MIT"
|
||||
kind = "translation"
|
||||
usage = "Kazakh UI strings, compiled in by crates/ui-egui/src/i18n/mod.rs"
|
||||
sha256 = "e0874fddf6833e6005604dbc16f4b9dbb72d07cff3ce18bb8cbece0fee2fc5e0"
|
||||
sha256 = "18c15dd98f6efe9929d6b00360dc6d15a44bbe6bfde044688bc911011868efeb"
|
||||
|
||||
[[asset]]
|
||||
path = "crates/ui-egui/src/i18n/ja.tsv"
|
||||
@@ -184,7 +184,7 @@ licence = "MIT OR Apache-2.0"
|
||||
licence_file = "LICENSE-MIT"
|
||||
kind = "translation"
|
||||
usage = "Japanese UI strings, compiled in by crates/ui-egui/src/i18n/mod.rs"
|
||||
sha256 = "1ae379d3bb19741c50e05a967f3b33f73d34df0b23a55257a04524c917c0a53d"
|
||||
sha256 = "07b222d5b3fdd155ba57cec323dc9ca290c6e01331bb32f7181f21728362d53b"
|
||||
|
||||
[[asset]]
|
||||
path = "crates/ui-egui/src/i18n/uk.tsv"
|
||||
@@ -195,7 +195,7 @@ licence = "MIT OR Apache-2.0"
|
||||
licence_file = "LICENSE-MIT"
|
||||
kind = "translation"
|
||||
usage = "Ukrainian UI strings, compiled in by crates/ui-egui/src/i18n/mod.rs"
|
||||
sha256 = "6efd057033876643b4a4a5a9179ad9c4291f6201c04c2cc7948f4d454e6f90e1"
|
||||
sha256 = "b15b5fdca526de6d39d4a22b0c4d54f13eb5df0691ef6c0ea5e4987122ea45be"
|
||||
|
||||
[[asset]]
|
||||
path = "crates/ui-egui/src/i18n/ar.tsv"
|
||||
@@ -206,7 +206,7 @@ licence = "MIT OR Apache-2.0"
|
||||
licence_file = "LICENSE-MIT"
|
||||
kind = "translation"
|
||||
usage = "Arabic UI strings, compiled in by crates/ui-egui/src/i18n/mod.rs"
|
||||
sha256 = "b929e99180a0fa23cdfb8c8fa77f11e458b9ef9adc269890792ac066f0f0713c"
|
||||
sha256 = "882c07204a95bef324f67f891e76dae0a1a499a420e07929490e6b7f62cf4487"
|
||||
|
||||
[[asset]]
|
||||
path = "crates/ui-egui/src/i18n/tr.tsv"
|
||||
@@ -217,7 +217,7 @@ licence = "MIT OR Apache-2.0"
|
||||
licence_file = "LICENSE-MIT"
|
||||
kind = "translation"
|
||||
usage = "Turkish UI strings, compiled in by crates/ui-egui/src/i18n/mod.rs"
|
||||
sha256 = "f46a9aa4c7b34ef97d5f0fa7dc93ce36cdece9498a8bf51cd83fecf002b98b6e"
|
||||
sha256 = "7afdd36b96ac5b9c4c1023f506b98af9c559fe85ea00eb7e9518eda9fe77850b"
|
||||
|
||||
[[asset]]
|
||||
path = "crates/ui-egui/src/i18n/lt.tsv"
|
||||
@@ -228,7 +228,7 @@ licence = "MIT OR Apache-2.0"
|
||||
licence_file = "LICENSE-MIT"
|
||||
kind = "translation"
|
||||
usage = "Lithuanian UI strings, compiled in by crates/ui-egui/src/i18n/mod.rs"
|
||||
sha256 = "49275046f26850714e87a4c862cd0cac8eee175a39ec839f6b348e1e3ccc6bef"
|
||||
sha256 = "6ed886d00ad8cd39d8bf254f4733c8b8c90d5bf2c6868ff9c4ca42765a148786"
|
||||
|
||||
|
||||
[[asset]]
|
||||
@@ -3352,7 +3352,7 @@ licence = "MIT OR Apache-2.0"
|
||||
licence_file = "LICENSE-MIT"
|
||||
kind = "translation"
|
||||
usage = "Vietnamese UI strings, compiled in by crates/ui-egui/src/i18n/mod.rs"
|
||||
sha256 = "31fbec695e02ea651daae01f2673a5dadfc1430080f2adb2c6d441bc06900cf4"
|
||||
sha256 = "2c352743eaeec21eb9e522c71c43f3f6df34b81f024a5c72c85332e2ecc2b338"
|
||||
|
||||
[[asset]]
|
||||
path = "crates/ui-egui/src/i18n/sl.tsv"
|
||||
@@ -3363,7 +3363,7 @@ licence = "MIT OR Apache-2.0"
|
||||
licence_file = "LICENSE-MIT"
|
||||
kind = "translation"
|
||||
usage = "Slovene UI strings, compiled in by crates/ui-egui/src/i18n/mod.rs"
|
||||
sha256 = "cd4d613d1e8d9b5cc1bc82c5a9c35968048319027b0470d1c644c6a3bc617243"
|
||||
sha256 = "a212a56fd316e58349845c750e935b28ba5074b3fd096016c3ae92cbe502648f"
|
||||
|
||||
[[asset]]
|
||||
|
||||
|
||||
@@ -172,6 +172,7 @@ Ranked; detail and the full milestone table in [docs/roadmap.md](docs/roadmap.md
|
||||
|
||||
## Progress log
|
||||
|
||||
- **2026-10-20 (M6, calculation order page):** Prepare a form ▸ Calculation order, a page of its own, lists the calculated fields in the order they calculate with their formulas and values, moved with Up/Down arrows (as Acrobat's Set Field Calculation Order), Alt+↑/↓ or by dragging. A card says what is wrong with the order and holds Fix order; a loop has a card of its own that opens one of its formulas. On the page, each calculated field shows its step, and arrows show what the field in focus reads and what reads it. Estimates unchanged.
|
||||
- **2026-10-20 (M6, calculation order):** The order a form's fields calculate in (`/CO`) is read, checked, fixed and set headlessly with `form_calculation_order`: it says which fields read one calculated later (they show stale values), which read each other in a loop, and which the PDF's order leaves out; Fix order moves only what must move, in one undo step, and the form recalculates. Editing a formula no longer moves its field to the end of the order, and a field the order lists twice calculates once. Estimates unchanged.
|
||||
- **2026-10-19 (M6, renames keep formulas):** Renaming a field renames it in every calculation that reads it, in the same undo step: `AFSimple_Calculate` field lists, simplified field notation (the comment and the JavaScript after it) and `getField` calls naming it in one string literal; the rest of each script is kept as written. A sum used to drop the renamed field, notation read it as 0 and a script kept a stale value. Field Properties says how many formulas changed and `form_set_props` lists them as `formulas_updated`. Names built at run time and other events' scripts are not rewritten. Estimates unchanged.
|
||||
|
||||
|
||||
@@ -411,6 +411,7 @@ pub fn tools() -> Vec<ToolDef> {
|
||||
&["doc"],
|
||||
)),
|
||||
t("form_calculation_order", "Read or set the calculation order", "The calculated fields in the order they calculate (Acrobat: Set Field Calculation Order), each with the fields its formula reads (`reads`; a script's names built at run time aren't known) and its `issues`: runs_too_early (it reads `field`, which calculates after it, so it shows a stale value), cycle (it reads `fields`, which read it back: no order fixes that, a formula has to change) and not_in_order (the PDF's order leaves it out, so other viewers may not calculate it). `extra` lists entries of the PDF's order that calculate nothing. Without a change it only reads. Changes, one at a time: `order` (these fields first, in this order, then the other calculated fields in their order), `field` with `move` earlier|later (one place), or `fix` true (only what must move moves, so every field calculates after the fields it reads, and the extra entries go). A change recalculates the form. Undoable.")
|
||||
.cmd("form.calculation_order")
|
||||
.with(schema(
|
||||
json!({ "doc": doc(), "order": { "type": "array", "items": { "type": "string" } }, "field": { "type": "string" }, "move": { "type": "string", "enum": ["earlier", "later"] }, "fix": { "type": "boolean" } }),
|
||||
&["doc"],
|
||||
|
||||
@@ -3889,6 +3889,9 @@ fn the_calculation_order_is_read_fixed_and_set() {
|
||||
assert_eq!(r["fields"][3]["issues"], json!([{ "issue": "cycle", "fields": ["y"] }]));
|
||||
assert_eq!((r["fixable"].clone(), r["extra"].clone()), (json!(true), json!([])));
|
||||
assert!(r.get("undo").is_none(), "reading changes nothing");
|
||||
// Prepare a form ▸ Calculation order is this tool headlessly.
|
||||
let r = ok(&mut a, "command_run", json!({ "id": "form.calculation_order", "params": { "doc": doc } }));
|
||||
assert_eq!(r["calculation_order"], json!(["total", "tax", "sub", "x", "y"]));
|
||||
let r = ok(&mut a, "form_calculation_order", json!({ "doc": doc, "fix": true }));
|
||||
assert_eq!(r["calculation_order"], json!(["sub", "tax", "total", "x", "y"]), "only what must move moves; the loop stays");
|
||||
assert_eq!(r["undo"], "Set calculation order");
|
||||
|
||||
@@ -347,6 +347,7 @@ pub static TOOL_GROUPS: &[ToolGroup] = &[
|
||||
item("Field properties", "settings-2", "form.field.properties", Ready),
|
||||
item("Tab order by rows", "rows-3", "form.tab_order.row", Ready),
|
||||
item("Tab order by columns", "columns-3", "form.tab_order.column", Ready),
|
||||
item("Calculation order", "list-ordered", "form.calculation_order", Ready),
|
||||
item("Flatten form fields", "layers", "form.flatten", Ready),
|
||||
item("Import data", "file-input", "form.import_data", Ready),
|
||||
item("Export data", "file-output", "form.export_data", Ready),
|
||||
|
||||
@@ -275,6 +275,7 @@ pub const COMMANDS: &[CommandSpec] = &[
|
||||
c("form.tab_order.row", "Tab order: by rows", None, None, HasFields, "rows-3"),
|
||||
c("form.tab_order.column", "Tab order: by columns", None, None, HasFields, "columns-3"),
|
||||
c("form.tab_order.structure", "Tab order: by document structure", None, None, HasFields, "list"),
|
||||
c("form.calculation_order", "Calculation order", None, None, Document, "list-ordered"),
|
||||
c("edit.text", "Add text", None, None, Modification, "type"),
|
||||
c("edit.edit_text", "Edit text & images", None, None, Modification, "text-cursor-input"),
|
||||
c("edit.link", "Add or edit links", None, None, Modification, "link-2"),
|
||||
|
||||
@@ -0,0 +1,956 @@
|
||||
//! Prepare a form ▸ Calculation order, a page of the left panel, and what it shows on the page.
|
||||
//!
|
||||
//! The panel: a card that says whether the order is right and what Fix order does, a card for
|
||||
//! each loop, and the calculated fields in the order they calculate, each with its formula, the
|
||||
//! value it shows and what is wrong with its place. A field moves by dragging, with the arrows of
|
||||
//! the selected field (Acrobat's Set Field Calculation Order has Up and Down), or with Alt+↑/↓.
|
||||
//! Every change is one undoable edit.
|
||||
//!
|
||||
//! The page: each calculated field's step in the order, and for the field in focus (under the
|
||||
//! pointer in the list or on the page, else the selected one) arrows from the fields it reads and
|
||||
//! to the fields that read it.
|
||||
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use std::sync::Arc;
|
||||
|
||||
use egui::{Align2, Color32, CornerRadius, Pos2, Rect, Sense, Shape, Stroke, Vec2, pos2, vec2};
|
||||
use pdfcraft_engine::form_scripts::{CalcOp, Calculate, format_value};
|
||||
use pdfcraft_engine::{CalculatedField, CalculationIssue, CalculationOrder, Edit, FormField, FormFieldKind};
|
||||
use pdfcraft_render::DocInfo;
|
||||
|
||||
use crate::canvas::PageXform;
|
||||
use crate::theme::{self, Tokens};
|
||||
use crate::{LeftPanel, PdfCraftApp, icons, widgets};
|
||||
|
||||
/// Links and steps on the page, which is paper white in either theme.
|
||||
const LINK_OK: Color32 = Color32::from_rgb(0x1B, 0x63, 0xE0);
|
||||
const LINK_LATE: Color32 = Color32::from_rgb(0xA8, 0x64, 0x00);
|
||||
const LINK_LOOP: Color32 = Color32::from_rgb(0xC2, 0x26, 0x2E);
|
||||
const STEP: Color32 = Color32::from_rgb(0x3A, 0x3A, 0x42);
|
||||
const ROW: f32 = 46.0;
|
||||
/// Links kept at most: a formula reading a group reads every field under it.
|
||||
const MAX_LINKS: usize = 20_000;
|
||||
/// Names a sentence lists before it stops with "…".
|
||||
const MAX_NAMES: usize = 6;
|
||||
/// Loop cards shown at most.
|
||||
const MAX_LOOPS: usize = 5;
|
||||
/// Fields too early that the card names one by one.
|
||||
const MAX_LATE: usize = 3;
|
||||
|
||||
/// How a field's place in the order, or a link between two fields, stands.
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||
enum Tone {
|
||||
Ok,
|
||||
/// It calculates before a field it reads, so it uses that field's old value.
|
||||
Late,
|
||||
/// Its formula reads its own result through other formulas.
|
||||
Loop,
|
||||
}
|
||||
|
||||
/// A view's calculation order, read again only after an edit (filling a field in is one), and
|
||||
/// what the pointer is over.
|
||||
#[derive(Clone, Debug, Default)]
|
||||
pub struct CalcOrderView {
|
||||
cache: Option<(u64, Arc<Listed>)>,
|
||||
/// The field whose row is under the pointer, this frame.
|
||||
hover_row: Option<String>,
|
||||
/// The field under the pointer on the page, last frame.
|
||||
hover_page: Option<String>,
|
||||
/// Links on page is off.
|
||||
hide_links: bool,
|
||||
/// The selected field the list last scrolled to, so a new selection (on the page too) brings
|
||||
/// its row into view once.
|
||||
scrolled_to: Option<String>,
|
||||
}
|
||||
|
||||
/// The calculation order with what the panel and the page show of it.
|
||||
#[derive(Debug)]
|
||||
struct Listed {
|
||||
order: CalculationOrder,
|
||||
/// One per field of the order, in its order.
|
||||
rows: Vec<Row>,
|
||||
/// From each field a formula reads to the calculated field that reads it.
|
||||
links: Vec<Link>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct Row {
|
||||
/// The value as the field shows it (its format applied), on one line.
|
||||
value: String,
|
||||
/// The formula on one line: the Calculate tab's, or a script's first line.
|
||||
formula: String,
|
||||
script: bool,
|
||||
tone: Tone,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
struct Link {
|
||||
from: String,
|
||||
to: String,
|
||||
tone: Tone,
|
||||
}
|
||||
|
||||
impl CalcOrderView {
|
||||
fn listed(&mut self, doc: &pdfcraft_engine::Document) -> Arc<Listed> {
|
||||
let generation = doc.edit_generation();
|
||||
if let Some(listed) = self.current(generation) {
|
||||
return listed;
|
||||
}
|
||||
let order = doc.calculation_order();
|
||||
let rows = rows(&order.fields, &doc.form);
|
||||
let names: Vec<&str> = doc.form.iter().map(|f| f.name.as_str()).collect();
|
||||
let links = links(&order.fields, names);
|
||||
let listed = Arc::new(Listed { order, rows, links });
|
||||
self.cache = Some((generation, listed.clone()));
|
||||
listed
|
||||
}
|
||||
|
||||
/// The order read at `generation`, if it was.
|
||||
fn current(&self, generation: u64) -> Option<Arc<Listed>> {
|
||||
self.cache.as_ref().filter(|(g, _)| *g == generation).map(|(_, listed)| listed.clone())
|
||||
}
|
||||
|
||||
/// The field under the pointer on the page, for the next frame.
|
||||
pub(crate) fn set_hover_page(&mut self, name: Option<String>) {
|
||||
self.hover_page = name;
|
||||
}
|
||||
|
||||
/// The field whose links show: under the pointer in the list or on the page, else selected.
|
||||
fn focus(&self, selected: Option<&str>) -> Option<String> {
|
||||
self.hover_row.clone().or_else(|| self.hover_page.clone()).or_else(|| selected.map(str::to_owned))
|
||||
}
|
||||
}
|
||||
|
||||
fn tone(issues: &[CalculationIssue]) -> Tone {
|
||||
if issues.iter().any(|i| matches!(i, CalculationIssue::Cycle { .. })) {
|
||||
Tone::Loop
|
||||
} else if issues.iter().any(|i| matches!(i, CalculationIssue::RunsTooEarly { .. })) {
|
||||
Tone::Late
|
||||
} else {
|
||||
Tone::Ok
|
||||
}
|
||||
}
|
||||
|
||||
/// `text` on one line, cut at 200 characters.
|
||||
fn one_line(text: &str) -> String {
|
||||
text.split_whitespace().collect::<Vec<_>>().join(" ").chars().take(200).collect()
|
||||
}
|
||||
|
||||
/// Each calculated field's value, formula and standing, in the order's order.
|
||||
fn rows(calculated: &[CalculatedField], form: &[FormField]) -> Vec<Row> {
|
||||
let mut by_name: HashMap<&str, &FormField> = HashMap::with_capacity(form.len());
|
||||
for f in form {
|
||||
by_name.entry(f.name.as_str()).or_insert(f);
|
||||
}
|
||||
calculated
|
||||
.iter()
|
||||
.map(|c| {
|
||||
let field = by_name.get(c.name.as_str());
|
||||
let value = match field {
|
||||
Some(f) if f.kind == FormFieldKind::Text => f.value.first().map(|v| format_value(&f.actions.format, v)).unwrap_or_default(),
|
||||
Some(f) => f.display_value(),
|
||||
None => String::new(),
|
||||
};
|
||||
let (formula, script) = match field.map(|f| (&f.actions.calculate, f.actions.scripts.calculate.as_deref())) {
|
||||
Some((Calculate::Simple { op, fields }, _)) => {
|
||||
let op = match op {
|
||||
CalcOp::Sum => "sum",
|
||||
CalcOp::Product => "product",
|
||||
CalcOp::Average => "average",
|
||||
CalcOp::Minimum => "min",
|
||||
CalcOp::Maximum => "max",
|
||||
};
|
||||
(format!("= {op}({})", fields.join(", ")), false)
|
||||
}
|
||||
Some((Calculate::Notation(n), _)) => (format!("= {}", one_line(n)), false),
|
||||
Some((Calculate::None, Some(js))) => (js.lines().map(str::trim).find(|l| !l.is_empty()).map(one_line).unwrap_or_default(), true),
|
||||
_ => (String::new(), false),
|
||||
};
|
||||
Row { value: one_line(&value), formula, script, tone: tone(&c.issues) }
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
/// The links between the form's fields (`names`): a formula's read name finds the field of that
|
||||
/// name and the fields under it, as the calculation looks values up. At most [`MAX_LINKS`].
|
||||
fn links(calculated: &[CalculatedField], mut names: Vec<&str>) -> Vec<Link> {
|
||||
names.sort_unstable();
|
||||
names.dedup();
|
||||
let mut out = Vec::new();
|
||||
for c in calculated {
|
||||
let mut seen = HashSet::new();
|
||||
for read in &c.reads {
|
||||
let prefix = format!("{read}.");
|
||||
let exact = names.partition_point(|n| *n < read.as_str());
|
||||
let under = names.partition_point(|n| *n < prefix.as_str());
|
||||
let same = names.get(exact..).unwrap_or_default().iter().take_while(|n| **n == read.as_str());
|
||||
let below = names.get(under..).unwrap_or_default().iter().take_while(|n| n.starts_with(&prefix));
|
||||
for &from in same.chain(below) {
|
||||
if out.len() >= MAX_LINKS {
|
||||
return out;
|
||||
}
|
||||
if !seen.insert(from) {
|
||||
continue;
|
||||
}
|
||||
let tone = if c.issues.iter().any(|i| matches!(i, CalculationIssue::Cycle { fields } if fields.iter().any(|x| x == from))) {
|
||||
Tone::Loop
|
||||
} else if c.issues.iter().any(|i| matches!(i, CalculationIssue::RunsTooEarly { field } if field == from)) {
|
||||
Tone::Late
|
||||
} else {
|
||||
Tone::Ok
|
||||
};
|
||||
out.push(Link { from: from.to_owned(), to: c.name.clone(), tone });
|
||||
}
|
||||
}
|
||||
}
|
||||
out
|
||||
}
|
||||
|
||||
/// The loops: the fields that read each other, each loop in the order's order.
|
||||
fn loops(calculated: &[CalculatedField]) -> Vec<Vec<&str>> {
|
||||
let index: HashMap<&str, usize> = calculated.iter().enumerate().map(|(k, f)| (f.name.as_str(), k)).collect();
|
||||
// Each field points at an earlier field of its loop, and a loop's first field at itself.
|
||||
let mut first: Vec<usize> = (0..calculated.len()).collect();
|
||||
let root = |first: &[usize], mut k: usize| {
|
||||
// Every step goes to an earlier field, so there are fewer steps than fields.
|
||||
for _ in 0..first.len() {
|
||||
match first.get(k) {
|
||||
Some(&p) if p != k => k = p,
|
||||
_ => break,
|
||||
}
|
||||
}
|
||||
k
|
||||
};
|
||||
for (k, f) in calculated.iter().enumerate() {
|
||||
for issue in &f.issues {
|
||||
if let CalculationIssue::Cycle { fields } = issue {
|
||||
for j in fields.iter().filter_map(|x| index.get(x.as_str()).copied()) {
|
||||
let (a, b) = (root(&first, k), root(&first, j));
|
||||
if let Some(p) = first.get_mut(a.max(b)) {
|
||||
*p = a.min(b);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
let mut groups: Vec<(usize, Vec<&str>)> = Vec::new();
|
||||
for (k, f) in calculated.iter().enumerate().filter(|(_, f)| tone(&f.issues) == Tone::Loop) {
|
||||
let r = root(&first, k);
|
||||
match groups.iter_mut().find(|(g, _)| *g == r) {
|
||||
Some((_, names)) => names.push(&f.name),
|
||||
None => groups.push((r, vec![&f.name])),
|
||||
}
|
||||
}
|
||||
groups.into_iter().map(|(_, names)| names).collect()
|
||||
}
|
||||
|
||||
/// Names in a sentence: "a, b and c", cut with "…" after [`MAX_NAMES`].
|
||||
fn names(list: &[&str]) -> String {
|
||||
match list {
|
||||
[] => String::new(),
|
||||
[one] => (*one).to_owned(),
|
||||
_ if list.len() > MAX_NAMES => format!("{}, …", list.iter().take(MAX_NAMES).copied().collect::<Vec<_>>().join(", ")),
|
||||
[rest @ .., last] => crate::i18n::fmt(tl!("{names} and {last}"), &[("names", &rest.join(", ")), ("last", *last)]),
|
||||
}
|
||||
}
|
||||
|
||||
/// What the focused field reads and what reads it: "total reads sub and tax · No field reads it".
|
||||
fn trace(links: &[Link], focus: &str) -> String {
|
||||
let mut reads: Vec<&str> = Vec::new();
|
||||
let mut read_by: Vec<&str> = Vec::new();
|
||||
for l in links {
|
||||
if l.to == focus && !reads.contains(&l.from.as_str()) {
|
||||
reads.push(&l.from);
|
||||
}
|
||||
if l.from == focus && !read_by.contains(&l.to.as_str()) {
|
||||
read_by.push(&l.to);
|
||||
}
|
||||
}
|
||||
let reads = if reads.is_empty() {
|
||||
crate::i18n::fmt(tl!("{field} reads no other field"), &[("field", focus)])
|
||||
} else {
|
||||
crate::i18n::fmt(tl!("{field} reads {fields}"), &[("field", focus), ("fields", &names(&reads))])
|
||||
};
|
||||
let read_by = if read_by.is_empty() {
|
||||
tl!("No field reads it").to_owned()
|
||||
} else {
|
||||
let template = crate::i18n::trn(crate::i18n::current(), read_by.len() as u64, "{fields} reads it", "{fields} read it");
|
||||
crate::i18n::fmt(&template, &[("fields", &names(&read_by))])
|
||||
};
|
||||
format!("{reads} · {read_by}")
|
||||
}
|
||||
|
||||
/// The colours of the cards and the steps in the list, for the theme.
|
||||
struct Palette {
|
||||
warn: (Color32, Color32, Color32, Color32),
|
||||
good: (Color32, Color32, Color32),
|
||||
looped: (Color32, Color32, Color32, Color32),
|
||||
/// A step's fill and number, and the caption colour, by tone.
|
||||
step_ok: (Color32, Color32),
|
||||
step_late: (Color32, Color32),
|
||||
step_loop: (Color32, Color32),
|
||||
}
|
||||
|
||||
impl Palette {
|
||||
/// Fill, border, title and text of each card; light and dark pass 4.5:1 for their text.
|
||||
fn new(dark: bool) -> Self {
|
||||
let c = Color32::from_rgb;
|
||||
if dark {
|
||||
Palette {
|
||||
warn: (c(0x3A, 0x2E, 0x17), c(0x6B, 0x53, 0x21), c(0xF2, 0xC2, 0x6B), c(0xE6, 0xD7, 0xB8)),
|
||||
good: (c(0x1D, 0x33, 0x26), c(0x2F, 0x5C, 0x40), c(0x8F, 0xD6, 0xA8)),
|
||||
looped: (c(0x3D, 0x20, 0x22), c(0x6E, 0x32, 0x36), c(0xF1, 0x9A, 0x9E), c(0xE9, 0xC9, 0xCB)),
|
||||
step_ok: (c(0x3A, 0x3A, 0x40), c(0xD4, 0xD4, 0xDA)),
|
||||
step_late: (c(0x4A, 0x3A, 0x1A), c(0xF2, 0xC2, 0x6B)),
|
||||
step_loop: (c(0x4A, 0x22, 0x24), c(0xF1, 0x9A, 0x9E)),
|
||||
}
|
||||
} else {
|
||||
Palette {
|
||||
warn: (c(0xFF, 0xF6, 0xE5), c(0xF2, 0xD9, 0xA6), c(0x8A, 0x51, 0x00), c(0x4A, 0x3A, 0x1E)),
|
||||
good: (c(0xEE, 0xF8, 0xF1), c(0xBF, 0xE3, 0xCC), c(0x1E, 0x6B, 0x3C)),
|
||||
looped: (c(0xFD, 0xF0, 0xF0), c(0xF1, 0xC4, 0xC6), c(0xA8, 0x1E, 0x25), c(0x5A, 0x2A, 0x2D)),
|
||||
step_ok: (c(0xED, 0xED, 0xF0), c(0x3A, 0x3A, 0x42)),
|
||||
step_late: (c(0xFF, 0xF0, 0xD6), c(0x8A, 0x51, 0x00)),
|
||||
step_loop: (c(0xFD, 0xE8, 0xE8), c(0xC2, 0x26, 0x2E)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn step(&self, tone: Tone) -> (Color32, Color32) {
|
||||
match tone {
|
||||
Tone::Ok => self.step_ok,
|
||||
Tone::Late => self.step_late,
|
||||
Tone::Loop => self.step_loop,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A field being dragged to a new place: its place now.
|
||||
#[derive(Clone, Copy)]
|
||||
struct Dragged(usize);
|
||||
|
||||
/// What the page asks for, done once it is drawn.
|
||||
enum Act {
|
||||
Order(Vec<String>),
|
||||
Undo,
|
||||
EditFormula(String),
|
||||
Select(String),
|
||||
}
|
||||
|
||||
/// A card: a tinted, outlined box as wide as the panel.
|
||||
fn card<R>(ui: &mut egui::Ui, fill: Color32, edge: Color32, add: impl FnOnce(&mut egui::Ui) -> R) -> R {
|
||||
egui::Frame::new()
|
||||
.fill(fill)
|
||||
.stroke(Stroke::new(1.0, edge))
|
||||
.corner_radius(CornerRadius::same(10))
|
||||
.inner_margin(egui::Margin::same(12))
|
||||
.show(ui, |ui| {
|
||||
ui.set_width(ui.available_width());
|
||||
ui.spacing_mut().item_spacing.y = 6.0;
|
||||
add(ui)
|
||||
})
|
||||
.inner
|
||||
}
|
||||
|
||||
/// A card's first line: its icon and title.
|
||||
fn card_title(ui: &mut egui::Ui, icon: &str, title: &str, colour: Color32) {
|
||||
ui.horizontal_top(|ui| {
|
||||
let (r, _) = ui.allocate_exact_size(vec2(16.0, 17.0), Sense::hover());
|
||||
icons::paint(ui, r, icon, 15.0, colour);
|
||||
ui.add(egui::Label::new(egui::RichText::new(title).font(theme::semibold(13.0)).color(colour)).wrap());
|
||||
});
|
||||
}
|
||||
|
||||
fn card_text(ui: &mut egui::Ui, text: &str, colour: Color32) {
|
||||
ui.add(egui::Label::new(egui::RichText::new(text).font(theme::regular(12.0)).color(colour)).wrap());
|
||||
}
|
||||
|
||||
/// A word that acts: "Undo", "Edit total's formula".
|
||||
fn text_button(ui: &mut egui::Ui, text: &str, t: &Tokens) -> bool {
|
||||
let resp =
|
||||
ui.add(egui::Label::new(egui::RichText::new(text).font(theme::semibold(12.5)).color(t.accent_text)).selectable(false).sense(Sense::click()));
|
||||
theme::hand(resp).clicked()
|
||||
}
|
||||
|
||||
/// The cards above the list: what is wrong and Fix order, or that the order is right; and loops.
|
||||
fn cards(ui: &mut egui::Ui, t: &Tokens, pal: &Palette, order: &CalculationOrder, editable: bool, undo: bool) -> Option<Act> {
|
||||
let lang = crate::i18n::current();
|
||||
let mut act = None;
|
||||
// Each field that calculates too early, with the fields it reads that calculate later.
|
||||
let late: Vec<(&str, Vec<&str>)> = order
|
||||
.fields
|
||||
.iter()
|
||||
.map(|f| {
|
||||
let later = f.issues.iter().filter_map(|i| if let CalculationIssue::RunsTooEarly { field } = i { Some(field.as_str()) } else { None });
|
||||
(f.name.as_str(), later.collect::<Vec<_>>())
|
||||
})
|
||||
.filter(|(_, later)| !later.is_empty())
|
||||
.collect();
|
||||
let unlisted: Vec<&str> = order.fields.iter().filter(|f| !f.listed).map(|f| f.name.as_str()).collect();
|
||||
let loops = loops(&order.fields);
|
||||
if order.fixable() {
|
||||
let (fill, edge, title, text) = pal.warn;
|
||||
card(ui, fill, edge, |ui| {
|
||||
let heading = if late.is_empty() {
|
||||
tl!("The order saved in the PDF needs tidying").to_owned()
|
||||
} else {
|
||||
crate::i18n::trn(lang, late.len() as u64, "{n} field shows an old value", "{n} fields show old values")
|
||||
};
|
||||
card_title(ui, "triangle-alert", &heading, title);
|
||||
for (field, later) in late.iter().take(MAX_LATE) {
|
||||
let template = crate::i18n::trn(
|
||||
lang,
|
||||
later.len() as u64,
|
||||
"{field} calculates before {fields}, which it reads.",
|
||||
"{field} calculates before {fields}, which it reads.",
|
||||
);
|
||||
card_text(ui, &crate::i18n::fmt(&template, &[("field", field), ("fields", &names(later))]), text);
|
||||
}
|
||||
if late.len() > MAX_LATE {
|
||||
let more = (late.len() - MAX_LATE) as u64;
|
||||
card_text(ui, &crate::i18n::trn(lang, more, "{n} more field calculates too early.", "{n} more fields calculate too early."), text);
|
||||
}
|
||||
if !unlisted.is_empty() {
|
||||
let template = crate::i18n::trn(
|
||||
lang,
|
||||
unlisted.len() as u64,
|
||||
"{fields} is missing from the order saved in the PDF, so other PDF viewers may not calculate it.",
|
||||
"{fields} are missing from the order saved in the PDF, so other PDF viewers may not calculate them.",
|
||||
);
|
||||
card_text(ui, &crate::i18n::fmt(&template, &[("fields", &names(&unlisted))]), text);
|
||||
}
|
||||
if !order.extra.is_empty() {
|
||||
let note = crate::i18n::trn(
|
||||
lang,
|
||||
order.extra.len() as u64,
|
||||
"The calculation order has {n} entry that calculates nothing. Fix order removes it.",
|
||||
"The calculation order has {n} entries that calculate nothing. Fix order removes them.",
|
||||
);
|
||||
card_text(ui, ¬e, text);
|
||||
}
|
||||
ui.add_space(2.0);
|
||||
ui.horizontal(|ui| {
|
||||
let fix = ui.add_enabled_ui(editable, |ui| widgets::pill_button(ui, tl!("Fix order"), true)).inner;
|
||||
if fix.on_hover_text(tl!("Move only what must move, so every field calculates after the fields it reads.")).clicked() {
|
||||
act = Some(Act::Order(order.fixed()));
|
||||
}
|
||||
ui.add(egui::Label::new(egui::RichText::new(tl!("Moves only what must move")).font(theme::regular(11.5)).color(t.text_muted)).wrap());
|
||||
});
|
||||
});
|
||||
} else {
|
||||
let (fill, edge, colour) = pal.good;
|
||||
card(ui, fill, edge, |ui| {
|
||||
let said = if loops.is_empty() {
|
||||
tl!("Every field calculates after the fields it reads.")
|
||||
} else {
|
||||
tl!("Every field outside a loop calculates after the fields it reads.")
|
||||
};
|
||||
card_title(ui, "check", said, colour);
|
||||
if undo && text_button(ui, tl!("Undo"), t) {
|
||||
act = Some(Act::Undo);
|
||||
}
|
||||
});
|
||||
}
|
||||
for members in loops.iter().take(MAX_LOOPS) {
|
||||
let (fill, edge, title, text) = pal.looped;
|
||||
ui.add_space(6.0);
|
||||
card(ui, fill, edge, |ui| {
|
||||
let heading = match members.as_slice() {
|
||||
[one] => crate::i18n::fmt(tl!("{field} reads its own value"), &[("field", *one)]),
|
||||
_ => crate::i18n::fmt(tl!("{fields} read each other"), &[("fields", &names(members))]),
|
||||
};
|
||||
card_title(ui, "rotate-cw", &heading, title);
|
||||
card_text(ui, tl!("No order can fix a loop. Change one of the formulas."), text);
|
||||
if editable
|
||||
&& let Some(first) = members.first()
|
||||
&& text_button(ui, &crate::i18n::fmt(tl!("Edit {field}'s formula"), &[("field", first)]), t)
|
||||
{
|
||||
act = Some(Act::EditFormula((*first).to_owned()));
|
||||
}
|
||||
});
|
||||
}
|
||||
act
|
||||
}
|
||||
|
||||
/// Why a row is marked, for its tooltip.
|
||||
fn explained(issues: &[CalculationIssue]) -> String {
|
||||
issues
|
||||
.iter()
|
||||
.map(|i| match i {
|
||||
CalculationIssue::RunsTooEarly { field } => {
|
||||
crate::i18n::fmt(tl!("Reads {name}, which calculates later, so it shows an old value."), &[("name", field)])
|
||||
}
|
||||
CalculationIssue::Cycle { fields } => crate::i18n::fmt(
|
||||
tl!("Reads {names}, which read it back. No order can fix a loop: change one of the formulas."),
|
||||
&[("names", &fields.join(", "))],
|
||||
),
|
||||
CalculationIssue::NotInOrder => {
|
||||
tl!("Missing from the calculation order saved in the PDF: other PDF viewers may not calculate it.").to_owned()
|
||||
}
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
.join("\n")
|
||||
}
|
||||
|
||||
/// The Calculation order page; Back returns to Prepare a form.
|
||||
pub(crate) fn panel(app: &mut PdfCraftApp, ui: &mut egui::Ui, t: &Tokens) {
|
||||
let (back, close) = crate::panels::panel_header(ui, t, "Calculation order", Some(tl!("Back to Prepare a form")));
|
||||
if back {
|
||||
app.left = LeftPanel::Tool("form");
|
||||
}
|
||||
if close {
|
||||
app.left_open = false;
|
||||
}
|
||||
let Some((index, id)) = app.active_ids() else {
|
||||
ui.label(egui::RichText::new(tl!("Open a document first")).color(t.text_muted));
|
||||
return;
|
||||
};
|
||||
let Some(doc) = app.session.get(id) else { return };
|
||||
let Some(view) = app.views.get_mut(index) else { return };
|
||||
let listed = view.calc_order.listed(doc);
|
||||
let order = &listed.order;
|
||||
if order.fields.is_empty() && order.extra.is_empty() {
|
||||
ui.label(
|
||||
egui::RichText::new(tl!(
|
||||
"No field in this form calculates its value yet. Give a field a calculation on the Calculate tab of its properties, and it shows here."
|
||||
))
|
||||
.color(t.text_muted),
|
||||
);
|
||||
return;
|
||||
}
|
||||
let editable = doc.allows_modification();
|
||||
let pal = Palette::new(ui.visuals().dark_mode);
|
||||
let mut act = cards(ui, t, &pal, order, editable, doc.can_undo() == Some("Set calculation order"));
|
||||
|
||||
widgets::section_title(ui, tl!("Order · top calculates first"));
|
||||
let mut links_on = !view.calc_order.hide_links;
|
||||
|
||||
let names: Vec<&str> = order.fields.iter().map(|f| f.name.as_str()).collect();
|
||||
let moved = |from: usize, to: usize| -> Option<Act> {
|
||||
let mut next: Vec<String> = names.iter().map(|n| (*n).to_owned()).collect();
|
||||
(from != to && from < next.len() && to < next.len()).then(|| {
|
||||
let name = next.remove(from);
|
||||
next.insert(to, name);
|
||||
Act::Order(next)
|
||||
})
|
||||
};
|
||||
let selected = view.prepare.selected.as_ref().map(|(name, _)| name.clone());
|
||||
let place = selected.as_deref().and_then(|s| names.iter().position(|n| *n == s));
|
||||
// Alt+↑/↓ move the selected field, as in Combine files.
|
||||
let ctx = ui.ctx().clone();
|
||||
if editable
|
||||
&& let Some(k) = place
|
||||
&& !ctx.text_edit_focused()
|
||||
&& !egui::Popup::is_any_open(&ctx)
|
||||
&& ctx.memory(|m| m.top_modal_layer().is_none())
|
||||
{
|
||||
let (up, down) =
|
||||
ctx.input_mut(|i| (i.consume_key(egui::Modifiers::ALT, egui::Key::ArrowUp), i.consume_key(egui::Modifiers::ALT, egui::Key::ArrowDown)));
|
||||
if up && let Some(a) = k.checked_sub(1).and_then(|to| moved(k, to)) {
|
||||
act = Some(a);
|
||||
} else if down && let Some(a) = moved(k, k + 1) {
|
||||
act = Some(a);
|
||||
}
|
||||
}
|
||||
|
||||
let focus_page = view.calc_order.hover_page.clone();
|
||||
// A field selected since the last frame, whose row the list shows.
|
||||
let reveal = (selected != view.calc_order.scrolled_to).then(|| selected.clone()).flatten();
|
||||
view.calc_order.scrolled_to = selected.clone();
|
||||
let mut hover_row = None;
|
||||
let count = names.len();
|
||||
egui::ScrollArea::vertical().id_salt(("calc-order", id)).auto_shrink([false, false]).show(ui, |ui| {
|
||||
for (k, (f, row)) in order.fields.iter().zip(&listed.rows).enumerate() {
|
||||
let sense = if editable { Sense::click_and_drag() } else { Sense::click() };
|
||||
let (rect, resp) = ui.allocate_exact_size(vec2(ui.available_width(), ROW), sense);
|
||||
let is_selected = selected.as_deref() == Some(f.name.as_str());
|
||||
resp.widget_info(|| {
|
||||
let label = if row.value.is_empty() { format!("{}. {}", k + 1, f.name) } else { format!("{}. {}: {}", k + 1, f.name, row.value) };
|
||||
egui::WidgetInfo::selected(egui::WidgetType::Button, true, is_selected, label)
|
||||
});
|
||||
if reveal.as_deref() == Some(f.name.as_str()) {
|
||||
resp.scroll_to_me(Some(egui::Align::Center));
|
||||
}
|
||||
let pointed = ui.rect_contains_pointer(rect);
|
||||
if pointed {
|
||||
hover_row = Some(f.name.clone());
|
||||
}
|
||||
let visible = ui.is_rect_visible(rect);
|
||||
// The arrows' column, kept for every row so nothing moves when they show.
|
||||
let arrows_x = rect.right() - 26.0;
|
||||
if visible {
|
||||
let press = theme::Press::track(ui, &resp);
|
||||
if !is_selected && focus_page.as_deref() == Some(f.name.as_str()) {
|
||||
ui.painter().rect_filled(rect, CornerRadius::same(8), t.hover);
|
||||
}
|
||||
press.wash(ui, rect, 8, is_selected);
|
||||
let body = rect.translate(press.offset());
|
||||
let (fill, number) = pal.step(row.tone);
|
||||
let step = pos2(body.left() + 19.0, body.center().y);
|
||||
ui.painter().circle_filled(step, 11.0, fill);
|
||||
ui.painter().text(step, Align2::CENTER_CENTER, (k + 1).to_string(), theme::semibold(11.0), number);
|
||||
let top = body.top() + 15.0;
|
||||
let bottom = body.top() + 31.0;
|
||||
let text_x = body.left() + 38.0;
|
||||
let value_end = arrows_x - 4.0;
|
||||
let caption = match row.tone {
|
||||
Tone::Loop => Some((tl!("Loop"), pal.step_loop.1)),
|
||||
Tone::Late => Some((tl!("Too early"), pal.step_late.1)),
|
||||
Tone::Ok if !f.listed => Some((tl!("Not in order"), pal.step_late.1)),
|
||||
Tone::Ok => None,
|
||||
};
|
||||
let value_font = theme::medium(13.0);
|
||||
let value = widgets::fit_line(&row.value, (value_end - text_x) * 0.4, |s| widgets::text_width(ui, s, &value_font));
|
||||
let value_w = widgets::text_width(ui, &value, &value_font);
|
||||
let value_colour = if row.tone == Tone::Late { pal.step_late.1 } else { t.text };
|
||||
ui.painter().text(pos2(value_end, top), Align2::RIGHT_CENTER, value, value_font, value_colour);
|
||||
let caption_w = caption.map_or(0.0, |(c, colour)| {
|
||||
let font = theme::semibold(10.5);
|
||||
let w = widgets::text_width(ui, c, &font);
|
||||
ui.painter().text(pos2(value_end, bottom), Align2::RIGHT_CENTER, c, font, colour);
|
||||
w
|
||||
});
|
||||
let room = (value_end - text_x - value_w.max(caption_w) - 10.0).max(0.0);
|
||||
let name_font = theme::medium(13.0);
|
||||
let tag = row.script.then(|| (tl!("Script"), widgets::text_width(ui, tl!("Script"), &theme::semibold(9.5)) + 8.0));
|
||||
let name_room = (room - tag.map_or(0.0, |(_, w)| w + 6.0)).max(0.0);
|
||||
widgets::paint_left(ui, pos2(text_x, top), &f.name, name_font.clone(), t.text, name_room);
|
||||
if let Some((label, w)) = tag {
|
||||
let x = text_x + widgets::text_width(ui, &f.name, &name_font).min(name_room) + 6.0;
|
||||
let chip = Rect::from_min_size(pos2(x, top - 7.5), vec2(w, 15.0));
|
||||
ui.painter().rect_stroke(chip, CornerRadius::same(4), Stroke::new(1.0, t.border), egui::StrokeKind::Inside);
|
||||
ui.painter().text(chip.center(), Align2::CENTER_CENTER, label, theme::semibold(9.5), t.text_muted);
|
||||
}
|
||||
widgets::paint_left(ui, pos2(text_x, bottom), &row.formula, egui::FontId::monospace(11.0), t.text_muted, room);
|
||||
}
|
||||
// The selected field's arrows, or the one under the pointer.
|
||||
if editable && (is_selected || pointed) {
|
||||
let up = Rect::from_min_size(pos2(arrows_x, rect.top() + 3.0), vec2(24.0, 19.0));
|
||||
let down = Rect::from_min_size(pos2(arrows_x, rect.bottom() - 22.0), vec2(24.0, 19.0));
|
||||
for (r, icon, earlier, tip) in
|
||||
[(up, "chevron-up", true, tl!("Earlier in calculation order")), (down, "chevron-down", false, tl!("Later in calculation order"))]
|
||||
{
|
||||
let to = if earlier { k.checked_sub(1) } else { Some(k + 1).filter(|&to| to < count) };
|
||||
let b = ui.interact(r, ui.id().with(("calc-order", k, earlier)), if to.is_some() { Sense::click() } else { Sense::hover() });
|
||||
b.widget_info(|| egui::WidgetInfo::labeled(egui::WidgetType::Button, to.is_some(), format!("{tip}: {}", f.name)));
|
||||
if visible {
|
||||
let bpress = theme::Press::track(ui, &b);
|
||||
bpress.wash(ui, r, 4, false);
|
||||
icons::paint(ui, r.shrink(2.5).translate(bpress.offset()), icon, 14.0, if to.is_some() { t.icon } else { t.text_faint });
|
||||
}
|
||||
if theme::hand(b).on_hover_text(tip).clicked()
|
||||
&& let Some(a) = to.and_then(|to| moved(k, to))
|
||||
{
|
||||
act = Some(a);
|
||||
}
|
||||
}
|
||||
}
|
||||
if editable {
|
||||
resp.dnd_set_drag_payload(Dragged(k));
|
||||
if resp.dragged() {
|
||||
ui.ctx().set_cursor_icon(egui::CursorIcon::Grabbing);
|
||||
}
|
||||
// A field dragged over this one goes where the line is drawn.
|
||||
if let Some(from) = resp.dnd_hover_payload::<Dragged>().map(|d| d.0)
|
||||
&& from != k
|
||||
{
|
||||
let y = if from > k { rect.top() } else { rect.bottom() };
|
||||
ui.painter().hline(rect.x_range(), y, Stroke::new(2.0, t.accent));
|
||||
}
|
||||
if let Some(from) = resp.dnd_release_payload::<Dragged>().map(|d| d.0)
|
||||
&& let Some(a) = moved(from, k)
|
||||
{
|
||||
act = Some(a);
|
||||
}
|
||||
}
|
||||
let resp = theme::hand(resp);
|
||||
// The whole formula, then what is wrong; written only while the pointer is on it.
|
||||
let resp = if resp.hovered() {
|
||||
let why = [row.formula.clone(), explained(&f.issues)].into_iter().filter(|s| !s.is_empty()).collect::<Vec<_>>().join("\n\n");
|
||||
if why.is_empty() { resp } else { resp.on_hover_text(why) }
|
||||
} else {
|
||||
resp
|
||||
};
|
||||
if resp.clicked() {
|
||||
act = Some(Act::Select(f.name.clone()));
|
||||
}
|
||||
}
|
||||
ui.add_space(8.0);
|
||||
ui.add(widgets::checkbox(&mut links_on, egui::RichText::new(tl!("Links on page")).font(theme::regular(12.0)).color(t.text_muted)))
|
||||
.on_hover_text(tl!("Show on the page which fields each field reads"));
|
||||
if editable {
|
||||
ui.add_space(4.0);
|
||||
let (up, down) = if cfg!(target_os = "macos") { ("⌥↑", "⌥↓") } else { ("Alt+↑", "Alt+↓") };
|
||||
let hint = crate::i18n::fmt(tl!("Drag a field to move it, or select it and press {up} or {down}."), &[("up", up), ("down", down)]);
|
||||
ui.add(egui::Label::new(egui::RichText::new(hint).font(theme::regular(11.5)).color(t.text_faint)).wrap());
|
||||
}
|
||||
});
|
||||
view.calc_order.hover_row = hover_row;
|
||||
view.calc_order.hide_links = !links_on;
|
||||
match act {
|
||||
Some(Act::Order(names)) => {
|
||||
app.apply_edit(Edit::SetCalculationOrder { names });
|
||||
}
|
||||
Some(Act::Undo) => {
|
||||
app.execute("edit.undo");
|
||||
}
|
||||
Some(Act::EditFormula(name)) => {
|
||||
if let Some(view) = app.views.get_mut(index) {
|
||||
view.prepare.select((name.clone(), 0), false);
|
||||
}
|
||||
app.open_field_props(&name, 0);
|
||||
if let Some(d) = app.field_props.as_mut() {
|
||||
d.tab = crate::prepare::FieldTab::Calculate;
|
||||
}
|
||||
}
|
||||
Some(Act::Select(name)) => {
|
||||
// Where its first widget is, to show it there.
|
||||
let shown = app
|
||||
.session
|
||||
.get(id)
|
||||
.and_then(|doc| doc.form.iter().find(|g| g.name == name).and_then(|g| g.widgets.first()).and_then(|w| Some((w.page?, w.rect))));
|
||||
if let Some(view) = app.views.get_mut(index) {
|
||||
view.prepare.select((name, 0), false);
|
||||
if let Some((page, rect)) = shown {
|
||||
view.go_to_page(page);
|
||||
view.flash = Some((page, rect.map(|v| v as f32), 0.0));
|
||||
}
|
||||
}
|
||||
}
|
||||
None => {}
|
||||
}
|
||||
}
|
||||
|
||||
/// The calculation order on page `page`: the links of the field in focus, with the fields it has
|
||||
/// nothing to do with faded, and the steps of the focus and its linked fields; with nothing in
|
||||
/// focus, the steps of the fields whose place is wrong. A form with many calculations stays
|
||||
/// readable either way. Returns the field under the pointer.
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub(crate) fn paint_page(
|
||||
ui: &egui::Ui,
|
||||
painter: &egui::Painter,
|
||||
xf: &PageXform,
|
||||
page: usize,
|
||||
info: &DocInfo,
|
||||
form: &[FormField],
|
||||
view: &CalcOrderView,
|
||||
generation: u64,
|
||||
selected: Option<&str>,
|
||||
) -> Option<String> {
|
||||
let listed = view.current(generation)?;
|
||||
// Each field's first widget on this page.
|
||||
let mut on_page: Vec<(&str, Rect)> = Vec::new();
|
||||
for f in form {
|
||||
if let Some(w) = f.widgets.iter().find(|w| w.page == Some(page) && !w.hidden) {
|
||||
let r = w.rect;
|
||||
on_page.push((&f.name, xf.user_rect(info, page, [r[0] as f32, r[1] as f32, r[2] as f32, r[3] as f32])));
|
||||
}
|
||||
}
|
||||
if on_page.is_empty() {
|
||||
return None;
|
||||
}
|
||||
let pointer = ui.input(|i| i.pointer.hover_pos());
|
||||
let hovered = pointer.and_then(|p| on_page.iter().rev().find(|(_, r)| r.contains(p))).map(|(n, _)| (*n).to_owned());
|
||||
let at: HashMap<&str, Rect> = on_page.iter().copied().collect();
|
||||
let zoom = (xf.rect.width() / xf.pw.max(1.0)).clamp(0.5, 3.0);
|
||||
let focus = if view.hide_links { None } else { view.focus(selected) };
|
||||
// The focus's links, and the fields at either end of them (with the focus itself).
|
||||
let shown: Vec<&Link> = focus.as_deref().map(|f| listed.links.iter().filter(|l| l.from == f || l.to == f).collect()).unwrap_or_default();
|
||||
let related: Option<HashSet<&str>> = focus.as_deref().map(|f| shown.iter().flat_map(|l| [l.from.as_str(), l.to.as_str()]).chain([f]).collect());
|
||||
if let (Some(focus), Some(related)) = (focus.as_deref(), &related) {
|
||||
for (name, r) in &on_page {
|
||||
if !related.contains(name) {
|
||||
painter.rect_filled(r.expand(1.0), CornerRadius::ZERO, Color32::from_white_alpha(150));
|
||||
} else {
|
||||
let width = if *name == focus { 2.0 } else { 1.0 };
|
||||
painter.rect_stroke(r.expand(1.0), CornerRadius::same(2), Stroke::new(width, LINK_OK), egui::StrokeKind::Outside);
|
||||
}
|
||||
}
|
||||
for l in &shown {
|
||||
if let (Some(a), Some(b)) = (at.get(l.from.as_str()), at.get(l.to.as_str())) {
|
||||
arrow(painter, *a, *b, l.tone, zoom);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (k, (f, row)) in listed.order.fields.iter().zip(&listed.rows).enumerate() {
|
||||
let Some(r) = at.get(f.name.as_str()) else { continue };
|
||||
let shown = match &related {
|
||||
Some(related) => related.contains(f.name.as_str()),
|
||||
None => row.tone != Tone::Ok || !f.listed,
|
||||
};
|
||||
if !shown {
|
||||
continue;
|
||||
}
|
||||
let fill = match row.tone {
|
||||
Tone::Ok => STEP,
|
||||
Tone::Late => LINK_LATE,
|
||||
Tone::Loop => LINK_LOOP,
|
||||
};
|
||||
// No bigger than the field, so a small one keeps its contents in view.
|
||||
let radius = (8.0 * zoom).clamp(6.5, 10.0).min((r.height() * 0.6).max(5.0));
|
||||
let c = r.left_top();
|
||||
painter.circle(c, radius, fill, Stroke::new(1.5, Color32::WHITE));
|
||||
painter.text(c, Align2::CENTER_CENTER, (k + 1).to_string(), theme::semibold(radius * 1.1), Color32::WHITE);
|
||||
}
|
||||
hovered
|
||||
}
|
||||
|
||||
/// Where a ray from `r`'s centre in direction `dir` (a unit vector) leaves `r`.
|
||||
fn edge(r: Rect, dir: Vec2) -> Pos2 {
|
||||
let half = r.size() / 2.0;
|
||||
let along = |h: f32, d: f32| if d.abs() > 1e-6 { h / d.abs() } else { f32::INFINITY };
|
||||
r.center() + dir * along(half.x, dir.x).min(along(half.y, dir.y))
|
||||
}
|
||||
|
||||
/// An arrow from field `a` to field `b`: dashed when the value arrives too late, red in a loop.
|
||||
/// Fields one above the other link out to the right, and fields side by side over the top, clear
|
||||
/// of the fields between them (a grid's neighbours would otherwise get arrows too short to see).
|
||||
/// Other fields link between their nearest edges, bent a little to the arrow's left so the two
|
||||
/// arrows of a loop don't overlap. A field that reads itself gets a loop off its right edge.
|
||||
fn arrow(painter: &egui::Painter, a: Rect, b: Rect, tone: Tone, zoom: f32) {
|
||||
let colour = match tone {
|
||||
Tone::Ok => LINK_OK,
|
||||
Tone::Late => LINK_LATE,
|
||||
Tone::Loop => LINK_LOOP,
|
||||
};
|
||||
let stroke = Stroke::new(1.75, colour);
|
||||
let head = 9.0;
|
||||
let gap = b.center() - a.center();
|
||||
let overlap = |a0: f32, a1: f32, b0: f32, b1: f32| a1.min(b1) - a0.max(b0);
|
||||
let (start, c1, c2, end) = if gap.length() < 1.0 {
|
||||
let bow = 24.0 * zoom;
|
||||
let (start, end) = (pos2(a.right(), a.center().y - 4.0), pos2(a.right(), a.center().y + 4.0));
|
||||
(start, start + vec2(bow, -bow * 0.6), end + vec2(bow, bow * 0.6), end)
|
||||
} else if overlap(a.left(), a.right(), b.left(), b.right()) > 0.0 {
|
||||
let (start, end) = (pos2(a.right() + 2.0, a.center().y - 3.0), pos2(b.right() + 2.0, b.center().y + 3.0));
|
||||
let bow = (18.0 * zoom + (end.y - start.y).abs() * 0.3).min(140.0);
|
||||
(start, start + vec2(bow, 0.0), end + vec2(bow, 0.0), end)
|
||||
} else if overlap(a.top(), a.bottom(), b.top(), b.bottom()) > 0.0 {
|
||||
let (start, end) = (pos2(a.center().x - 3.0, a.top() - 2.0), pos2(b.center().x + 3.0, b.top() - 2.0));
|
||||
let bow = (14.0 * zoom + (end.x - start.x).abs() * 0.25).min(100.0);
|
||||
(start, start - vec2(0.0, bow), end - vec2(0.0, bow), end)
|
||||
} else {
|
||||
let dir = gap / gap.length();
|
||||
let (start, end) = (edge(a, dir) + dir * 2.0, edge(b, -dir) - dir * 2.0);
|
||||
let bend = vec2(dir.y, -dir.x) * ((end - start).length() * 0.18).min(60.0);
|
||||
(start, start + (end - start) / 3.0 + bend, start + (end - start) * (2.0 / 3.0) + bend, end)
|
||||
};
|
||||
// The line stops where the head starts, which points along the curve's last stretch.
|
||||
let back = (end - c2).normalized();
|
||||
let back = if back.is_finite() && back != Vec2::ZERO { back } else { vec2(-1.0, 0.0) };
|
||||
let base = end - back * head;
|
||||
let curve = egui::epaint::CubicBezierShape::from_points_stroke([start, c1, c2, base], false, Color32::TRANSPARENT, stroke);
|
||||
let points: Vec<Pos2> = curve.flatten(Some(0.5));
|
||||
if tone == Tone::Late {
|
||||
painter.extend(Shape::dashed_line(&points, stroke, 5.0, 4.0));
|
||||
} else {
|
||||
painter.add(Shape::line(points, stroke));
|
||||
}
|
||||
let side = vec2(-back.y, back.x) * 4.5;
|
||||
painter.add(Shape::convex_polygon(vec![end, base + side, base - side], colour, Stroke::NONE));
|
||||
}
|
||||
|
||||
/// The focused field's links in words, in a pill at the top of the page view.
|
||||
pub(crate) fn paint_trace(ui: &egui::Ui, painter: &egui::Painter, viewport: Rect, view: &CalcOrderView, generation: u64, selected: Option<&str>) {
|
||||
if view.hide_links {
|
||||
return;
|
||||
}
|
||||
let (Some(listed), Some(focus)) = (view.current(generation), view.focus(selected)) else { return };
|
||||
let t = Tokens::get(ui.ctx());
|
||||
let text = trace(&listed.links, &focus);
|
||||
let font = theme::regular(12.0);
|
||||
// Clear of the floating tool strip at the view's left.
|
||||
let room = (viewport.width() - 220.0).max(0.0);
|
||||
let shown = widgets::fit_line(&text, room, |s| widgets::text_width(ui, s, &font));
|
||||
if shown.is_empty() {
|
||||
return;
|
||||
}
|
||||
let w = widgets::text_width(ui, &shown, &font) + 46.0;
|
||||
let pill = Rect::from_center_size(pos2(viewport.center().x, viewport.top() + 26.0), vec2(w, 30.0));
|
||||
painter.rect(pill, CornerRadius::same(15), t.card, Stroke::new(1.0, t.border), egui::StrokeKind::Inside);
|
||||
icons::paint(ui, Rect::from_center_size(pill.left_center() + vec2(18.0, 0.0), vec2(14.0, 14.0)), "move-right", 13.0, LINK_OK);
|
||||
painter.text(pill.left_center() + vec2(32.0, 0.0), Align2::LEFT_CENTER, shown, font, t.text);
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
fn field(name: &str, reads: &[&str], issues: Vec<CalculationIssue>) -> CalculatedField {
|
||||
CalculatedField { name: name.into(), reads: reads.iter().map(|r| (*r).to_owned()).collect(), listed: true, issues }
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn a_name_list_reads_as_a_sentence_and_stops_after_six() {
|
||||
crate::i18n::set_current(crate::i18n::Lang::EN);
|
||||
assert_eq!(names(&[]), "");
|
||||
assert_eq!(names(&["a"]), "a");
|
||||
assert_eq!(names(&["a", "b"]), "a and b");
|
||||
assert_eq!(names(&["a", "b", "c"]), "a, b and c");
|
||||
assert_eq!(names(&["1", "2", "3", "4", "5", "6", "7"]), "1, 2, 3, 4, 5, 6, …");
|
||||
}
|
||||
|
||||
fn link(from: &str, to: &str, tone: Tone) -> Link {
|
||||
Link { from: from.into(), to: to.into(), tone }
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn a_read_name_links_the_field_of_that_name_and_the_fields_under_it() {
|
||||
let calculated = [field("total", &["row", "row.1", "tax"], vec![])];
|
||||
let got = links(&calculated, vec!["rows", "row.2", "total", "row", "row.1", "tax"]);
|
||||
let from: Vec<&str> = got.iter().map(|l| l.from.as_str()).collect();
|
||||
// `rows` isn't under `row`, and `row.1` named twice links once.
|
||||
assert_eq!(from, ["row", "row.1", "row.2", "tax"]);
|
||||
assert!(got.iter().all(|l| l.to == "total" && l.tone == Tone::Ok));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn a_link_is_late_or_in_a_loop_as_its_reader_s_issues_say() {
|
||||
let calculated = [
|
||||
field("total", &["sub", "shipping"], vec![CalculationIssue::RunsTooEarly { field: "sub".into() }]),
|
||||
field("sub", &["qty"], vec![]),
|
||||
field("x", &["y"], vec![CalculationIssue::Cycle { fields: vec!["y".into()] }]),
|
||||
field("y", &["x"], vec![CalculationIssue::Cycle { fields: vec!["x".into()] }]),
|
||||
];
|
||||
let got = links(&calculated, vec!["qty", "shipping", "sub", "total", "x", "y"]);
|
||||
assert_eq!(
|
||||
got,
|
||||
[
|
||||
link("sub", "total", Tone::Late),
|
||||
link("shipping", "total", Tone::Ok),
|
||||
link("qty", "sub", Tone::Ok),
|
||||
link("y", "x", Tone::Loop),
|
||||
link("x", "y", Tone::Loop),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn links_stop_at_the_cap() {
|
||||
let names: Vec<String> = (0..MAX_LINKS + 10).map(|k| format!("g.{k}")).collect();
|
||||
let calculated = [field("sum", &["g"], vec![])];
|
||||
assert_eq!(links(&calculated, names.iter().map(String::as_str).collect()).len(), MAX_LINKS);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn the_summary_says_what_a_field_reads_and_what_reads_it() {
|
||||
crate::i18n::set_current(crate::i18n::Lang::EN);
|
||||
let links = [link("sub", "total", Tone::Late), link("tax", "total", Tone::Ok), link("qty", "sub", Tone::Ok), link("sub", "tax", Tone::Ok)];
|
||||
assert_eq!(trace(&links, "total"), "total reads sub and tax · No field reads it");
|
||||
assert_eq!(trace(&links, "sub"), "sub reads qty · total and tax read it");
|
||||
assert_eq!(trace(&links, "tax"), "tax reads sub · total reads it");
|
||||
assert_eq!(trace(&links, "qty"), "qty reads no other field · sub reads it");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn loops_group_the_fields_that_read_each_other() {
|
||||
let calculated = [
|
||||
field("a", &["b"], vec![CalculationIssue::Cycle { fields: vec!["b".into()] }]),
|
||||
field("x", &["x"], vec![CalculationIssue::Cycle { fields: vec!["x".into()] }]),
|
||||
field("ok", &[], vec![]),
|
||||
field("c", &["a"], vec![CalculationIssue::Cycle { fields: vec!["a".into()] }]),
|
||||
field("b", &["c"], vec![CalculationIssue::Cycle { fields: vec!["c".into()] }]),
|
||||
];
|
||||
assert_eq!(loops(&calculated), vec![vec!["a", "c", "b"], vec!["x"]]);
|
||||
}
|
||||
}
|
||||
@@ -519,6 +519,8 @@ pub struct DocView {
|
||||
pub forms: crate::forms_ui::FormView,
|
||||
/// Prepare a form: the selected field and the gesture in progress.
|
||||
pub prepare: crate::prepare::PrepareView,
|
||||
/// Prepare a form ▸ Calculation order.
|
||||
pub(crate) calc_order: crate::calc_order_ui::CalcOrderView,
|
||||
/// Edit a PDF: the selected added item, the text being typed.
|
||||
pub content: crate::content_ui::ContentView,
|
||||
/// Edit a PDF ▸ Link tool state.
|
||||
@@ -799,6 +801,7 @@ impl DocView {
|
||||
measure: Default::default(),
|
||||
forms: Default::default(),
|
||||
prepare: Default::default(),
|
||||
calc_order: Default::default(),
|
||||
content: Default::default(),
|
||||
links: Default::default(),
|
||||
redact_drag: None,
|
||||
@@ -2403,6 +2406,8 @@ pub fn document_area(app: &mut PdfCraftApp, index: usize, ui: &mut egui::Ui) {
|
||||
}
|
||||
// The Prepare a form panel is open (or a field tool is picked): fields are edited, not filled.
|
||||
let preparing = app.is_preparing();
|
||||
// Prepare a form ▸ Calculation order: the order's steps and links on the page.
|
||||
let calc_order = preparing && app.left_open && app.left == crate::LeftPanel::CalculationOrder;
|
||||
// Edit a PDF: added text and images can be selected, moved and edited.
|
||||
let editing_content =
|
||||
(app.left_open && app.left == crate::LeftPanel::Tool("edit")) || matches!(app.quick_tool, QuickTool::AddText | QuickTool::EditText);
|
||||
@@ -2767,6 +2772,7 @@ pub fn document_area(app: &mut PdfCraftApp, index: usize, ui: &mut egui::Ui) {
|
||||
let mut copy_selected = false;
|
||||
let comments_hidden = doc.comments_hidden();
|
||||
let form = doc.form.clone();
|
||||
let generation = doc.edit_generation();
|
||||
let can_fill = doc.allows_form_filling();
|
||||
let can_crop = doc.allows_assembly();
|
||||
let mut open_boxes = false;
|
||||
@@ -2892,6 +2898,7 @@ pub fn document_area(app: &mut PdfCraftApp, index: usize, ui: &mut egui::Ui) {
|
||||
// Set again below when the right-click lands on a link.
|
||||
view.links.context = None;
|
||||
}
|
||||
let mut calc_hover = None;
|
||||
for &i in &visible_pages {
|
||||
badge_hover = None;
|
||||
let r = snap_to_pixels(rects[i].translate(origin.to_vec2()), ppp);
|
||||
@@ -3460,6 +3467,12 @@ pub fn document_area(app: &mut PdfCraftApp, index: usize, ui: &mut egui::Ui) {
|
||||
}
|
||||
if preparing {
|
||||
crate::prepare::paint_page(ui, painter, &xf, i, info, &form, view);
|
||||
if calc_order {
|
||||
let selected = view.prepare.selected.as_ref().map(|(name, _)| name.as_str());
|
||||
if let Some(name) = crate::calc_order_ui::paint_page(ui, painter, &xf, i, info, &form, &view.calc_order, generation, selected) {
|
||||
calc_hover = Some(name);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
crate::forms_ui::paint_page(ui, painter, &xf, i, info, &form, view);
|
||||
}
|
||||
@@ -3581,6 +3594,11 @@ pub fn document_area(app: &mut PdfCraftApp, index: usize, ui: &mut egui::Ui) {
|
||||
hover_text = badge_hover.take();
|
||||
}
|
||||
}
|
||||
if calc_order {
|
||||
view.calc_order.set_hover_page(calc_hover);
|
||||
let selected = view.prepare.selected.as_ref().map(|(name, _)| name.as_str());
|
||||
crate::calc_order_ui::paint_trace(ui, painter, visible, &view.calc_order, generation, selected);
|
||||
}
|
||||
// ScrollArea ignores the wheel while any widget is dragged, so a text-selection drag
|
||||
// scrolls the page itself (#721). After the page loop, so it keeps scrolling once the
|
||||
// pointer leaves the selection's page for the gap or the next page; over the whole
|
||||
|
||||
@@ -313,6 +313,15 @@ impl PdfCraftApp {
|
||||
}
|
||||
}
|
||||
"form.fields" => self.choose_right_panel(Some(RightPanel::Fields)),
|
||||
"form.calculation_order" => {
|
||||
self.left = crate::LeftPanel::CalculationOrder;
|
||||
// The page edits the fields, so Preview ends; the page grid closes, as for a tool.
|
||||
self.form_preview = false;
|
||||
if let Some(v) = active.and_then(|i| self.views.get_mut(i)) {
|
||||
v.organize = false;
|
||||
}
|
||||
self.reveal_tools();
|
||||
}
|
||||
"comment.flatten" => {
|
||||
self.apply_edit(Edit::Flatten { comments: true, fields: false });
|
||||
}
|
||||
|
||||
@@ -519,6 +519,36 @@
|
||||
Could not save: {e} تعذّر الحفظ: {e}
|
||||
Earlier in tab order أبكر في ترتيب التنقل
|
||||
Later in tab order أبعد في ترتيب التنقل
|
||||
Calculation order ترتيب الحساب
|
||||
Fix order إصلاح الترتيب
|
||||
Move only what must move, so every field calculates after the fields it reads. ينقل فقط ما يجب نقله، كي يُحسب كل حقل بعد الحقول التي يقرؤها.
|
||||
Earlier in calculation order أبكر في ترتيب الحساب
|
||||
Later in calculation order أبعد في ترتيب الحساب
|
||||
Too early مبكر جدًا
|
||||
Reads {name}, which calculates later, so it shows an old value. يقرأ {name} الذي يُحسب لاحقًا، لذا يعرض قيمة قديمة.
|
||||
Loop حلقة
|
||||
Reads {names}, which read it back. No order can fix a loop: change one of the formulas. يقرأ {names} التي تقرؤه بدورها. لا يمكن لأي ترتيب إصلاح الحلقة: غيّر إحدى الصيغ.
|
||||
Not in order خارج الترتيب
|
||||
Missing from the calculation order saved in the PDF: other PDF viewers may not calculate it. غير موجود في ترتيب الحساب المحفوظ في ملف PDF: قد لا تحسبه برامج عرض PDF الأخرى.
|
||||
Back to Prepare a form العودة إلى تجهيز نموذج
|
||||
No field in this form calculates its value yet. Give a field a calculation on the Calculate tab of its properties, and it shows here. لا يحسب أي حقل في هذا النموذج قيمته بعد. امنح حقلًا عملية حساب في علامة التبويب «الحساب» ضمن خصائصه، وسيظهر هنا.
|
||||
{names} and {last} {names} و{last}
|
||||
{field} reads no other field {field} لا يقرأ أي حقل آخر
|
||||
{field} reads {fields} {field} يقرأ {fields}
|
||||
No field reads it لا يقرؤه أي حقل
|
||||
The order saved in the PDF needs tidying يحتاج الترتيب المحفوظ في PDF إلى تنظيم
|
||||
Moves only what must move ينقل فقط ما يجب نقله
|
||||
Every field calculates after the fields it reads. يُحسب كل حقل بعد الحقول التي يقرؤها.
|
||||
Every field outside a loop calculates after the fields it reads. يُحسب كل حقل خارج حلقة بعد الحقول التي يقرؤها.
|
||||
{field} reads its own value {field} يقرأ قيمته نفسها
|
||||
{fields} read each other {fields} يقرأ بعضها بعضًا
|
||||
No order can fix a loop. Change one of the formulas. لا يمكن لأي ترتيب إصلاح حلقة. غيّر إحدى الصيغ.
|
||||
Edit {field}'s formula تحرير صيغة {field}
|
||||
Order · top calculates first الترتيب · الأعلى يُحسب أولًا
|
||||
Script برنامج نصي
|
||||
Links on page الروابط على الصفحة
|
||||
Show on the page which fields each field reads إظهار الحقول التي يقرؤها كل حقل على الصفحة
|
||||
Drag a field to move it, or select it and press {up} or {down}. اسحب حقلًا لنقله، أو حدده واضغط {up} أو {down}.
|
||||
From: من:
|
||||
To: إلى:
|
||||
High Resolution دقة عالية
|
||||
@@ -2364,6 +2394,12 @@ animation effects Off معطّلة
|
||||
no output folder was chosen لم يتم اختيار مجلد للإخراج
|
||||
@plural Downloaded {n} PDF|Downloaded {n} PDFs تم تنزيل {n} من ملفات PDF|تم تنزيل ملف PDF واحد ({n})|تم تنزيل ملفي PDF ({n})|تم تنزيل {n} ملفات PDF|تم تنزيل {n} ملف PDF|تم تنزيل {n} من ملفات PDF
|
||||
@plural {n} calculation now uses the new name.|{n} calculations now use the new name. تم تحديث {n} من العمليات الحسابية لتستخدم الاسم الجديد.|عملية حسابية واحدة ({n}) تستخدم الآن الاسم الجديد.|عمليتان حسابيتان ({n}) تستخدمان الآن الاسم الجديد.|{n} عمليات حسابية تستخدم الآن الاسم الجديد.|{n} عملية حسابية تستخدم الآن الاسم الجديد.|{n} من العمليات الحسابية تستخدم الآن الاسم الجديد.
|
||||
@plural The calculation order has {n} entry that calculates nothing. Fix order removes it.|The calculation order has {n} entries that calculate nothing. Fix order removes them. يحتوي ترتيب الحساب على {n} من الإدخالات التي لا تحسب شيئًا. «إصلاح الترتيب» يزيلها.|يحتوي ترتيب الحساب على إدخال واحد ({n}) لا يحسب شيئًا. «إصلاح الترتيب» يزيله.|يحتوي ترتيب الحساب على إدخالين ({n}) لا يحسبان شيئًا. «إصلاح الترتيب» يزيلهما.|يحتوي ترتيب الحساب على {n} إدخالات لا تحسب شيئًا. «إصلاح الترتيب» يزيلها.|يحتوي ترتيب الحساب على {n} إدخالًا لا يحسب شيئًا. «إصلاح الترتيب» يزيلها.|يحتوي ترتيب الحساب على {n} من الإدخالات التي لا تحسب شيئًا. «إصلاح الترتيب» يزيلها.
|
||||
@plural {fields} reads it|{fields} read it {fields} تقرؤه|{fields} يقرؤه|{fields} يقرآنه|{fields} تقرؤه|{fields} تقرؤه|{fields} تقرؤه
|
||||
@plural {n} field shows an old value|{n} fields show old values {n} من الحقول تعرض قيمًا قديمة|حقل واحد ({n}) يعرض قيمة قديمة|حقلان ({n}) يعرضان قيمًا قديمة|{n} حقول تعرض قيمًا قديمة|{n} حقلًا يعرض قيمًا قديمة|{n} من الحقول تعرض قيمًا قديمة
|
||||
@plural {field} calculates before {fields}, which it reads.|{field} calculates before {fields}, which it reads. {field} يُحسب قبل {fields}، التي يقرؤها.|{field} يُحسب قبل {fields}، الذي يقرؤه.|{field} يُحسب قبل {fields}، اللذين يقرؤهما.|{field} يُحسب قبل {fields}، التي يقرؤها.|{field} يُحسب قبل {fields}، التي يقرؤها.|{field} يُحسب قبل {fields}، التي يقرؤها.
|
||||
@plural {n} more field calculates too early.|{n} more fields calculate too early. {n} من الحقول الأخرى تُحسب مبكرًا جدًا.|حقل آخر ({n}) يُحسب مبكرًا جدًا.|حقلان آخران ({n}) يُحسبان مبكرًا جدًا.|{n} حقول أخرى تُحسب مبكرًا جدًا.|{n} حقلًا آخر يُحسب مبكرًا جدًا.|{n} من الحقول الأخرى تُحسب مبكرًا جدًا.
|
||||
@plural {fields} is missing from the order saved in the PDF, so other PDF viewers may not calculate it.|{fields} are missing from the order saved in the PDF, so other PDF viewers may not calculate them. {fields} غير موجودة في الترتيب المحفوظ في PDF، لذا قد لا تحسبها عارضات PDF الأخرى.|{fields} غير موجود في الترتيب المحفوظ في PDF، لذا قد لا تحسبه عارضات PDF الأخرى.|{fields} غير موجودين في الترتيب المحفوظ في PDF، لذا قد لا تحسبهما عارضات PDF الأخرى.|{fields} غير موجودة في الترتيب المحفوظ في PDF، لذا قد لا تحسبها عارضات PDF الأخرى.|{fields} غير موجودة في الترتيب المحفوظ في PDF، لذا قد لا تحسبها عارضات PDF الأخرى.|{fields} غير موجودة في الترتيب المحفوظ في PDF، لذا قد لا تحسبها عارضات PDF الأخرى.
|
||||
Scan مسح ضوئي
|
||||
Sign a sheet of white paper and take a photo of it in bright, even light (use the flash). Choose the photo or drop it here: PdfCraft finds the signature and removes the paper. وقّع على ورقة بيضاء والتقط لها صورة في إضاءة ساطعة ومتساوية (استخدم الفلاش). اختر الصورة أو أفلتها هنا: يعثر PdfCraft على التوقيع ويزيل الورق.
|
||||
Choose photo… اختيار صورة…
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 6 and column 47.
|
@@ -191,6 +191,36 @@
|
||||
Could not save: {e} Неуспешно записване: {e}
|
||||
Earlier in tab order По-напред в реда на табулация
|
||||
Later in tab order По-назад в реда на табулация
|
||||
Calculation order Ред на изчисляване
|
||||
Fix order Поправяне на реда
|
||||
Move only what must move, so every field calculates after the fields it reads. Премества само това, което трябва, така че всяко поле да се изчислява след полетата, които чете.
|
||||
Earlier in calculation order По-напред в реда на изчисляване
|
||||
Later in calculation order По-назад в реда на изчисляване
|
||||
Too early Твърде рано
|
||||
Reads {name}, which calculates later, so it shows an old value. Чете {name}, което се изчислява по-късно, затова показва стара стойност.
|
||||
Loop Цикъл
|
||||
Reads {names}, which read it back. No order can fix a loop: change one of the formulas. Чете {names}, които на свой ред го четат. Никой ред не може да поправи цикъл: променете една от формулите.
|
||||
Not in order Извън реда
|
||||
Missing from the calculation order saved in the PDF: other PDF viewers may not calculate it. Липсва в реда на изчисляване, записан в PDF файла: други програми за PDF може да не го изчисляват.
|
||||
Back to Prepare a form Назад към „Подготви формуляр“
|
||||
No field in this form calculates its value yet. Give a field a calculation on the Calculate tab of its properties, and it shows here. Все още нито едно поле в този формуляр не изчислява стойността си. Задайте изчисление на поле в раздела „Изчисляване“ на свойствата му и то ще се покаже тук.
|
||||
{names} and {last} {names} и {last}
|
||||
{field} reads no other field {field} не чете друго поле
|
||||
{field} reads {fields} {field} чете {fields}
|
||||
No field reads it Никое поле не го чете
|
||||
The order saved in the PDF needs tidying Редът, запазен в PDF файла, има нужда от подреждане
|
||||
Moves only what must move Премества само каквото трябва
|
||||
Every field calculates after the fields it reads. Всяко поле се изчислява след полетата, които чете.
|
||||
Every field outside a loop calculates after the fields it reads. Всяко поле извън цикъл се изчислява след полетата, които чете.
|
||||
{field} reads its own value {field} чете собствената си стойност
|
||||
{fields} read each other {fields} се четат взаимно
|
||||
No order can fix a loop. Change one of the formulas. Никой ред не може да поправи цикъл. Променете някоя от формулите.
|
||||
Edit {field}'s formula Редактиране на формулата на {field}
|
||||
Order · top calculates first Ред · горното се изчислява първо
|
||||
Script Скрипт
|
||||
Links on page Връзки на страницата
|
||||
Show on the page which fields each field reads Показване на страницата кои полета чете всяко поле
|
||||
Drag a field to move it, or select it and press {up} or {down}. Плъзнете поле, за да го преместите, или го изберете и натиснете {up} или {down}.
|
||||
From: От:
|
||||
To: До:
|
||||
High Resolution Висока резолюция
|
||||
@@ -2306,6 +2336,12 @@ animation effects Off Изключени
|
||||
no output folder was chosen не е избрана папка за изхода
|
||||
@plural Downloaded {n} PDF|Downloaded {n} PDFs Изтеглен е {n} PDF|Изтеглени са {n} PDF файла
|
||||
@plural {n} calculation now uses the new name.|{n} calculations now use the new name. {n} изчисление вече използва новото име.|{n} изчисления вече използват новото име.
|
||||
@plural The calculation order has {n} entry that calculates nothing. Fix order removes it.|The calculation order has {n} entries that calculate nothing. Fix order removes them. Редът на изчисляване има {n} запис, който не изчислява нищо. „Поправяне на реда“ го премахва.|Редът на изчисляване има {n} записа, които не изчисляват нищо. „Поправяне на реда“ ги премахва.
|
||||
@plural {fields} reads it|{fields} read it {fields} го чете|{fields} го четат
|
||||
@plural {n} field shows an old value|{n} fields show old values {n} поле показва стара стойност|{n} полета показват стари стойности
|
||||
@plural {field} calculates before {fields}, which it reads.|{field} calculates before {fields}, which it reads. {field} се изчислява преди {fields}, което чете.|{field} се изчислява преди {fields}, които чете.
|
||||
@plural {n} more field calculates too early.|{n} more fields calculate too early. Още {n} поле се изчислява твърде рано.|Още {n} полета се изчисляват твърде рано.
|
||||
@plural {fields} is missing from the order saved in the PDF, so other PDF viewers may not calculate it.|{fields} are missing from the order saved in the PDF, so other PDF viewers may not calculate them. {fields} липсва в реда, запазен в PDF файла, затова други програми за PDF може да не го изчислят.|{fields} липсват в реда, запазен в PDF файла, затова други програми за PDF може да не ги изчислят.
|
||||
Scan Сканиране
|
||||
Sign a sheet of white paper and take a photo of it in bright, even light (use the flash). Choose the photo or drop it here: PdfCraft finds the signature and removes the paper. Подпишете се на лист бяла хартия и го снимайте на ярка, равномерна светлина (със светкавица). Изберете снимката или я пуснете тук: PdfCraft открива подписа и премахва хартията.
|
||||
Choose photo… Избор на снимка…
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 8 and column 16.
|
@@ -599,6 +599,36 @@ key Space Mezerník
|
||||
Could not save: {e} Nelze uložit: {e}
|
||||
Earlier in tab order Dříve v pořadí tabulátoru
|
||||
Later in tab order Později v pořadí tabulátoru
|
||||
Calculation order Pořadí výpočtů
|
||||
Fix order Opravit pořadí
|
||||
Move only what must move, so every field calculates after the fields it reads. Přesune jen to, co musí, aby se každé pole počítalo až po polích, která čte.
|
||||
Earlier in calculation order Dříve v pořadí výpočtů
|
||||
Later in calculation order Později v pořadí výpočtů
|
||||
Too early Příliš brzy
|
||||
Reads {name}, which calculates later, so it shows an old value. Čte {name}, které se počítá později, takže ukazuje starou hodnotu.
|
||||
Loop Smyčka
|
||||
Reads {names}, which read it back. No order can fix a loop: change one of the formulas. Čte {names}, která ho čtou zpět. Žádné pořadí smyčku neopraví: změňte jeden ze vzorců.
|
||||
Not in order Mimo pořadí
|
||||
Missing from the calculation order saved in the PDF: other PDF viewers may not calculate it. Chybí v pořadí výpočtů uloženém v PDF: jiné prohlížeče PDF ho možná nepočítají.
|
||||
Back to Prepare a form Zpět na Připravit formulář
|
||||
No field in this form calculates its value yet. Give a field a calculation on the Calculate tab of its properties, and it shows here. Žádné pole tohoto formuláře zatím nepočítá svou hodnotu. Zadejte poli výpočet na kartě Výpočet v jeho vlastnostech a zobrazí se zde.
|
||||
{names} and {last} {names} a {last}
|
||||
{field} reads no other field {field} nečte žádné jiné pole
|
||||
{field} reads {fields} {field} čte {fields}
|
||||
No field reads it Žádné pole ho nečte
|
||||
The order saved in the PDF needs tidying Pořadí uložené v PDF je potřeba uklidit
|
||||
Moves only what must move Přesune jen to, co musí
|
||||
Every field calculates after the fields it reads. Každé pole se počítá až po polích, která čte.
|
||||
Every field outside a loop calculates after the fields it reads. Každé pole mimo smyčku se počítá až po polích, která čte.
|
||||
{field} reads its own value {field} čte svou vlastní hodnotu
|
||||
{fields} read each other {fields} čtou jedno druhé
|
||||
No order can fix a loop. Change one of the formulas. Smyčku žádné pořadí neopraví. Změňte jeden ze vzorců.
|
||||
Edit {field}'s formula Upravit vzorec pole {field}
|
||||
Order · top calculates first Pořadí · horní se počítá první
|
||||
Script Skript
|
||||
Links on page Vazby na stránce
|
||||
Show on the page which fields each field reads Ukázat na stránce, která pole čte každé pole
|
||||
Drag a field to move it, or select it and press {up} or {down}. Pole přesunete přetažením, nebo ho vyberte a stiskněte {up} nebo {down}.
|
||||
From: Od:
|
||||
To: Do:
|
||||
High Resolution Vysoké rozlišení
|
||||
@@ -2417,6 +2447,12 @@ animation effects Off Vypnuto
|
||||
no output folder was chosen nebyla vybrána výstupní složka
|
||||
@plural Downloaded {n} PDF|Downloaded {n} PDFs Stažen {n} soubor PDF|Staženy {n} soubory PDF|Staženo {n} souborů PDF
|
||||
@plural {n} calculation now uses the new name.|{n} calculations now use the new name. {n} výpočet nyní používá nový název.|{n} výpočty nyní používají nový název.|{n} výpočtů nyní používá nový název.
|
||||
@plural The calculation order has {n} entry that calculates nothing. Fix order removes it.|The calculation order has {n} entries that calculate nothing. Fix order removes them. Pořadí výpočtů má {n} položku, která nic nepočítá. „Opravit pořadí“ ji odstraní.|Pořadí výpočtů má {n} položky, které nic nepočítají. „Opravit pořadí“ je odstraní.|Pořadí výpočtů má {n} položek, které nic nepočítají. „Opravit pořadí“ je odstraní.
|
||||
@plural {fields} reads it|{fields} read it {fields} ho čte|{fields} ho čtou|{fields} ho čtou
|
||||
@plural {n} field shows an old value|{n} fields show old values {n} pole ukazuje starou hodnotu|{n} pole ukazují staré hodnoty|{n} polí ukazuje staré hodnoty
|
||||
@plural {field} calculates before {fields}, which it reads.|{field} calculates before {fields}, which it reads. {field} se počítá před {fields}, které čte.|{field} se počítá před {fields}, která čte.|{field} se počítá před {fields}, která čte.
|
||||
@plural {n} more field calculates too early.|{n} more fields calculate too early. Ještě {n} pole se počítá příliš brzy.|Ještě {n} pole se počítají příliš brzy.|Ještě {n} polí se počítá příliš brzy.
|
||||
@plural {fields} is missing from the order saved in the PDF, so other PDF viewers may not calculate it.|{fields} are missing from the order saved in the PDF, so other PDF viewers may not calculate them. {fields} chybí v pořadí uloženém v PDF, takže ho jiné prohlížeče PDF nemusí vypočítat.|{fields} chybí v pořadí uloženém v PDF, takže je jiné prohlížeče PDF nemusí vypočítat.|{fields} chybí v pořadí uloženém v PDF, takže je jiné prohlížeče PDF nemusí vypočítat.
|
||||
Scan Skenovat
|
||||
Sign a sheet of white paper and take a photo of it in bright, even light (use the flash). Choose the photo or drop it here: PdfCraft finds the signature and removes the paper. Podepište se na bílý list papíru a vyfoťte ho při jasném, rovnoměrném světle (použijte blesk). Vyberte fotografii nebo ji sem přetáhněte: PdfCraft najde podpis a odstraní papír.
|
||||
Choose photo… Vybrat fotografii…
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 6 and column 47.
|
@@ -492,6 +492,36 @@
|
||||
Could not save: {e} Speichern fehlgeschlagen: {e}
|
||||
Earlier in tab order Früher in der Tab-Reihenfolge
|
||||
Later in tab order Später in der Tab-Reihenfolge
|
||||
Calculation order Berechnungsreihenfolge
|
||||
Fix order Reihenfolge korrigieren
|
||||
Move only what must move, so every field calculates after the fields it reads. Nur verschieben, was verschoben werden muss, damit jedes Feld nach den Feldern berechnet wird, die es liest.
|
||||
Earlier in calculation order Früher in der Berechnungsreihenfolge
|
||||
Later in calculation order Später in der Berechnungsreihenfolge
|
||||
Too early Zu früh
|
||||
Reads {name}, which calculates later, so it shows an old value. Liest {name}, das später berechnet wird, und zeigt deshalb einen alten Wert.
|
||||
Loop Schleife
|
||||
Reads {names}, which read it back. No order can fix a loop: change one of the formulas. Liest {names}, die es wieder lesen. Keine Reihenfolge kann eine Schleife beheben: Ändere eine der Formeln.
|
||||
Not in order Nicht in der Reihenfolge
|
||||
Missing from the calculation order saved in the PDF: other PDF viewers may not calculate it. Fehlt in der im PDF gespeicherten Berechnungsreihenfolge: Andere PDF-Viewer berechnen es womöglich nicht.
|
||||
Back to Prepare a form Zurück zu „Formular vorbereiten“
|
||||
No field in this form calculates its value yet. Give a field a calculation on the Calculate tab of its properties, and it shows here. Noch berechnet kein Feld dieses Formulars seinen Wert. Gib einem Feld auf dem Tab „Berechnen“ seiner Eigenschaften eine Berechnung, dann erscheint es hier.
|
||||
{names} and {last} {names} und {last}
|
||||
{field} reads no other field {field} liest kein anderes Feld
|
||||
{field} reads {fields} {field} liest {fields}
|
||||
No field reads it Kein Feld liest es
|
||||
The order saved in the PDF needs tidying Die im PDF gespeicherte Reihenfolge muss bereinigt werden
|
||||
Moves only what must move Verschiebt nur, was verschoben werden muss
|
||||
Every field calculates after the fields it reads. Jedes Feld wird nach den Feldern berechnet, die es liest.
|
||||
Every field outside a loop calculates after the fields it reads. Jedes Feld außerhalb einer Schleife wird nach den Feldern berechnet, die es liest.
|
||||
{field} reads its own value {field} liest seinen eigenen Wert
|
||||
{fields} read each other {fields} lesen sich gegenseitig
|
||||
No order can fix a loop. Change one of the formulas. Keine Reihenfolge kann eine Schleife beheben. Ändere eine der Formeln.
|
||||
Edit {field}'s formula Formel von {field} bearbeiten
|
||||
Order · top calculates first Reihenfolge · oben wird zuerst berechnet
|
||||
Script Skript
|
||||
Links on page Verbindungen auf der Seite
|
||||
Show on the page which fields each field reads Auf der Seite zeigen, welche Felder jedes Feld liest
|
||||
Drag a field to move it, or select it and press {up} or {down}. Ziehe ein Feld, um es zu verschieben, oder wähle es aus und drücke {up} oder {down}.
|
||||
From: Von:
|
||||
To: Bis:
|
||||
High Resolution Hohe Auflösung
|
||||
@@ -2344,6 +2374,12 @@ animation effects Off Aus
|
||||
no output folder was chosen kein Ausgabeordner gewählt
|
||||
@plural Downloaded {n} PDF|Downloaded {n} PDFs {n} PDF heruntergeladen|{n} PDFs heruntergeladen
|
||||
@plural {n} calculation now uses the new name.|{n} calculations now use the new name. {n} Berechnung verwendet jetzt den neuen Namen.|{n} Berechnungen verwenden jetzt den neuen Namen.
|
||||
@plural The calculation order has {n} entry that calculates nothing. Fix order removes it.|The calculation order has {n} entries that calculate nothing. Fix order removes them. Die Berechnungsreihenfolge hat {n} Eintrag, der nichts berechnet. „Reihenfolge korrigieren“ entfernt ihn.|Die Berechnungsreihenfolge hat {n} Einträge, die nichts berechnen. „Reihenfolge korrigieren“ entfernt sie.
|
||||
@plural {fields} reads it|{fields} read it {fields} liest es|{fields} lesen es
|
||||
@plural {n} field shows an old value|{n} fields show old values {n} Feld zeigt einen alten Wert|{n} Felder zeigen alte Werte
|
||||
@plural {field} calculates before {fields}, which it reads.|{field} calculates before {fields}, which it reads. {field} wird vor {fields} berechnet, das es liest.|{field} wird vor {fields} berechnet, die es liest.
|
||||
@plural {n} more field calculates too early.|{n} more fields calculate too early. {n} weiteres Feld wird zu früh berechnet.|{n} weitere Felder werden zu früh berechnet.
|
||||
@plural {fields} is missing from the order saved in the PDF, so other PDF viewers may not calculate it.|{fields} are missing from the order saved in the PDF, so other PDF viewers may not calculate them. {fields} fehlt in der im PDF gespeicherten Reihenfolge, daher berechnen andere PDF-Viewer es womöglich nicht.|{fields} fehlen in der im PDF gespeicherten Reihenfolge, daher berechnen andere PDF-Viewer sie womöglich nicht.
|
||||
Scan Scannen
|
||||
Sign a sheet of white paper and take a photo of it in bright, even light (use the flash). Choose the photo or drop it here: PdfCraft finds the signature and removes the paper. Unterschreiben Sie auf einem weißen Blatt Papier und fotografieren Sie es bei hellem, gleichmäßigem Licht (mit Blitz). Wählen Sie das Foto aus oder ziehen Sie es hierher: PdfCraft findet die Unterschrift und entfernt das Papier.
|
||||
Choose photo… Foto auswählen…
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 6 and column 51.
|
@@ -1830,6 +1830,36 @@
|
||||
Could not save: {e} Δεν ήταν δυνατή η αποθήκευση: {e}
|
||||
Earlier in tab order Νωρίτερα στη σειρά μετακίνησης με Tab
|
||||
Later in tab order Αργότερα στη σειρά μετακίνησης με Tab
|
||||
Calculation order Σειρά υπολογισμού
|
||||
Fix order Διόρθωση σειράς
|
||||
Move only what must move, so every field calculates after the fields it reads. Μετακινεί μόνο ό,τι πρέπει, ώστε κάθε πεδίο να υπολογίζεται μετά τα πεδία που διαβάζει.
|
||||
Earlier in calculation order Νωρίτερα στη σειρά υπολογισμού
|
||||
Later in calculation order Αργότερα στη σειρά υπολογισμού
|
||||
Too early Πολύ νωρίς
|
||||
Reads {name}, which calculates later, so it shows an old value. Διαβάζει το {name}, που υπολογίζεται αργότερα, οπότε δείχνει παλιά τιμή.
|
||||
Loop Βρόχος
|
||||
Reads {names}, which read it back. No order can fix a loop: change one of the formulas. Διαβάζει τα {names}, που με τη σειρά τους το διαβάζουν. Καμία σειρά δεν διορθώνει έναν βρόχο: αλλάξτε έναν από τους τύπους.
|
||||
Not in order Εκτός σειράς
|
||||
Missing from the calculation order saved in the PDF: other PDF viewers may not calculate it. Λείπει από τη σειρά υπολογισμού που είναι αποθηκευμένη στο PDF: άλλα προγράμματα προβολής PDF ίσως δεν το υπολογίζουν.
|
||||
Back to Prepare a form Επιστροφή στην Προετοιμασία φόρμας
|
||||
No field in this form calculates its value yet. Give a field a calculation on the Calculate tab of its properties, and it shows here. Κανένα πεδίο αυτής της φόρμας δεν υπολογίζει ακόμη την τιμή του. Δώστε σε ένα πεδίο υπολογισμό στην καρτέλα Υπολογισμός των ιδιοτήτων του και θα εμφανιστεί εδώ.
|
||||
{names} and {last} {names} και {last}
|
||||
{field} reads no other field {field} δεν διαβάζει άλλο πεδίο
|
||||
{field} reads {fields} {field} διαβάζει {fields}
|
||||
No field reads it Κανένα πεδίο δεν το διαβάζει
|
||||
The order saved in the PDF needs tidying Η σειρά που είναι αποθηκευμένη στο PDF χρειάζεται τακτοποίηση
|
||||
Moves only what must move Μετακινεί μόνο ό,τι πρέπει
|
||||
Every field calculates after the fields it reads. Κάθε πεδίο υπολογίζεται μετά από τα πεδία που διαβάζει.
|
||||
Every field outside a loop calculates after the fields it reads. Κάθε πεδίο εκτός βρόχου υπολογίζεται μετά από τα πεδία που διαβάζει.
|
||||
{field} reads its own value {field} διαβάζει τη δική του τιμή
|
||||
{fields} read each other {fields} διαβάζουν το ένα το άλλο
|
||||
No order can fix a loop. Change one of the formulas. Καμία σειρά δεν διορθώνει έναν βρόχο. Αλλάξτε έναν από τους τύπους.
|
||||
Edit {field}'s formula Επεξεργασία του τύπου του {field}
|
||||
Order · top calculates first Σειρά · το πάνω υπολογίζεται πρώτο
|
||||
Script Σενάριο
|
||||
Links on page Συνδέσεις στη σελίδα
|
||||
Show on the page which fields each field reads Εμφάνιση στη σελίδα των πεδίων που διαβάζει κάθε πεδίο
|
||||
Drag a field to move it, or select it and press {up} or {down}. Σύρετε ένα πεδίο για να το μετακινήσετε ή επιλέξτε το και πατήστε {up} ή {down}.
|
||||
From: Από:
|
||||
To: Έως:
|
||||
High Resolution Υψηλή ανάλυση
|
||||
@@ -2340,6 +2370,12 @@ animation effects Off Ανενεργά
|
||||
no output folder was chosen δεν επιλέχθηκε φάκελος εξόδου
|
||||
@plural Downloaded {n} PDF|Downloaded {n} PDFs Λήφθηκε {n} PDF|Λήφθηκαν {n} PDF
|
||||
@plural {n} calculation now uses the new name.|{n} calculations now use the new name. {n} υπολογισμός χρησιμοποιεί πλέον το νέο όνομα.|{n} υπολογισμοί χρησιμοποιούν πλέον το νέο όνομα.
|
||||
@plural The calculation order has {n} entry that calculates nothing. Fix order removes it.|The calculation order has {n} entries that calculate nothing. Fix order removes them. Η σειρά υπολογισμού έχει {n} καταχώριση που δεν υπολογίζει τίποτα. Η «Διόρθωση σειράς» την αφαιρεί.|Η σειρά υπολογισμού έχει {n} καταχωρίσεις που δεν υπολογίζουν τίποτα. Η «Διόρθωση σειράς» τις αφαιρεί.
|
||||
@plural {fields} reads it|{fields} read it {fields} το διαβάζει|{fields} το διαβάζουν
|
||||
@plural {n} field shows an old value|{n} fields show old values {n} πεδίο δείχνει παλιά τιμή|{n} πεδία δείχνουν παλιές τιμές
|
||||
@plural {field} calculates before {fields}, which it reads.|{field} calculates before {fields}, which it reads. {field} υπολογίζεται πριν από {fields}, που διαβάζει.|{field} υπολογίζεται πριν από {fields}, που διαβάζει.
|
||||
@plural {n} more field calculates too early.|{n} more fields calculate too early. Ακόμη {n} πεδίο υπολογίζεται πολύ νωρίς.|Ακόμη {n} πεδία υπολογίζονται πολύ νωρίς.
|
||||
@plural {fields} is missing from the order saved in the PDF, so other PDF viewers may not calculate it.|{fields} are missing from the order saved in the PDF, so other PDF viewers may not calculate them. {fields} λείπει από τη σειρά που είναι αποθηκευμένη στο PDF, οπότε άλλα προγράμματα PDF ίσως δεν το υπολογίσουν.|{fields} λείπουν από τη σειρά που είναι αποθηκευμένη στο PDF, οπότε άλλα προγράμματα PDF ίσως δεν τα υπολογίσουν.
|
||||
@plural {n} field name collides with earlier files and will be renamed: {list}|{n} field names collide with earlier files and will be renamed: {list} {n} όνομα πεδίου συγκρούεται με προηγούμενα αρχεία και θα μετονομαστεί: {list}|{n} ονόματα πεδίων συγκρούονται με προηγούμενα αρχεία και θα μετονομαστούν: {list}
|
||||
Scan Σάρωση
|
||||
Sign a sheet of white paper and take a photo of it in bright, even light (use the flash). Choose the photo or drop it here: PdfCraft finds the signature and removes the paper. Υπογράψτε σε ένα λευκό φύλλο χαρτιού και φωτογραφίστε το σε έντονο, ομοιόμορφο φως (χρησιμοποιήστε το φλας). Επιλέξτε τη φωτογραφία ή αφήστε την εδώ: το PdfCraft βρίσκει την υπογραφή και αφαιρεί το χαρτί.
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 477 and column 9.
|
@@ -515,6 +515,36 @@
|
||||
Could not save: {e} No se pudo guardar: {e}
|
||||
Earlier in tab order Antes en el orden de tabulación
|
||||
Later in tab order Después en el orden de tabulación
|
||||
Calculation order Orden de cálculo
|
||||
Fix order Corregir orden
|
||||
Move only what must move, so every field calculates after the fields it reads. Mueve solo lo que debe moverse, para que cada campo se calcule después de los campos que lee.
|
||||
Earlier in calculation order Antes en el orden de cálculo
|
||||
Later in calculation order Después en el orden de cálculo
|
||||
Too early Demasiado pronto
|
||||
Reads {name}, which calculates later, so it shows an old value. Lee {name}, que se calcula después, así que muestra un valor antiguo.
|
||||
Loop Bucle
|
||||
Reads {names}, which read it back. No order can fix a loop: change one of the formulas. Lee {names}, que a su vez lo leen. Ningún orden puede corregir un bucle: cambia una de las fórmulas.
|
||||
Not in order Fuera del orden
|
||||
Missing from the calculation order saved in the PDF: other PDF viewers may not calculate it. Falta en el orden de cálculo guardado en el PDF: otros visores de PDF podrían no calcularlo.
|
||||
Back to Prepare a form Volver a Preparar un formulario
|
||||
No field in this form calculates its value yet. Give a field a calculation on the Calculate tab of its properties, and it shows here. Ningún campo de este formulario calcula todavía su valor. Dale a un campo un cálculo en la pestaña Calcular de sus propiedades y aparecerá aquí.
|
||||
{names} and {last} {names} y {last}
|
||||
{field} reads no other field {field} no lee ningún otro campo
|
||||
{field} reads {fields} {field} lee {fields}
|
||||
No field reads it Ningún campo lo lee
|
||||
The order saved in the PDF needs tidying El orden guardado en el PDF necesita una limpieza
|
||||
Moves only what must move Mueve solo lo que debe moverse
|
||||
Every field calculates after the fields it reads. Cada campo se calcula después de los campos que lee.
|
||||
Every field outside a loop calculates after the fields it reads. Cada campo fuera de un bucle se calcula después de los campos que lee.
|
||||
{field} reads its own value {field} lee su propio valor
|
||||
{fields} read each other {fields} se leen entre sí
|
||||
No order can fix a loop. Change one of the formulas. Ningún orden puede corregir un bucle. Cambia una de las fórmulas.
|
||||
Edit {field}'s formula Editar la fórmula de {field}
|
||||
Order · top calculates first Orden · lo de arriba se calcula primero
|
||||
Script Script
|
||||
Links on page Vínculos en la página
|
||||
Show on the page which fields each field reads Mostrar en la página qué campos lee cada campo
|
||||
Drag a field to move it, or select it and press {up} or {down}. Arrastra un campo para moverlo, o selecciónalo y pulsa {up} o {down}.
|
||||
From: Desde:
|
||||
To: Hasta:
|
||||
High Resolution Alta resolución
|
||||
@@ -2472,6 +2502,12 @@ animation effects Off Desactivados
|
||||
no output folder was chosen no se eligió ninguna carpeta de salida
|
||||
@plural Downloaded {n} PDF|Downloaded {n} PDFs Se descargó {n} PDF|Se descargaron {n} PDF
|
||||
@plural {n} calculation now uses the new name.|{n} calculations now use the new name. {n} cálculo usa ahora el nuevo nombre.|{n} cálculos usan ahora el nuevo nombre.
|
||||
@plural The calculation order has {n} entry that calculates nothing. Fix order removes it.|The calculation order has {n} entries that calculate nothing. Fix order removes them. El orden de cálculo tiene {n} entrada que no calcula nada. «Corregir orden» la elimina.|El orden de cálculo tiene {n} entradas que no calculan nada. «Corregir orden» las elimina.
|
||||
@plural {fields} reads it|{fields} read it {fields} lo lee|{fields} lo leen
|
||||
@plural {n} field shows an old value|{n} fields show old values {n} campo muestra un valor antiguo|{n} campos muestran valores antiguos
|
||||
@plural {field} calculates before {fields}, which it reads.|{field} calculates before {fields}, which it reads. {field} se calcula antes que {fields}, que lee.|{field} se calcula antes que {fields}, que lee.
|
||||
@plural {n} more field calculates too early.|{n} more fields calculate too early. {n} campo más se calcula demasiado pronto.|{n} campos más se calculan demasiado pronto.
|
||||
@plural {fields} is missing from the order saved in the PDF, so other PDF viewers may not calculate it.|{fields} are missing from the order saved in the PDF, so other PDF viewers may not calculate them. {fields} falta en el orden guardado en el PDF, así que otros visores de PDF podrían no calcularlo.|{fields} faltan en el orden guardado en el PDF, así que otros visores de PDF podrían no calcularlos.
|
||||
Scan Escanear
|
||||
Sign a sheet of white paper and take a photo of it in bright, even light (use the flash). Choose the photo or drop it here: PdfCraft finds the signature and removes the paper. Firma en una hoja de papel blanco y hazle una foto con luz intensa y uniforme (usa el flash). Elige la foto o suéltala aquí: PdfCraft encuentra la firma y elimina el papel.
|
||||
Choose photo… Elegir foto…
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 6 and column 60.
|
@@ -492,6 +492,36 @@
|
||||
Could not save: {e} Impossible d'enregistrer : {e}
|
||||
Earlier in tab order Plus tôt dans l'ordre de tabulation
|
||||
Later in tab order Plus tard dans l'ordre de tabulation
|
||||
Calculation order Ordre de calcul
|
||||
Fix order Corriger l'ordre
|
||||
Move only what must move, so every field calculates after the fields it reads. Ne déplacer que ce qui doit l'être, pour que chaque champ soit calculé après les champs qu'il lit.
|
||||
Earlier in calculation order Plus tôt dans l'ordre de calcul
|
||||
Later in calculation order Plus tard dans l'ordre de calcul
|
||||
Too early Trop tôt
|
||||
Reads {name}, which calculates later, so it shows an old value. Lit {name}, qui est calculé plus tard : il affiche donc une ancienne valeur.
|
||||
Loop Boucle
|
||||
Reads {names}, which read it back. No order can fix a loop: change one of the formulas. Lit {names}, qui le lisent en retour. Aucun ordre ne peut corriger une boucle : modifiez l'une des formules.
|
||||
Not in order Hors de l'ordre
|
||||
Missing from the calculation order saved in the PDF: other PDF viewers may not calculate it. Absent de l'ordre de calcul enregistré dans le PDF : d'autres lecteurs PDF risquent de ne pas le calculer.
|
||||
Back to Prepare a form Retour à Préparer un formulaire
|
||||
No field in this form calculates its value yet. Give a field a calculation on the Calculate tab of its properties, and it shows here. Aucun champ de ce formulaire ne calcule encore sa valeur. Donnez un calcul à un champ dans l'onglet Calculer de ses propriétés, et il apparaîtra ici.
|
||||
{names} and {last} {names} et {last}
|
||||
{field} reads no other field {field} ne lit aucun autre champ
|
||||
{field} reads {fields} {field} lit {fields}
|
||||
No field reads it Aucun champ ne le lit
|
||||
The order saved in the PDF needs tidying L'ordre enregistré dans le PDF doit être nettoyé
|
||||
Moves only what must move Déplace seulement ce qui doit l'être
|
||||
Every field calculates after the fields it reads. Chaque champ est calculé après les champs qu'il lit.
|
||||
Every field outside a loop calculates after the fields it reads. Chaque champ hors d'une boucle est calculé après les champs qu'il lit.
|
||||
{field} reads its own value {field} lit sa propre valeur
|
||||
{fields} read each other {fields} se lisent mutuellement
|
||||
No order can fix a loop. Change one of the formulas. Aucun ordre ne peut corriger une boucle. Modifiez l'une des formules.
|
||||
Edit {field}'s formula Modifier la formule de {field}
|
||||
Order · top calculates first Ordre · le haut est calculé en premier
|
||||
Script Script
|
||||
Links on page Liens sur la page
|
||||
Show on the page which fields each field reads Afficher sur la page les champs que lit chaque champ
|
||||
Drag a field to move it, or select it and press {up} or {down}. Faites glisser un champ pour le déplacer, ou sélectionnez-le et appuyez sur {up} ou {down}.
|
||||
From: De :
|
||||
To: À :
|
||||
High Resolution Haute résolution
|
||||
@@ -2343,6 +2373,12 @@ animation effects Off Désactivés
|
||||
no output folder was chosen aucun dossier de sortie choisi
|
||||
@plural Downloaded {n} PDF|Downloaded {n} PDFs {n} PDF téléchargé|{n} PDF téléchargés
|
||||
@plural {n} calculation now uses the new name.|{n} calculations now use the new name. {n} calcul utilise désormais le nouveau nom.|{n} calculs utilisent désormais le nouveau nom.
|
||||
@plural The calculation order has {n} entry that calculates nothing. Fix order removes it.|The calculation order has {n} entries that calculate nothing. Fix order removes them. L'ordre de calcul contient {n} entrée qui ne calcule rien. « Corriger l'ordre » la supprime.|L'ordre de calcul contient {n} entrées qui ne calculent rien. « Corriger l'ordre » les supprime.
|
||||
@plural {fields} reads it|{fields} read it {fields} le lit|{fields} le lisent
|
||||
@plural {n} field shows an old value|{n} fields show old values {n} champ affiche une ancienne valeur|{n} champs affichent d'anciennes valeurs
|
||||
@plural {field} calculates before {fields}, which it reads.|{field} calculates before {fields}, which it reads. {field} est calculé avant {fields}, qu'il lit.|{field} est calculé avant {fields}, qu'il lit.
|
||||
@plural {n} more field calculates too early.|{n} more fields calculate too early. {n} autre champ est calculé trop tôt.|{n} autres champs sont calculés trop tôt.
|
||||
@plural {fields} is missing from the order saved in the PDF, so other PDF viewers may not calculate it.|{fields} are missing from the order saved in the PDF, so other PDF viewers may not calculate them. {fields} manque dans l'ordre enregistré dans le PDF, donc d'autres lecteurs PDF risquent de ne pas le calculer.|{fields} manquent dans l'ordre enregistré dans le PDF, donc d'autres lecteurs PDF risquent de ne pas les calculer.
|
||||
Scan Numériser
|
||||
Sign a sheet of white paper and take a photo of it in bright, even light (use the flash). Choose the photo or drop it here: PdfCraft finds the signature and removes the paper. Signez une feuille de papier blanc et prenez-la en photo sous une lumière vive et uniforme (utilisez le flash). Choisissez la photo ou déposez-la ici : PdfCraft trouve la signature et retire le papier.
|
||||
Choose photo… Choisir une photo…
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 6 and column 39.
|
@@ -490,6 +490,36 @@
|
||||
Could not save: {e} A mentés nem sikerült: {e}
|
||||
Earlier in tab order Előbbre a tab-sorrendben
|
||||
Later in tab order Hátrébb a tab-sorrendben
|
||||
Calculation order Számítási sorrend
|
||||
Fix order Sorrend javítása
|
||||
Move only what must move, so every field calculates after the fields it reads. Csak azt mozgatja, amit muszáj, hogy minden mező az általa olvasott mezők után számítódjon.
|
||||
Earlier in calculation order Előbbre a számítási sorrendben
|
||||
Later in calculation order Hátrébb a számítási sorrendben
|
||||
Too early Túl korán
|
||||
Reads {name}, which calculates later, so it shows an old value. Ezt olvassa: {name}, amely később számítódik, ezért régi értéket mutat.
|
||||
Loop Hurok
|
||||
Reads {names}, which read it back. No order can fix a loop: change one of the formulas. Ezeket olvassa: {names}, amelyek visszaolvassák. Hurkot semmilyen sorrend nem javít meg: módosítsd az egyik képletet.
|
||||
Not in order Nincs a sorrendben
|
||||
Missing from the calculation order saved in the PDF: other PDF viewers may not calculate it. Hiányzik a PDF-ben mentett számítási sorrendből: más PDF-megjelenítők talán nem számítják ki.
|
||||
Back to Prepare a form Vissza az Űrlap előkészítéséhez
|
||||
No field in this form calculates its value yet. Give a field a calculation on the Calculate tab of its properties, and it shows here. Ennek az űrlapnak még egyik mezője sem számítja ki az értékét. Adj egy mezőnek számítást a tulajdonságai Számítás lapján, és itt megjelenik.
|
||||
{names} and {last} {names} és {last}
|
||||
{field} reads no other field {field} nem olvas más mezőt
|
||||
{field} reads {fields} {field} olvassa: {fields}
|
||||
No field reads it Egyik mező sem olvassa
|
||||
The order saved in the PDF needs tidying A PDF-ben mentett sorrend rendbetételre szorul
|
||||
Moves only what must move Csak azt mozgatja, amit muszáj
|
||||
Every field calculates after the fields it reads. Minden mező az általa olvasott mezők után számítódik.
|
||||
Every field outside a loop calculates after the fields it reads. A hurkokon kívül minden mező az általa olvasott mezők után számítódik.
|
||||
{field} reads its own value {field} a saját értékét olvassa
|
||||
{fields} read each other {fields} egymást olvassák
|
||||
No order can fix a loop. Change one of the formulas. Egy hurkot semmilyen sorrend nem javít meg. Módosítsd az egyik képletet.
|
||||
Edit {field}'s formula {field} képletének szerkesztése
|
||||
Order · top calculates first Sorrend · a felső számítódik először
|
||||
Script Szkript
|
||||
Links on page Kapcsolatok az oldalon
|
||||
Show on the page which fields each field reads Az oldalon mutatja, melyik mező mely mezőket olvassa
|
||||
Drag a field to move it, or select it and press {up} or {down}. Húzz el egy mezőt az áthelyezéshez, vagy jelöld ki, és nyomd meg ezt: {up} vagy {down}.
|
||||
From: Ettől:
|
||||
To: Eddig:
|
||||
High Resolution Nagy felbontás
|
||||
@@ -2342,6 +2372,12 @@ animation effects Off Ki
|
||||
no output folder was chosen nincs kiválasztva kimeneti mappa
|
||||
@plural Downloaded {n} PDF|Downloaded {n} PDFs {n} PDF letöltve|{n} PDF letöltve
|
||||
@plural {n} calculation now uses the new name.|{n} calculations now use the new name. {n} számítás mostantól az új nevet használja.|{n} számítás mostantól az új nevet használja.
|
||||
@plural The calculation order has {n} entry that calculates nothing. Fix order removes it.|The calculation order has {n} entries that calculate nothing. Fix order removes them. A számítási sorrendben {n} bejegyzés semmit nem számít ki. A „Sorrend javítása” eltávolítja.|A számítási sorrendben {n} bejegyzés semmit nem számít ki. A „Sorrend javítása” eltávolítja őket.
|
||||
@plural {fields} reads it|{fields} read it {fields} olvassa|{fields} olvassák
|
||||
@plural {n} field shows an old value|{n} fields show old values {n} mező régi értéket mutat|{n} mező régi értéket mutat
|
||||
@plural {field} calculates before {fields}, which it reads.|{field} calculates before {fields}, which it reads. {field} előbb számítódik, mint {fields}, amelyet olvas.|{field} előbb számítódik, mint {fields}, amelyeket olvas.
|
||||
@plural {n} more field calculates too early.|{n} more fields calculate too early. További {n} mező túl korán számítódik.|További {n} mező túl korán számítódik.
|
||||
@plural {fields} is missing from the order saved in the PDF, so other PDF viewers may not calculate it.|{fields} are missing from the order saved in the PDF, so other PDF viewers may not calculate them. {fields} hiányzik a PDF-ben mentett sorrendből, ezért más PDF-megjelenítők esetleg nem számítják ki.|{fields} hiányoznak a PDF-ben mentett sorrendből, ezért más PDF-megjelenítők esetleg nem számítják ki őket.
|
||||
Scan Beolvasás
|
||||
Sign a sheet of white paper and take a photo of it in bright, even light (use the flash). Choose the photo or drop it here: PdfCraft finds the signature and removes the paper. Írja alá a nevét egy fehér papírlapon, és fényképezze le erős, egyenletes fényben (vakuval). Válassza ki a fényképet, vagy húzza ide: a PdfCraft megkeresi az aláírást, és eltávolítja a papírt.
|
||||
Choose photo… Fénykép kiválasztása…
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 7 and column 44.
|
@@ -516,6 +516,36 @@
|
||||
Could not save: {e} Impossibile salvare: {e}
|
||||
Earlier in tab order Prima nell'ordine di tabulazione
|
||||
Later in tab order Dopo nell'ordine di tabulazione
|
||||
Calculation order Ordine di calcolo
|
||||
Fix order Correggi ordine
|
||||
Move only what must move, so every field calculates after the fields it reads. Sposta solo ciò che deve spostarsi, così ogni campo viene calcolato dopo i campi che legge.
|
||||
Earlier in calculation order Prima nell'ordine di calcolo
|
||||
Later in calculation order Dopo nell'ordine di calcolo
|
||||
Too early Troppo presto
|
||||
Reads {name}, which calculates later, so it shows an old value. Legge {name}, che viene calcolato dopo, quindi mostra un valore vecchio.
|
||||
Loop Ciclo
|
||||
Reads {names}, which read it back. No order can fix a loop: change one of the formulas. Legge {names}, che a loro volta lo leggono. Nessun ordine può correggere un ciclo: modifica una delle formule.
|
||||
Not in order Fuori ordine
|
||||
Missing from the calculation order saved in the PDF: other PDF viewers may not calculate it. Manca nell'ordine di calcolo salvato nel PDF: altri visualizzatori PDF potrebbero non calcolarlo.
|
||||
Back to Prepare a form Torna a Prepara un modulo
|
||||
No field in this form calculates its value yet. Give a field a calculation on the Calculate tab of its properties, and it shows here. Nessun campo di questo modulo calcola ancora il proprio valore. Assegna un calcolo a un campo nella scheda Calcolo delle sue proprietà e comparirà qui.
|
||||
{names} and {last} {names} e {last}
|
||||
{field} reads no other field {field} non legge nessun altro campo
|
||||
{field} reads {fields} {field} legge {fields}
|
||||
No field reads it Nessun campo lo legge
|
||||
The order saved in the PDF needs tidying L'ordine salvato nel PDF va riordinato
|
||||
Moves only what must move Sposta solo ciò che va spostato
|
||||
Every field calculates after the fields it reads. Ogni campo viene calcolato dopo i campi che legge.
|
||||
Every field outside a loop calculates after the fields it reads. Ogni campo fuori da un ciclo viene calcolato dopo i campi che legge.
|
||||
{field} reads its own value {field} legge il proprio valore
|
||||
{fields} read each other {fields} si leggono a vicenda
|
||||
No order can fix a loop. Change one of the formulas. Nessun ordine può correggere un ciclo. Modifica una delle formule.
|
||||
Edit {field}'s formula Modifica la formula di {field}
|
||||
Order · top calculates first Ordine · in alto si calcola per primo
|
||||
Script Script
|
||||
Links on page Collegamenti sulla pagina
|
||||
Show on the page which fields each field reads Mostra sulla pagina quali campi legge ogni campo
|
||||
Drag a field to move it, or select it and press {up} or {down}. Trascina un campo per spostarlo, oppure selezionalo e premi {up} o {down}.
|
||||
From: Da:
|
||||
To: A:
|
||||
High Resolution Alta risoluzione
|
||||
@@ -2352,6 +2382,12 @@ animation effects Off Disattivati
|
||||
no output folder was chosen nessuna cartella di output scelta
|
||||
@plural Downloaded {n} PDF|Downloaded {n} PDFs Scaricato {n} PDF|Scaricati {n} PDF
|
||||
@plural {n} calculation now uses the new name.|{n} calculations now use the new name. {n} calcolo ora usa il nuovo nome.|{n} calcoli ora usano il nuovo nome.
|
||||
@plural The calculation order has {n} entry that calculates nothing. Fix order removes it.|The calculation order has {n} entries that calculate nothing. Fix order removes them. L'ordine di calcolo ha {n} voce che non calcola nulla. «Correggi ordine» la rimuove.|L'ordine di calcolo ha {n} voci che non calcolano nulla. «Correggi ordine» le rimuove.
|
||||
@plural {fields} reads it|{fields} read it {fields} lo legge|{fields} lo leggono
|
||||
@plural {n} field shows an old value|{n} fields show old values {n} campo mostra un valore vecchio|{n} campi mostrano valori vecchi
|
||||
@plural {field} calculates before {fields}, which it reads.|{field} calculates before {fields}, which it reads. {field} viene calcolato prima di {fields}, che legge.|{field} viene calcolato prima di {fields}, che legge.
|
||||
@plural {n} more field calculates too early.|{n} more fields calculate too early. Ancora {n} campo viene calcolato troppo presto.|Altri {n} campi vengono calcolati troppo presto.
|
||||
@plural {fields} is missing from the order saved in the PDF, so other PDF viewers may not calculate it.|{fields} are missing from the order saved in the PDF, so other PDF viewers may not calculate them. {fields} manca nell'ordine salvato nel PDF, quindi altri visualizzatori PDF potrebbero non calcolarlo.|{fields} mancano nell'ordine salvato nel PDF, quindi altri visualizzatori PDF potrebbero non calcolarli.
|
||||
Scan Scansiona
|
||||
Sign a sheet of white paper and take a photo of it in bright, even light (use the flash). Choose the photo or drop it here: PdfCraft finds the signature and removes the paper. Firma un foglio di carta bianca e fotografalo con una luce intensa e uniforme (usa il flash). Scegli la foto o trascinala qui: PdfCraft trova la firma e rimuove la carta.
|
||||
Choose photo… Scegli foto…
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 6 and column 47.
|
@@ -519,6 +519,36 @@
|
||||
Could not save: {e} 保存できませんでした: {e}
|
||||
Earlier in tab order タブ順序を前へ
|
||||
Later in tab order タブ順序を後ろへ
|
||||
Calculation order 計算順序
|
||||
Fix order 順序を修正
|
||||
Move only what must move, so every field calculates after the fields it reads. 各フィールドが読み取るフィールドの後に計算されるよう、必要なものだけを移動します。
|
||||
Earlier in calculation order 計算順序を前へ
|
||||
Later in calculation order 計算順序を後ろへ
|
||||
Too early 早すぎる
|
||||
Reads {name}, which calculates later, so it shows an old value. 後で計算される {name} を読み取るため、古い値を表示します。
|
||||
Loop 循環
|
||||
Reads {names}, which read it back. No order can fix a loop: change one of the formulas. {names} を読み取り、それらがこのフィールドを読み返します。循環はどの順序でも直せません。いずれかの数式を変更してください。
|
||||
Not in order 順序にない
|
||||
Missing from the calculation order saved in the PDF: other PDF viewers may not calculate it. PDF に保存された計算順序にありません。ほかの PDF ビューアーでは計算されない可能性があります。
|
||||
Back to Prepare a form 「フォームを作成」に戻る
|
||||
No field in this form calculates its value yet. Give a field a calculation on the Calculate tab of its properties, and it shows here. このフォームには値を計算するフィールドがまだありません。フィールドのプロパティの[計算]タブで計算を設定すると、ここに表示されます。
|
||||
{names} and {last} {names}、{last}
|
||||
{field} reads no other field {field} は他のフィールドを読み取りません
|
||||
{field} reads {fields} {field} は {fields} を読み取ります
|
||||
No field reads it 読み取るフィールドはありません
|
||||
The order saved in the PDF needs tidying PDF に保存された順序の整理が必要です
|
||||
Moves only what must move 必要な分だけ移動します
|
||||
Every field calculates after the fields it reads. すべてのフィールドが、読み取るフィールドの後に計算されます。
|
||||
Every field outside a loop calculates after the fields it reads. 循環の外にあるすべてのフィールドが、読み取るフィールドの後に計算されます。
|
||||
{field} reads its own value {field} は自分の値を読み取ります
|
||||
{fields} read each other {fields} は互いを読み取ります
|
||||
No order can fix a loop. Change one of the formulas. 循環はどの順序でも直せません。いずれかの数式を変更してください。
|
||||
Edit {field}'s formula {field} の数式を編集
|
||||
Order · top calculates first 順序 · 上から計算
|
||||
Script スクリプト
|
||||
Links on page ページ上のリンク
|
||||
Show on the page which fields each field reads 各フィールドが読み取るフィールドをページ上に表示します
|
||||
Drag a field to move it, or select it and press {up} or {down}. フィールドをドラッグして移動するか、選択して {up} または {down} を押します。
|
||||
From: 開始:
|
||||
To: 終了:
|
||||
High Resolution 高解像度
|
||||
@@ -2343,6 +2373,12 @@ animation effects Off オフ
|
||||
no output folder was chosen 出力フォルダーが選択されていません
|
||||
@plural Downloaded {n} PDF|Downloaded {n} PDFs {n} 個の PDF をダウンロードしました
|
||||
@plural {n} calculation now uses the new name.|{n} calculations now use the new name. {n} 件の計算式を新しい名前に更新しました。
|
||||
@plural The calculation order has {n} entry that calculates nothing. Fix order removes it.|The calculation order has {n} entries that calculate nothing. Fix order removes them. 計算順序に、何も計算しない項目が {n} 件あります。「順序を修正」で削除されます。
|
||||
@plural {fields} reads it|{fields} read it {fields} が読み取ります
|
||||
@plural {n} field shows an old value|{n} fields show old values {n} 個のフィールドが古い値を表示しています
|
||||
@plural {field} calculates before {fields}, which it reads.|{field} calculates before {fields}, which it reads. {field} は、読み取る {fields} より先に計算されます。
|
||||
@plural {n} more field calculates too early.|{n} more fields calculate too early. さらに {n} 個のフィールドが早すぎます。
|
||||
@plural {fields} is missing from the order saved in the PDF, so other PDF viewers may not calculate it.|{fields} are missing from the order saved in the PDF, so other PDF viewers may not calculate them. {fields} は PDF に保存された順序にないため、他の PDF ビューアーでは計算されない場合があります。
|
||||
Scan スキャン
|
||||
Sign a sheet of white paper and take a photo of it in bright, even light (use the flash). Choose the photo or drop it here: PdfCraft finds the signature and removes the paper. 白い紙に署名し、明るく均一な光の下で写真を撮ってください(フラッシュを使用)。写真を選択するか、ここにドロップしてください。PdfCraft が署名を見つけ、紙の部分を取り除きます。
|
||||
Choose photo… 写真を選択…
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 6 and column 47.
|
@@ -479,6 +479,36 @@
|
||||
Could not save: {e} Сақтау мүмкін болмады: {e}
|
||||
Earlier in tab order Табуляция реті бойынша алдыңғы
|
||||
Later in tab order Табуляция реті бойынша кейінгі
|
||||
Calculation order Есептеу реті
|
||||
Fix order Ретті түзету
|
||||
Move only what must move, so every field calculates after the fields it reads. Әр өріс өзі оқитын өрістерден кейін есептелуі үшін тек жылжуы қажет нәрсені ғана жылжытады.
|
||||
Earlier in calculation order Есептеу реті бойынша алдыңғы
|
||||
Later in calculation order Есептеу реті бойынша кейінгі
|
||||
Too early Тым ерте
|
||||
Reads {name}, which calculates later, so it shows an old value. {name} өрісін оқиды, ол кейінірек есептеледі, сондықтан ескі мәнді көрсетеді.
|
||||
Loop Цикл
|
||||
Reads {names}, which read it back. No order can fix a loop: change one of the formulas. {names} өрістерін оқиды, олар оны қайта оқиды. Ешбір рет циклды түзете алмайды: формулалардың бірін өзгертіңіз.
|
||||
Not in order Ретте жоқ
|
||||
Missing from the calculation order saved in the PDF: other PDF viewers may not calculate it. PDF ішінде сақталған есептеу ретінде жоқ: басқа PDF қарау құралдары оны есептемеуі мүмкін.
|
||||
Back to Prepare a form Форманы дайындауға оралу
|
||||
No field in this form calculates its value yet. Give a field a calculation on the Calculate tab of its properties, and it shows here. Бұл формада мәнін есептейтін өріс әлі жоқ. Өріс сипаттарының «Есептеу» қойындысында оған есептеу беріңіз, сонда ол осында көрсетіледі.
|
||||
{names} and {last} {names} және {last}
|
||||
{field} reads no other field {field} басқа өрісті оқымайды
|
||||
{field} reads {fields} {field} мыналарды оқиды: {fields}
|
||||
No field reads it Оны ешбір өріс оқымайды
|
||||
The order saved in the PDF needs tidying PDF-те сақталған ретті ретке келтіру керек
|
||||
Moves only what must move Тек жылжуы тиістіні ғана жылжытады
|
||||
Every field calculates after the fields it reads. Әр өріс өзі оқитын өрістерден кейін есептеледі.
|
||||
Every field outside a loop calculates after the fields it reads. Циклден тыс әр өріс өзі оқитын өрістерден кейін есептеледі.
|
||||
{field} reads its own value {field} өз мәнін оқиды
|
||||
{fields} read each other {fields} бірін-бірі оқиды
|
||||
No order can fix a loop. Change one of the formulas. Ешбір рет циклді түзете алмайды. Формулалардың бірін өзгертіңіз.
|
||||
Edit {field}'s formula {field} формуласын өңдеу
|
||||
Order · top calculates first Рет · жоғарғысы бірінші есептеледі
|
||||
Script Скрипт
|
||||
Links on page Беттегі байланыстар
|
||||
Show on the page which fields each field reads Әр өріс қай өрістерді оқитынын бетте көрсету
|
||||
Drag a field to move it, or select it and press {up} or {down}. Өрісті жылжыту үшін сүйреңіз немесе оны таңдап, {up} не {down} пернесін басыңыз.
|
||||
From: Бастап:
|
||||
To: Дейін:
|
||||
High Resolution Жоғары ажыратымдылық
|
||||
@@ -2330,6 +2360,12 @@ animation effects Off Өшірулі
|
||||
no output folder was chosen шығыс қалтасы таңдалмады
|
||||
@plural Downloaded {n} PDF|Downloaded {n} PDFs {n} PDF жүктелді|{n} PDF жүктелді
|
||||
@plural {n} calculation now uses the new name.|{n} calculations now use the new name. {n} есептеу енді жаңа атауды пайдаланады.|{n} есептеу енді жаңа атауды пайдаланады.
|
||||
@plural The calculation order has {n} entry that calculates nothing. Fix order removes it.|The calculation order has {n} entries that calculate nothing. Fix order removes them. Есептеу ретінде ештеңе есептемейтін {n} жазба бар. «Ретті түзету» оны жояды.|Есептеу ретінде ештеңе есептемейтін {n} жазба бар. «Ретті түзету» оларды жояды.
|
||||
@plural {fields} reads it|{fields} read it Оны {fields} оқиды|Оны {fields} оқиды
|
||||
@plural {n} field shows an old value|{n} fields show old values {n} өріс ескі мәнді көрсетеді|{n} өріс ескі мәндерді көрсетеді
|
||||
@plural {field} calculates before {fields}, which it reads.|{field} calculates before {fields}, which it reads. {field} өзі оқитын {fields} өрісінен бұрын есептеледі.|{field} өзі оқитын {fields} өрістерінен бұрын есептеледі.
|
||||
@plural {n} more field calculates too early.|{n} more fields calculate too early. Тағы {n} өріс тым ерте есептеледі.|Тағы {n} өріс тым ерте есептеледі.
|
||||
@plural {fields} is missing from the order saved in the PDF, so other PDF viewers may not calculate it.|{fields} are missing from the order saved in the PDF, so other PDF viewers may not calculate them. {fields} PDF-те сақталған ретте жоқ, сондықтан басқа PDF қаралымдары оны есептемеуі мүмкін.|{fields} PDF-те сақталған ретте жоқ, сондықтан басқа PDF қаралымдары оларды есептемеуі мүмкін.
|
||||
@plural {n} field name collides with earlier files and will be renamed: {list}|{n} field names collide with earlier files and will be renamed: {list} {n} өріс атауы алдыңғы файлдармен қайшы келеді және қайта аталады: {list}|{n} өріс атауы алдыңғы файлдармен қайшы келеді және қайта аталады: {list}
|
||||
Scan Сканерлеу
|
||||
Sign a sheet of white paper and take a photo of it in bright, even light (use the flash). Choose the photo or drop it here: PdfCraft finds the signature and removes the paper. Ақ қағаз парағына қол қойып, оны жарық әрі біркелкі жарықта суретке түсіріңіз (жарқылды қосыңыз). Суретті таңдаңыз немесе осында тастаңыз: PdfCraft қолтаңбаны тауып, қағазды алып тастайды.
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 856 and column 9.
|
@@ -685,6 +685,36 @@
|
||||
Larger pages Didesni puslapiai
|
||||
Later Vėliau
|
||||
Later in tab order Vėlesnė skirtukų tvarka
|
||||
Calculation order Skaičiavimo tvarka
|
||||
Fix order Pataisyti tvarką
|
||||
Move only what must move, so every field calculates after the fields it reads. Perkelia tik tai, ką būtina, kad kiekvienas laukas būtų skaičiuojamas po laukų, kuriuos jis skaito.
|
||||
Earlier in calculation order Anksčiau skaičiavimo tvarkoje
|
||||
Later in calculation order Vėliau skaičiavimo tvarkoje
|
||||
Too early Per anksti
|
||||
Reads {name}, which calculates later, so it shows an old value. Skaito {name}, kuris skaičiuojamas vėliau, todėl rodo seną reikšmę.
|
||||
Loop Ciklas
|
||||
Reads {names}, which read it back. No order can fix a loop: change one of the formulas. Skaito {names}, kurie savo ruožtu skaito jį. Jokia tvarka neištaisys ciklo: pakeiskite vieną iš formulių.
|
||||
Not in order Ne tvarkoje
|
||||
Missing from the calculation order saved in the PDF: other PDF viewers may not calculate it. Trūksta PDF faile įrašytoje skaičiavimo tvarkoje: kitos PDF peržiūros programos gali jo neskaičiuoti.
|
||||
Back to Prepare a form Grįžti į „Rengti formą“
|
||||
No field in this form calculates its value yet. Give a field a calculation on the Calculate tab of its properties, and it shows here. Nė vienas šios formos laukas dar neskaičiuoja savo reikšmės. Nustatykite laukui skaičiavimą jo savybių kortelėje „Skaičiavimas“, ir jis bus rodomas čia.
|
||||
{names} and {last} {names} ir {last}
|
||||
{field} reads no other field {field} neskaito jokio kito lauko
|
||||
{field} reads {fields} {field} skaito {fields}
|
||||
No field reads it Jo neskaito joks laukas
|
||||
The order saved in the PDF needs tidying PDF faile įrašytą tvarką reikia sutvarkyti
|
||||
Moves only what must move Perkelia tik tai, ką būtina
|
||||
Every field calculates after the fields it reads. Kiekvienas laukas apskaičiuojamas po laukų, kuriuos skaito.
|
||||
Every field outside a loop calculates after the fields it reads. Kiekvienas laukas už ciklo ribų apskaičiuojamas po laukų, kuriuos skaito.
|
||||
{field} reads its own value {field} skaito savo paties reikšmę
|
||||
{fields} read each other {fields} skaito vienas kitą
|
||||
No order can fix a loop. Change one of the formulas. Jokia tvarka neištaisys ciklo. Pakeiskite vieną iš formulių.
|
||||
Edit {field}'s formula Redaguoti lauko {field} formulę
|
||||
Order · top calculates first Tvarka · viršutinis apskaičiuojamas pirmas
|
||||
Script Scenarijus
|
||||
Links on page Ryšiai puslapyje
|
||||
Show on the page which fields each field reads Rodyti puslapyje, kuriuos laukus skaito kiekvienas laukas
|
||||
Drag a field to move it, or select it and press {up} or {down}. Vilkite lauką, kad jį perkeltumėte, arba pažymėkite jį ir paspauskite {up} arba {down}.
|
||||
Layers Sluoksniai
|
||||
Layers Panel and Page Sluoksnių skydelis ir puslapis
|
||||
Layout and Magnification Išdėstymas ir mastelis
|
||||
@@ -2600,6 +2630,12 @@ certificate SHA-256 digest SHA-256 santrauka
|
||||
@plural {n} object selected|{n} objects selected Pažymėtas {n} objektas|Pažymėti {n} objektai|Pažymėta {n} objektų
|
||||
@plural Downloaded {n} PDF|Downloaded {n} PDFs Atsisiųstas {n} PDF failas|Atsisiųsti {n} PDF failai|Atsisiųsta {n} PDF failų
|
||||
@plural {n} calculation now uses the new name.|{n} calculations now use the new name. {n} skaičiavimas dabar naudoja naują pavadinimą.|{n} skaičiavimai dabar naudoja naują pavadinimą.|{n} skaičiavimų dabar naudoja naują pavadinimą.
|
||||
@plural The calculation order has {n} entry that calculates nothing. Fix order removes it.|The calculation order has {n} entries that calculate nothing. Fix order removes them. Skaičiavimo tvarkoje yra {n} įrašas, kuris nieko neskaičiuoja. „Pataisyti tvarką“ jį pašalina.|Skaičiavimo tvarkoje yra {n} įrašai, kurie nieko neskaičiuoja. „Pataisyti tvarką“ juos pašalina.|Skaičiavimo tvarkoje yra {n} įrašų, kurie nieko neskaičiuoja. „Pataisyti tvarką“ juos pašalina.
|
||||
@plural {fields} reads it|{fields} read it {fields} jį skaito|{fields} jį skaito|{fields} jį skaito
|
||||
@plural {n} field shows an old value|{n} fields show old values {n} laukas rodo seną reikšmę|{n} laukai rodo senas reikšmes|{n} laukų rodo senas reikšmes
|
||||
@plural {field} calculates before {fields}, which it reads.|{field} calculates before {fields}, which it reads. {field} apskaičiuojamas anksčiau už {fields}, kurį skaito.|{field} apskaičiuojamas anksčiau už {fields}, kuriuos skaito.|{field} apskaičiuojamas anksčiau už {fields}, kuriuos skaito.
|
||||
@plural {n} more field calculates too early.|{n} more fields calculate too early. Dar {n} laukas apskaičiuojamas per anksti.|Dar {n} laukai apskaičiuojami per anksti.|Dar {n} laukų apskaičiuojama per anksti.
|
||||
@plural {fields} is missing from the order saved in the PDF, so other PDF viewers may not calculate it.|{fields} are missing from the order saved in the PDF, so other PDF viewers may not calculate them. {fields} nėra PDF faile įrašytoje tvarkoje, todėl kitos PDF peržiūros programos gali jo neapskaičiuoti.|{fields} nėra PDF faile įrašytoje tvarkoje, todėl kitos PDF peržiūros programos gali jų neapskaičiuoti.|{fields} nėra PDF faile įrašytoje tvarkoje, todėl kitos PDF peržiūros programos gali jų neapskaičiuoti.
|
||||
key Ctrl Ctrl
|
||||
key Shift Shift
|
||||
key Delete Delete
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 404 and column 9.
|
@@ -514,6 +514,36 @@
|
||||
Could not save: {e} Nie można zapisać: {e}
|
||||
Earlier in tab order Wcześniej w kolejności tabulacji
|
||||
Later in tab order Później w kolejności tabulacji
|
||||
Calculation order Kolejność obliczeń
|
||||
Fix order Popraw kolejność
|
||||
Move only what must move, so every field calculates after the fields it reads. Przenosi tylko to, co musi, aby każde pole było obliczane po polach, które odczytuje.
|
||||
Earlier in calculation order Wcześniej w kolejności obliczeń
|
||||
Later in calculation order Później w kolejności obliczeń
|
||||
Too early Za wcześnie
|
||||
Reads {name}, which calculates later, so it shows an old value. Odczytuje {name}, które jest obliczane później, więc pokazuje starą wartość.
|
||||
Loop Pętla
|
||||
Reads {names}, which read it back. No order can fix a loop: change one of the formulas. Odczytuje {names}, które z kolei odczytują je. Żadna kolejność nie naprawi pętli: zmień jedną z formuł.
|
||||
Not in order Poza kolejnością
|
||||
Missing from the calculation order saved in the PDF: other PDF viewers may not calculate it. Brakuje go w kolejności obliczeń zapisanej w pliku PDF: inne przeglądarki PDF mogą go nie obliczać.
|
||||
Back to Prepare a form Wróć do „Przygotuj formularz”
|
||||
No field in this form calculates its value yet. Give a field a calculation on the Calculate tab of its properties, and it shows here. Żadne pole tego formularza nie oblicza jeszcze swojej wartości. Nadaj polu obliczenie na karcie Obliczenia w jego właściwościach, a pojawi się tutaj.
|
||||
{names} and {last} {names} i {last}
|
||||
{field} reads no other field {field} nie odczytuje żadnego innego pola
|
||||
{field} reads {fields} {field} odczytuje {fields}
|
||||
No field reads it Żadne pole go nie odczytuje
|
||||
The order saved in the PDF needs tidying Kolejność zapisana w pliku PDF wymaga uporządkowania
|
||||
Moves only what must move Przesuwa tylko to, co trzeba
|
||||
Every field calculates after the fields it reads. Każde pole jest obliczane po polach, które odczytuje.
|
||||
Every field outside a loop calculates after the fields it reads. Każde pole poza pętlą jest obliczane po polach, które odczytuje.
|
||||
{field} reads its own value {field} odczytuje własną wartość
|
||||
{fields} read each other {fields} odczytują się nawzajem
|
||||
No order can fix a loop. Change one of the formulas. Żadna kolejność nie naprawi pętli. Zmień jedną z formuł.
|
||||
Edit {field}'s formula Edytuj formułę pola {field}
|
||||
Order · top calculates first Kolejność · najpierw obliczane jest górne
|
||||
Script Skrypt
|
||||
Links on page Powiązania na stronie
|
||||
Show on the page which fields each field reads Pokaż na stronie, które pola odczytuje każde pole
|
||||
Drag a field to move it, or select it and press {up} or {down}. Przeciągnij pole, aby je przenieść, albo zaznacz je i naciśnij {up} lub {down}.
|
||||
From: Od:
|
||||
To: Do:
|
||||
High Resolution Wysoka rozdzielczość
|
||||
@@ -2311,6 +2341,12 @@ animation effects Off Wyłączone
|
||||
no output folder was chosen nie wybrano folderu wyjściowego
|
||||
@plural Downloaded {n} PDF|Downloaded {n} PDFs Pobrano {n} plik PDF|Pobrano {n} pliki PDF|Pobrano {n} plików PDF
|
||||
@plural {n} calculation now uses the new name.|{n} calculations now use the new name. {n} obliczenie używa teraz nowej nazwy.|{n} obliczenia używają teraz nowej nazwy.|{n} obliczeń używa teraz nowej nazwy.
|
||||
@plural The calculation order has {n} entry that calculates nothing. Fix order removes it.|The calculation order has {n} entries that calculate nothing. Fix order removes them. Kolejność obliczeń ma {n} wpis, który niczego nie oblicza. „Popraw kolejność” go usuwa.|Kolejność obliczeń ma {n} wpisy, które niczego nie obliczają. „Popraw kolejność” je usuwa.|Kolejność obliczeń ma {n} wpisów, które niczego nie obliczają. „Popraw kolejność” je usuwa.
|
||||
@plural {fields} reads it|{fields} read it {fields} go odczytuje|{fields} go odczytują|{fields} go odczytują
|
||||
@plural {n} field shows an old value|{n} fields show old values {n} pole pokazuje starą wartość|{n} pola pokazują stare wartości|{n} pól pokazuje stare wartości
|
||||
@plural {field} calculates before {fields}, which it reads.|{field} calculates before {fields}, which it reads. {field} jest obliczane przed {fields}, które odczytuje.|{field} jest obliczane przed {fields}, które odczytuje.|{field} jest obliczane przed {fields}, które odczytuje.
|
||||
@plural {n} more field calculates too early.|{n} more fields calculate too early. Jeszcze {n} pole jest obliczane za wcześnie.|Jeszcze {n} pola są obliczane za wcześnie.|Jeszcze {n} pól jest obliczanych za wcześnie.
|
||||
@plural {fields} is missing from the order saved in the PDF, so other PDF viewers may not calculate it.|{fields} are missing from the order saved in the PDF, so other PDF viewers may not calculate them. W kolejności zapisanej w pliku PDF brakuje {fields}, więc inne przeglądarki PDF mogą go nie obliczać.|W kolejności zapisanej w pliku PDF brakuje {fields}, więc inne przeglądarki PDF mogą ich nie obliczać.|W kolejności zapisanej w pliku PDF brakuje {fields}, więc inne przeglądarki PDF mogą ich nie obliczać.
|
||||
Scan Skanuj
|
||||
Sign a sheet of white paper and take a photo of it in bright, even light (use the flash). Choose the photo or drop it here: PdfCraft finds the signature and removes the paper. Podpisz się na białej kartce i zrób jej zdjęcie przy jasnym, równomiernym świetle (użyj lampy błyskowej). Wybierz zdjęcie lub upuść je tutaj: PdfCraft znajdzie podpis i usunie papier.
|
||||
Choose photo… Wybierz zdjęcie…
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 6 and column 47.
|
@@ -147,6 +147,36 @@
|
||||
Could not save: {e} Não foi possível salvar: {e}
|
||||
Earlier in tab order Mais acima na ordem de tabulação
|
||||
Later in tab order Mais abaixo na ordem de tabulação
|
||||
Calculation order Ordem de cálculo
|
||||
Fix order Corrigir ordem
|
||||
Move only what must move, so every field calculates after the fields it reads. Mover só o que precisa ser movido, para que cada campo seja calculado depois dos campos que ele lê.
|
||||
Earlier in calculation order Mais acima na ordem de cálculo
|
||||
Later in calculation order Mais abaixo na ordem de cálculo
|
||||
Too early Cedo demais
|
||||
Reads {name}, which calculates later, so it shows an old value. Lê {name}, que é calculado depois, então mostra um valor antigo.
|
||||
Loop Ciclo
|
||||
Reads {names}, which read it back. No order can fix a loop: change one of the formulas. Lê {names}, que o leem de volta. Nenhuma ordem resolve um ciclo: altere uma das fórmulas.
|
||||
Not in order Fora da ordem
|
||||
Missing from the calculation order saved in the PDF: other PDF viewers may not calculate it. Ausente da ordem de cálculo salva no PDF: outros leitores de PDF podem não calculá-lo.
|
||||
Back to Prepare a form Voltar para Preparar um formulário
|
||||
No field in this form calculates its value yet. Give a field a calculation on the Calculate tab of its properties, and it shows here. Nenhum campo deste formulário calcula seu valor ainda. Dê um cálculo a um campo na aba Calcular das propriedades dele, e ele aparecerá aqui.
|
||||
{names} and {last} {names} e {last}
|
||||
{field} reads no other field {field} não lê nenhum outro campo
|
||||
{field} reads {fields} {field} lê {fields}
|
||||
No field reads it Nenhum campo o lê
|
||||
The order saved in the PDF needs tidying A ordem salva no PDF precisa de uma arrumação
|
||||
Moves only what must move Move só o que precisa mudar
|
||||
Every field calculates after the fields it reads. Cada campo é calculado depois dos campos que lê.
|
||||
Every field outside a loop calculates after the fields it reads. Cada campo fora de um ciclo é calculado depois dos campos que lê.
|
||||
{field} reads its own value {field} lê o próprio valor
|
||||
{fields} read each other {fields} leem um ao outro
|
||||
No order can fix a loop. Change one of the formulas. Nenhuma ordem corrige um ciclo. Altere uma das fórmulas.
|
||||
Edit {field}'s formula Editar a fórmula de {field}
|
||||
Order · top calculates first Ordem · o de cima é calculado primeiro
|
||||
Script Script
|
||||
Links on page Ligações na página
|
||||
Show on the page which fields each field reads Mostrar na página quais campos cada campo lê
|
||||
Drag a field to move it, or select it and press {up} or {down}. Arraste um campo para movê-lo, ou selecione-o e pressione {up} ou {down}.
|
||||
From: De:
|
||||
To: Até:
|
||||
High Resolution Alta resolução
|
||||
@@ -2357,6 +2387,12 @@ animation effects Off Desativados
|
||||
no output folder was chosen nenhuma pasta de saída foi escolhida
|
||||
@plural Downloaded {n} PDF|Downloaded {n} PDFs {n} PDF baixado|{n} PDFs baixados
|
||||
@plural {n} calculation now uses the new name.|{n} calculations now use the new name. {n} cálculo agora usa o novo nome.|{n} cálculos agora usam o novo nome.
|
||||
@plural The calculation order has {n} entry that calculates nothing. Fix order removes it.|The calculation order has {n} entries that calculate nothing. Fix order removes them. A ordem de cálculo tem {n} entrada que não calcula nada. "Corrigir ordem" a remove.|A ordem de cálculo tem {n} entradas que não calculam nada. "Corrigir ordem" as remove.
|
||||
@plural {fields} reads it|{fields} read it {fields} o lê|{fields} o leem
|
||||
@plural {n} field shows an old value|{n} fields show old values {n} campo mostra um valor antigo|{n} campos mostram valores antigos
|
||||
@plural {field} calculates before {fields}, which it reads.|{field} calculates before {fields}, which it reads. {field} é calculado antes de {fields}, que ele lê.|{field} é calculado antes de {fields}, que ele lê.
|
||||
@plural {n} more field calculates too early.|{n} more fields calculate too early. Mais {n} campo é calculado cedo demais.|Mais {n} campos são calculados cedo demais.
|
||||
@plural {fields} is missing from the order saved in the PDF, so other PDF viewers may not calculate it.|{fields} are missing from the order saved in the PDF, so other PDF viewers may not calculate them. {fields} não está na ordem salva no PDF, então outros visualizadores de PDF podem não calculá-lo.|{fields} não estão na ordem salva no PDF, então outros visualizadores de PDF podem não calculá-los.
|
||||
Scan Digitalizar
|
||||
Sign a sheet of white paper and take a photo of it in bright, even light (use the flash). Choose the photo or drop it here: PdfCraft finds the signature and removes the paper. Assine uma folha de papel branco e tire uma foto dela com luz forte e uniforme (use o flash). Escolha a foto ou solte-a aqui: o PdfCraft encontra a assinatura e remove o papel.
|
||||
Choose photo… Escolher foto…
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 9 and column 16.
|
@@ -512,6 +512,36 @@
|
||||
Could not save: {e} Не удалось сохранить: {e}
|
||||
Earlier in tab order Раньше в порядке табуляции
|
||||
Later in tab order Позже в порядке табуляции
|
||||
Calculation order Порядок вычислений
|
||||
Fix order Исправить порядок
|
||||
Move only what must move, so every field calculates after the fields it reads. Перемещает только то, что необходимо, чтобы каждое поле вычислялось после полей, которые оно читает.
|
||||
Earlier in calculation order Раньше в порядке вычислений
|
||||
Later in calculation order Позже в порядке вычислений
|
||||
Too early Слишком рано
|
||||
Reads {name}, which calculates later, so it shows an old value. Читает {name}, которое вычисляется позже, поэтому показывает старое значение.
|
||||
Loop Цикл
|
||||
Reads {names}, which read it back. No order can fix a loop: change one of the formulas. Читает {names}, которые в свою очередь читают его. Никакой порядок не исправит цикл: измените одну из формул.
|
||||
Not in order Вне порядка
|
||||
Missing from the calculation order saved in the PDF: other PDF viewers may not calculate it. Отсутствует в порядке вычислений, сохранённом в PDF: другие программы просмотра PDF могут его не вычислять.
|
||||
Back to Prepare a form Назад к «Подготовить форму»
|
||||
No field in this form calculates its value yet. Give a field a calculation on the Calculate tab of its properties, and it shows here. Ни одно поле этой формы пока не вычисляет своё значение. Задайте полю вычисление на вкладке «Вычислить» его свойств, и оно появится здесь.
|
||||
{names} and {last} {names} и {last}
|
||||
{field} reads no other field {field} не читает других полей
|
||||
{field} reads {fields} {field} читает {fields}
|
||||
No field reads it Его не читает ни одно поле
|
||||
The order saved in the PDF needs tidying Сохранённый в PDF порядок нуждается в исправлении
|
||||
Moves only what must move Перемещает только то, что нужно
|
||||
Every field calculates after the fields it reads. Каждое поле вычисляется после полей, которые оно читает.
|
||||
Every field outside a loop calculates after the fields it reads. Каждое поле вне цикла вычисляется после полей, которые оно читает.
|
||||
{field} reads its own value {field} читает собственное значение
|
||||
{fields} read each other {fields} читают друг друга
|
||||
No order can fix a loop. Change one of the formulas. Никакой порядок не исправит цикл. Измените одну из формул.
|
||||
Edit {field}'s formula Изменить формулу {field}
|
||||
Order · top calculates first Порядок · верхнее вычисляется первым
|
||||
Script Скрипт
|
||||
Links on page Связи на странице
|
||||
Show on the page which fields each field reads Показывать на странице, какие поля читает каждое поле
|
||||
Drag a field to move it, or select it and press {up} or {down}. Перетащите поле, чтобы переместить его, или выберите его и нажмите {up} или {down}.
|
||||
From: От:
|
||||
To: До:
|
||||
High Resolution Высокое разрешение
|
||||
@@ -2256,6 +2286,12 @@ animation effects Off Выкл
|
||||
no output folder was chosen не выбрана папка для вывода
|
||||
@plural Downloaded {n} PDF|Downloaded {n} PDFs Скачан {n} PDF-файл|Скачано {n} PDF-файла|Скачано {n} PDF-файлов
|
||||
@plural {n} calculation now uses the new name.|{n} calculations now use the new name. {n} вычисление теперь использует новое имя.|{n} вычисления теперь используют новое имя.|{n} вычислений теперь используют новое имя.
|
||||
@plural The calculation order has {n} entry that calculates nothing. Fix order removes it.|The calculation order has {n} entries that calculate nothing. Fix order removes them. В порядке вычислений {n} запись, которая ничего не вычисляет. «Исправить порядок» удалит её.|В порядке вычислений {n} записи, которые ничего не вычисляют. «Исправить порядок» удалит их.|В порядке вычислений {n} записей, которые ничего не вычисляют. «Исправить порядок» удалит их.
|
||||
@plural {fields} reads it|{fields} read it {fields} читает его|{fields} читают его|{fields} читают его
|
||||
@plural {n} field shows an old value|{n} fields show old values {n} поле показывает старое значение|{n} поля показывают старые значения|{n} полей показывают старые значения
|
||||
@plural {field} calculates before {fields}, which it reads.|{field} calculates before {fields}, which it reads. {field} вычисляется раньше {fields}, которое оно читает.|{field} вычисляется раньше {fields}, которые оно читает.|{field} вычисляется раньше {fields}, которые оно читает.
|
||||
@plural {n} more field calculates too early.|{n} more fields calculate too early. Ещё {n} поле вычисляется слишком рано.|Ещё {n} поля вычисляются слишком рано.|Ещё {n} полей вычисляются слишком рано.
|
||||
@plural {fields} is missing from the order saved in the PDF, so other PDF viewers may not calculate it.|{fields} are missing from the order saved in the PDF, so other PDF viewers may not calculate them. {fields} нет в порядке, сохранённом в PDF, поэтому другие программы просмотра PDF могут его не вычислить.|{fields} нет в порядке, сохранённом в PDF, поэтому другие программы просмотра PDF могут их не вычислить.|{fields} нет в порядке, сохранённом в PDF, поэтому другие программы просмотра PDF могут их не вычислить.
|
||||
Scan Сканировать
|
||||
Sign a sheet of white paper and take a photo of it in bright, even light (use the flash). Choose the photo or drop it here: PdfCraft finds the signature and removes the paper. Распишитесь на листе белой бумаги и сфотографируйте его при ярком равномерном освещении (со вспышкой). Выберите фото или перетащите его сюда: PdfCraft найдёт подпись и уберёт бумагу.
|
||||
Choose photo… Выбрать фото…
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 9 and column 16.
|
@@ -1007,6 +1007,36 @@
|
||||
Last commit Zadnji commit
|
||||
Later Prekliči
|
||||
Later in tab order Pozneje v vrstnem redu tabulatorja
|
||||
Calculation order Vrstni red izračunov
|
||||
Fix order Popravi vrstni red
|
||||
Move only what must move, so every field calculates after the fields it reads. Premakne le tisto, kar se mora premakniti, da se vsako polje izračuna po poljih, ki jih bere.
|
||||
Earlier in calculation order Prej v vrstnem redu izračunov
|
||||
Later in calculation order Pozneje v vrstnem redu izračunov
|
||||
Too early Prezgodaj
|
||||
Reads {name}, which calculates later, so it shows an old value. Bere {name}, ki se izračuna pozneje, zato prikazuje staro vrednost.
|
||||
Loop Zanka
|
||||
Reads {names}, which read it back. No order can fix a loop: change one of the formulas. Bere {names}, ki ga berejo nazaj. Noben vrstni red ne popravi zanke: spremenite eno od formul.
|
||||
Not in order Ni v vrstnem redu
|
||||
Missing from the calculation order saved in the PDF: other PDF viewers may not calculate it. Manjka v vrstnem redu izračunov, shranjenem v PDF-ju: drugi pregledovalniki PDF ga morda ne izračunajo.
|
||||
Back to Prepare a form Nazaj na Pripravi obrazec
|
||||
No field in this form calculates its value yet. Give a field a calculation on the Calculate tab of its properties, and it shows here. Nobeno polje tega obrazca še ne izračuna svoje vrednosti. Polju dodelite izračun na zavihku Izračunaj v njegovih lastnostih in prikazalo se bo tukaj.
|
||||
{names} and {last} {names} in {last}
|
||||
{field} reads no other field {field} ne bere nobenega drugega polja
|
||||
{field} reads {fields} {field} bere {fields}
|
||||
No field reads it Nobeno polje ga ne bere
|
||||
The order saved in the PDF needs tidying Vrstni red, shranjen v PDF-ju, je treba urediti
|
||||
Moves only what must move Premakne le, kar je treba
|
||||
Every field calculates after the fields it reads. Vsako polje se izračuna po poljih, ki jih bere.
|
||||
Every field outside a loop calculates after the fields it reads. Vsako polje zunaj zanke se izračuna po poljih, ki jih bere.
|
||||
{field} reads its own value {field} bere svojo lastno vrednost
|
||||
{fields} read each other {fields} se berejo med seboj
|
||||
No order can fix a loop. Change one of the formulas. Noben vrstni red ne popravi zanke. Spremenite eno od formul.
|
||||
Edit {field}'s formula Uredi formulo polja {field}
|
||||
Order · top calculates first Vrstni red · zgornje se izračuna prvo
|
||||
Script Skript
|
||||
Links on page Povezave na strani
|
||||
Show on the page which fields each field reads Na strani pokaži, katera polja bere posamezno polje
|
||||
Drag a field to move it, or select it and press {up} or {down}. Polje premaknete tako, da ga povlečete, ali pa ga izberite in pritisnite {up} ali {down}.
|
||||
Layers Plasti
|
||||
Layers Panel and Page Razdelek in stran s plastmi
|
||||
Layout and Magnification Postavitev in povečava
|
||||
@@ -2347,6 +2377,12 @@ animation effects Off Izklopljeni
|
||||
no output folder was chosen izhodna mapa ni bila izbrana
|
||||
@plural Downloaded {n} PDF|Downloaded {n} PDFs Prenesen {n} PDF|Prenesena {n} PDF-ja|Preneseni {n} PDF-ji|Prenesenih {n} PDF-jev
|
||||
@plural {n} calculation now uses the new name.|{n} calculations now use the new name. {n} izračun zdaj uporablja novo ime.|{n} izračuna zdaj uporabljata novo ime.|{n} izračuni zdaj uporabljajo novo ime.|{n} izračunov zdaj uporablja novo ime.
|
||||
@plural The calculation order has {n} entry that calculates nothing. Fix order removes it.|The calculation order has {n} entries that calculate nothing. Fix order removes them. Vrstni red izračunov ima {n} vnos, ki ne izračuna ničesar. »Popravi vrstni red« ga odstrani.|Vrstni red izračunov ima {n} vnosa, ki ne izračunata ničesar. »Popravi vrstni red« ju odstrani.|Vrstni red izračunov ima {n} vnose, ki ne izračunajo ničesar. »Popravi vrstni red« jih odstrani.|Vrstni red izračunov ima {n} vnosov, ki ne izračunajo ničesar. »Popravi vrstni red« jih odstrani.
|
||||
@plural {fields} reads it|{fields} read it {fields} ga bere|{fields} ga bereta|{fields} ga berejo|{fields} ga berejo
|
||||
@plural {n} field shows an old value|{n} fields show old values {n} polje kaže staro vrednost|{n} polji kažeta stari vrednosti|{n} polja kažejo stare vrednosti|{n} polj kaže stare vrednosti
|
||||
@plural {field} calculates before {fields}, which it reads.|{field} calculates before {fields}, which it reads. {field} se izračuna pred {fields}, ki ga bere.|{field} se izračuna pred {fields}, ki ju bere.|{field} se izračuna pred {fields}, ki jih bere.|{field} se izračuna pred {fields}, ki jih bere.
|
||||
@plural {n} more field calculates too early.|{n} more fields calculate too early. Še {n} polje se izračuna prezgodaj.|Še {n} polji se izračunata prezgodaj.|Še {n} polja se izračunajo prezgodaj.|Še {n} polj se izračuna prezgodaj.
|
||||
@plural {fields} is missing from the order saved in the PDF, so other PDF viewers may not calculate it.|{fields} are missing from the order saved in the PDF, so other PDF viewers may not calculate them. {fields} manjka v vrstnem redu, shranjenem v PDF-ju, zato ga drugi pregledovalniki PDF morda ne bodo izračunali.|{fields} manjkata v vrstnem redu, shranjenem v PDF-ju, zato ju drugi pregledovalniki PDF morda ne bodo izračunali.|{fields} manjkajo v vrstnem redu, shranjenem v PDF-ju, zato jih drugi pregledovalniki PDF morda ne bodo izračunali.|{fields} manjkajo v vrstnem redu, shranjenem v PDF-ju, zato jih drugi pregledovalniki PDF morda ne bodo izračunali.
|
||||
@plural {n} field name collides with earlier files and will be renamed: {list}|{n} field names collide with earlier files and will be renamed: {list} {n} ime polja se ujema z imeni iz prejšnjih datotek in bo preimenovano: {list}|{n} imeni polj se ujemata z imeni iz prejšnjih datotek in bosta preimenovani: {list}|{n} imena polj se ujemajo z imeni iz prejšnjih datotek in bodo preimenovana: {list}|{n} imen polj se ujema z imeni iz prejšnjih datotek in bo preimenovanih: {list}
|
||||
Scan Skeniraj
|
||||
Sign a sheet of white paper and take a photo of it in bright, even light (use the flash). Choose the photo or drop it here: PdfCraft finds the signature and removes the paper. Podpišite se na list belega papirja in ga fotografirajte v močni, enakomerni svetlobi (uporabite bliskavico). Izberite fotografijo ali jo spustite sem: PdfCraft poišče podpis in odstrani papir.
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 9 and column 16.
|
@@ -496,6 +496,36 @@ comment menu Edit సవరించు
|
||||
Could not save: {e} సేవ్ చేయడం సాధ్యం కాలేదు: {e}
|
||||
Earlier in tab order ట్యాబ్ క్రమంలో ముందు
|
||||
Later in tab order ట్యాబ్ క్రమంలో తర్వాత
|
||||
Calculation order గణన క్రమం
|
||||
Fix order క్రమాన్ని సరిచేయండి
|
||||
Move only what must move, so every field calculates after the fields it reads. ప్రతి ఫీల్డ్ అది చదివే ఫీల్డ్ల తర్వాత లెక్కించబడేలా, తప్పనిసరిగా కదలాల్సినవి మాత్రమే కదిలిస్తుంది.
|
||||
Earlier in calculation order గణన క్రమంలో ముందు
|
||||
Later in calculation order గణన క్రమంలో తర్వాత
|
||||
Too early చాలా ముందుగా
|
||||
Reads {name}, which calculates later, so it shows an old value. {name}ను చదువుతుంది, అది తర్వాత లెక్కించబడుతుంది, కాబట్టి పాత విలువను చూపుతుంది.
|
||||
Loop లూప్
|
||||
Reads {names}, which read it back. No order can fix a loop: change one of the formulas. {names}ను చదువుతుంది, అవి దీన్ని తిరిగి చదువుతాయి. ఏ క్రమమూ లూప్ను సరిచేయదు: సూత్రాలలో ఒకదాన్ని మార్చండి.
|
||||
Not in order క్రమంలో లేదు
|
||||
Missing from the calculation order saved in the PDF: other PDF viewers may not calculate it. PDFలో సేవ్ చేసిన గణన క్రమంలో లేదు: ఇతర PDF వీక్షకులు దీన్ని లెక్కించకపోవచ్చు.
|
||||
Back to Prepare a form ‘ఫారాన్ని సిద్ధం చేయి’కి తిరిగి వెళ్లు
|
||||
No field in this form calculates its value yet. Give a field a calculation on the Calculate tab of its properties, and it shows here. ఈ ఫారంలో ఏ ఫీల్డ్ ఇంకా తన విలువను గణించదు. ఫీల్డ్ లక్షణాలలోని గణన ట్యాబ్లో దానికి గణన ఇవ్వండి, అది ఇక్కడ కనిపిస్తుంది.
|
||||
{names} and {last} {names} మరియు {last}
|
||||
{field} reads no other field {field} మరే ఫీల్డ్నూ చదవదు
|
||||
{field} reads {fields} {field} {fields}ని చదువుతుంది
|
||||
No field reads it దాన్ని ఏ ఫీల్డ్ చదవదు
|
||||
The order saved in the PDF needs tidying PDFలో సేవ్ చేసిన క్రమాన్ని సరిదిద్దాలి
|
||||
Moves only what must move తప్పనిసరిగా జరపాల్సినవాటినే జరుపుతుంది
|
||||
Every field calculates after the fields it reads. ప్రతి ఫీల్డ్ తాను చదివే ఫీల్డ్ల తర్వాత గణించబడుతుంది.
|
||||
Every field outside a loop calculates after the fields it reads. లూప్ బయట ఉన్న ప్రతి ఫీల్డ్ తాను చదివే ఫీల్డ్ల తర్వాత గణించబడుతుంది.
|
||||
{field} reads its own value {field} తన సొంత విలువను చదువుతుంది
|
||||
{fields} read each other {fields} ఒకదానినొకటి చదువుతాయి
|
||||
No order can fix a loop. Change one of the formulas. ఏ క్రమమూ లూప్ను సరిచేయలేదు. సూత్రాల్లో ఒకదాన్ని మార్చండి.
|
||||
Edit {field}'s formula {field} సూత్రాన్ని సవరించు
|
||||
Order · top calculates first క్రమం · పైది ముందుగా గణించబడుతుంది
|
||||
Script స్క్రిప్ట్
|
||||
Links on page పేజీలో లింక్లు
|
||||
Show on the page which fields each field reads ప్రతి ఫీల్డ్ ఏ ఫీల్డ్లను చదువుతుందో పేజీలో చూపించు
|
||||
Drag a field to move it, or select it and press {up} or {down}. ఫీల్డ్ను జరపడానికి లాగండి, లేదా దాన్ని ఎంచుకుని {up} లేదా {down} నొక్కండి.
|
||||
From: కనిష్ఠం:
|
||||
To: గరిష్ఠం:
|
||||
High Resolution అధిక రిజల్యూషన్
|
||||
@@ -2244,6 +2274,12 @@ animation effects Off ఆఫ్
|
||||
no output folder was chosen అవుట్పుట్ ఫోల్డర్ ఎంచుకోలేదు
|
||||
@plural Downloaded {n} PDF|Downloaded {n} PDFs {n} PDF డౌన్లోడ్ చేయబడింది|{n} PDFలు డౌన్లోడ్ చేయబడ్డాయి
|
||||
@plural {n} calculation now uses the new name.|{n} calculations now use the new name. {n} గణన ఇప్పుడు కొత్త పేరును ఉపయోగిస్తుంది.|{n} గణనలు ఇప్పుడు కొత్త పేరును ఉపయోగిస్తాయి.
|
||||
@plural The calculation order has {n} entry that calculates nothing. Fix order removes it.|The calculation order has {n} entries that calculate nothing. Fix order removes them. గణన క్రమంలో ఏదీ లెక్కించని {n} ఎంట్రీ ఉంది. "క్రమాన్ని సరిచేయండి" దాన్ని తొలగిస్తుంది.|గణన క్రమంలో ఏదీ లెక్కించని {n} ఎంట్రీలు ఉన్నాయి. "క్రమాన్ని సరిచేయండి" వాటిని తొలగిస్తుంది.
|
||||
@plural {fields} reads it|{fields} read it {fields} దాన్ని చదువుతుంది|{fields} దాన్ని చదువుతాయి
|
||||
@plural {n} field shows an old value|{n} fields show old values {n} ఫీల్డ్ పాత విలువను చూపుతోంది|{n} ఫీల్డ్లు పాత విలువలను చూపుతున్నాయి
|
||||
@plural {field} calculates before {fields}, which it reads.|{field} calculates before {fields}, which it reads. {field} తాను చదివే {fields} కంటే ముందు గణించబడుతుంది.|{field} తాను చదివే {fields} కంటే ముందు గణించబడుతుంది.
|
||||
@plural {n} more field calculates too early.|{n} more fields calculate too early. మరో {n} ఫీల్డ్ చాలా ముందుగా గణించబడుతుంది.|మరో {n} ఫీల్డ్లు చాలా ముందుగా గణించబడతాయి.
|
||||
@plural {fields} is missing from the order saved in the PDF, so other PDF viewers may not calculate it.|{fields} are missing from the order saved in the PDF, so other PDF viewers may not calculate them. {fields} PDFలో సేవ్ చేసిన క్రమంలో లేదు, కాబట్టి ఇతర PDF వ్యూయర్లు దాన్ని గణించకపోవచ్చు.|{fields} PDFలో సేవ్ చేసిన క్రమంలో లేవు, కాబట్టి ఇతర PDF వ్యూయర్లు వాటిని గణించకపోవచ్చు.
|
||||
Scan స్కాన్
|
||||
Sign a sheet of white paper and take a photo of it in bright, even light (use the flash). Choose the photo or drop it here: PdfCraft finds the signature and removes the paper. తెల్ల కాగితంపై సంతకం చేసి, ప్రకాశవంతమైన, సమానమైన వెలుతురులో దాని ఫోటో తీయండి (ఫ్లాష్ ఉపయోగించండి). ఫోటోను ఎంచుకోండి లేదా ఇక్కడ వదలండి: PdfCraft సంతకాన్ని కనుగొని కాగితాన్ని తొలగిస్తుంది.
|
||||
Choose photo… ఫోటో ఎంచుకోండి…
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 13 and column 16.
|
@@ -477,6 +477,36 @@
|
||||
Could not save: {e} Kaydedilemedi: {e}
|
||||
Earlier in tab order Sekme sırasında daha önce
|
||||
Later in tab order Sekme sırasında daha sonra
|
||||
Calculation order Hesaplama sırası
|
||||
Fix order Sırayı düzelt
|
||||
Move only what must move, so every field calculates after the fields it reads. Her alan okuduğu alanlardan sonra hesaplansın diye yalnızca taşınması gerekenleri taşır.
|
||||
Earlier in calculation order Hesaplama sırasında daha önce
|
||||
Later in calculation order Hesaplama sırasında daha sonra
|
||||
Too early Çok erken
|
||||
Reads {name}, which calculates later, so it shows an old value. Daha sonra hesaplanan {name} alanını okur, bu yüzden eski bir değer gösterir.
|
||||
Loop Döngü
|
||||
Reads {names}, which read it back. No order can fix a loop: change one of the formulas. {names} alanlarını okur, onlar da bu alanı okur. Hiçbir sıra bir döngüyü düzeltemez: formüllerden birini değiştirin.
|
||||
Not in order Sırada değil
|
||||
Missing from the calculation order saved in the PDF: other PDF viewers may not calculate it. PDF'te kayıtlı hesaplama sırasında yok: diğer PDF görüntüleyicileri bunu hesaplamayabilir.
|
||||
Back to Prepare a form Form hazırla'ya geri dön
|
||||
No field in this form calculates its value yet. Give a field a calculation on the Calculate tab of its properties, and it shows here. Bu formdaki hiçbir alan henüz değerini hesaplamıyor. Bir alana özelliklerinin Hesapla sekmesinde bir hesaplama verin, burada görünür.
|
||||
{names} and {last} {names} ve {last}
|
||||
{field} reads no other field {field} başka bir alanı okumuyor
|
||||
{field} reads {fields} {field} şunları okur: {fields}
|
||||
No field reads it Onu hiçbir alan okumuyor
|
||||
The order saved in the PDF needs tidying PDF'te kayıtlı sıranın düzenlenmesi gerekiyor
|
||||
Moves only what must move Yalnızca taşınması gerekeni taşır
|
||||
Every field calculates after the fields it reads. Her alan, okuduğu alanlardan sonra hesaplanır.
|
||||
Every field outside a loop calculates after the fields it reads. Döngü dışındaki her alan, okuduğu alanlardan sonra hesaplanır.
|
||||
{field} reads its own value {field} kendi değerini okuyor
|
||||
{fields} read each other {fields} birbirini okuyor
|
||||
No order can fix a loop. Change one of the formulas. Hiçbir sıra bir döngüyü düzeltemez. Formüllerden birini değiştirin.
|
||||
Edit {field}'s formula {field} formülünü düzenle
|
||||
Order · top calculates first Sıra · üstteki önce hesaplanır
|
||||
Script Betik
|
||||
Links on page Sayfadaki bağlantılar
|
||||
Show on the page which fields each field reads Her alanın hangi alanları okuduğunu sayfada göster
|
||||
Drag a field to move it, or select it and press {up} or {down}. Taşımak için bir alanı sürükleyin veya seçip {up} ya da {down} tuşuna basın.
|
||||
From: Başlangıç:
|
||||
To: Bitiş:
|
||||
High Resolution Yüksek Çözünürlük
|
||||
@@ -2328,6 +2358,12 @@ animation effects Off Kapalı
|
||||
no output folder was chosen çıktı klasörü seçilmedi
|
||||
@plural Downloaded {n} PDF|Downloaded {n} PDFs {n} PDF indirildi
|
||||
@plural {n} calculation now uses the new name.|{n} calculations now use the new name. {n} hesaplama artık yeni adı kullanıyor.
|
||||
@plural The calculation order has {n} entry that calculates nothing. Fix order removes it.|The calculation order has {n} entries that calculate nothing. Fix order removes them. Hesaplama sırasında hiçbir şey hesaplamayan {n} giriş var. "Sırayı düzelt" bunları kaldırır.
|
||||
@plural {fields} reads it|{fields} read it Onu {fields} okuyor
|
||||
@plural {n} field shows an old value|{n} fields show old values {n} alan eski bir değer gösteriyor
|
||||
@plural {field} calculates before {fields}, which it reads.|{field} calculates before {fields}, which it reads. {field} önce hesaplanıyor; okuduğu {fields} daha sonra hesaplanıyor.
|
||||
@plural {n} more field calculates too early.|{n} more fields calculate too early. {n} alan daha çok erken hesaplanıyor.
|
||||
@plural {fields} is missing from the order saved in the PDF, so other PDF viewers may not calculate it.|{fields} are missing from the order saved in the PDF, so other PDF viewers may not calculate them. {fields}, PDF'te kayıtlı sırada yok; bu yüzden diğer PDF görüntüleyicileri hesaplamayabilir.
|
||||
@plural {n} field name collides with earlier files and will be renamed: {list}|{n} field names collide with earlier files and will be renamed: {list} {n} alan adı önceki dosyalarla çakışıyor ve yeniden adlandırılacak: {list}
|
||||
Scan Tara
|
||||
Sign a sheet of white paper and take a photo of it in bright, even light (use the flash). Choose the photo or drop it here: PdfCraft finds the signature and removes the paper. Beyaz bir kâğıda imzanızı atın ve parlak, eşit ışıkta fotoğrafını çekin (flaş kullanın). Fotoğrafı seçin veya buraya bırakın: PdfCraft imzayı bulur ve kâğıdı kaldırır.
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 855 and column 9.
|
@@ -517,6 +517,36 @@
|
||||
Could not save: {e} Не вдалося зберегти: {e}
|
||||
Earlier in tab order Раніше в порядку табуляції
|
||||
Later in tab order Пізніше в порядку табуляції
|
||||
Calculation order Порядок обчислень
|
||||
Fix order Виправити порядок
|
||||
Move only what must move, so every field calculates after the fields it reads. Переміщує лише те, що потрібно, щоб кожне поле обчислювалося після полів, які воно читає.
|
||||
Earlier in calculation order Раніше в порядку обчислень
|
||||
Later in calculation order Пізніше в порядку обчислень
|
||||
Too early Зарано
|
||||
Reads {name}, which calculates later, so it shows an old value. Читає {name}, яке обчислюється пізніше, тому показує старе значення.
|
||||
Loop Цикл
|
||||
Reads {names}, which read it back. No order can fix a loop: change one of the formulas. Читає {names}, які своєю чергою читають його. Жоден порядок не виправить цикл: змініть одну з формул.
|
||||
Not in order Поза порядком
|
||||
Missing from the calculation order saved in the PDF: other PDF viewers may not calculate it. Відсутнє в порядку обчислень, збереженому в PDF: інші переглядачі PDF можуть його не обчислювати.
|
||||
Back to Prepare a form Назад до «Підготувати форму»
|
||||
No field in this form calculates its value yet. Give a field a calculation on the Calculate tab of its properties, and it shows here. Жодне поле цієї форми поки не обчислює своє значення. Задайте полю обчислення на вкладці «Обчислення» його властивостей, і воно з’явиться тут.
|
||||
{names} and {last} {names} і {last}
|
||||
{field} reads no other field {field} не читає інших полів
|
||||
{field} reads {fields} {field} читає {fields}
|
||||
No field reads it Жодне поле його не читає
|
||||
The order saved in the PDF needs tidying Порядок, збережений у PDF, потребує впорядкування
|
||||
Moves only what must move Переміщує лише те, що треба
|
||||
Every field calculates after the fields it reads. Кожне поле обчислюється після полів, які воно читає.
|
||||
Every field outside a loop calculates after the fields it reads. Кожне поле поза циклом обчислюється після полів, які воно читає.
|
||||
{field} reads its own value {field} читає власне значення
|
||||
{fields} read each other {fields} читають одне одного
|
||||
No order can fix a loop. Change one of the formulas. Жоден порядок не виправить цикл. Змініть одну з формул.
|
||||
Edit {field}'s formula Змінити формулу {field}
|
||||
Order · top calculates first Порядок · верхнє обчислюється першим
|
||||
Script Скрипт
|
||||
Links on page Зв’язки на сторінці
|
||||
Show on the page which fields each field reads Показувати на сторінці, які поля читає кожне поле
|
||||
Drag a field to move it, or select it and press {up} or {down}. Перетягніть поле, щоб перемістити його, або виберіть його й натисніть {up} чи {down}.
|
||||
From: Від:
|
||||
To: До:
|
||||
High Resolution Висока роздільна здатність
|
||||
@@ -2365,6 +2395,12 @@ animation effects Off Вимкнено
|
||||
no output folder was chosen не вибрано теку для виводу
|
||||
@plural Downloaded {n} PDF|Downloaded {n} PDFs Завантажено {n} PDF-файл|Завантажено {n} PDF-файли|Завантажено {n} PDF-файлів
|
||||
@plural {n} calculation now uses the new name.|{n} calculations now use the new name. {n} обчислення тепер використовує нову назву.|{n} обчислення тепер використовують нову назву.|{n} обчислень тепер використовують нову назву.
|
||||
@plural The calculation order has {n} entry that calculates nothing. Fix order removes it.|The calculation order has {n} entries that calculate nothing. Fix order removes them. У порядку обчислень є {n} запис, який нічого не обчислює. «Виправити порядок» його видалить.|У порядку обчислень є {n} записи, які нічого не обчислюють. «Виправити порядок» їх видалить.|У порядку обчислень є {n} записів, які нічого не обчислюють. «Виправити порядок» їх видалить.
|
||||
@plural {fields} reads it|{fields} read it {fields} читає його|{fields} читають його|{fields} читають його
|
||||
@plural {n} field shows an old value|{n} fields show old values {n} поле показує старе значення|{n} поля показують старі значення|{n} полів показують старі значення
|
||||
@plural {field} calculates before {fields}, which it reads.|{field} calculates before {fields}, which it reads. {field} обчислюється раніше за {fields}, яке воно читає.|{field} обчислюється раніше за {fields}, які воно читає.|{field} обчислюється раніше за {fields}, які воно читає.
|
||||
@plural {n} more field calculates too early.|{n} more fields calculate too early. Ще {n} поле обчислюється зарано.|Ще {n} поля обчислюються зарано.|Ще {n} полів обчислюються зарано.
|
||||
@plural {fields} is missing from the order saved in the PDF, so other PDF viewers may not calculate it.|{fields} are missing from the order saved in the PDF, so other PDF viewers may not calculate them. {fields} немає в порядку, збереженому в PDF, тож інші переглядачі PDF можуть його не обчислити.|{fields} немає в порядку, збереженому в PDF, тож інші переглядачі PDF можуть їх не обчислити.|{fields} немає в порядку, збереженому в PDF, тож інші переглядачі PDF можуть їх не обчислити.
|
||||
Scan Сканувати
|
||||
Sign a sheet of white paper and take a photo of it in bright, even light (use the flash). Choose the photo or drop it here: PdfCraft finds the signature and removes the paper. Розпишіться на аркуші білого паперу та сфотографуйте його за яскравого рівномірного освітлення (зі спалахом). Виберіть фото або перетягніть його сюди: PdfCraft знайде підпис і прибере папір.
|
||||
Choose photo… Вибрати фото…
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 6 and column 47.
|
@@ -681,6 +681,36 @@ theme Appearance Giao diện
|
||||
Larger pages Trang lớn hơn
|
||||
Later Để sau
|
||||
Later in tab order Muộn hơn theo thứ tự tab
|
||||
Calculation order Thứ tự tính toán
|
||||
Fix order Sửa thứ tự
|
||||
Move only what must move, so every field calculates after the fields it reads. Chỉ di chuyển những gì cần di chuyển, để mỗi trường được tính sau các trường mà nó đọc.
|
||||
Earlier in calculation order Sớm hơn theo thứ tự tính toán
|
||||
Later in calculation order Muộn hơn theo thứ tự tính toán
|
||||
Too early Quá sớm
|
||||
Reads {name}, which calculates later, so it shows an old value. Đọc {name}, trường được tính sau, nên hiển thị giá trị cũ.
|
||||
Loop Vòng lặp
|
||||
Reads {names}, which read it back. No order can fix a loop: change one of the formulas. Đọc {names}, các trường này lại đọc ngược nó. Không thứ tự nào sửa được vòng lặp: hãy đổi một trong các công thức.
|
||||
Not in order Không có trong thứ tự
|
||||
Missing from the calculation order saved in the PDF: other PDF viewers may not calculate it. Không có trong thứ tự tính toán lưu trong PDF: các trình xem PDF khác có thể không tính trường này.
|
||||
Back to Prepare a form Quay lại Chuẩn bị biểu mẫu
|
||||
No field in this form calculates its value yet. Give a field a calculation on the Calculate tab of its properties, and it shows here. Chưa có trường nào trong biểu mẫu này tự tính giá trị. Hãy đặt phép tính cho một trường ở thẻ Tính toán trong thuộc tính của nó, trường đó sẽ hiện ở đây.
|
||||
{names} and {last} {names} và {last}
|
||||
{field} reads no other field {field} không đọc trường nào khác
|
||||
{field} reads {fields} {field} đọc {fields}
|
||||
No field reads it Không trường nào đọc nó
|
||||
The order saved in the PDF needs tidying Thứ tự lưu trong PDF cần được sắp xếp lại
|
||||
Moves only what must move Chỉ di chuyển những gì cần thiết
|
||||
Every field calculates after the fields it reads. Mọi trường đều được tính sau các trường mà nó đọc.
|
||||
Every field outside a loop calculates after the fields it reads. Mọi trường ngoài vòng lặp đều được tính sau các trường mà nó đọc.
|
||||
{field} reads its own value {field} đọc chính giá trị của nó
|
||||
{fields} read each other {fields} đọc lẫn nhau
|
||||
No order can fix a loop. Change one of the formulas. Không thứ tự nào sửa được vòng lặp. Hãy thay đổi một trong các công thức.
|
||||
Edit {field}'s formula Sửa công thức của {field}
|
||||
Order · top calculates first Thứ tự · trên cùng được tính trước
|
||||
Script Tập lệnh
|
||||
Links on page Liên kết trên trang
|
||||
Show on the page which fields each field reads Hiện trên trang các trường mà mỗi trường đọc
|
||||
Drag a field to move it, or select it and press {up} or {down}. Kéo một trường để di chuyển, hoặc chọn nó rồi nhấn {up} hoặc {down}.
|
||||
Layers Các lớp
|
||||
Layers Panel and Page Bảng Các lớp và trang
|
||||
Layout and Magnification Bố cục và độ phóng đại
|
||||
@@ -2590,6 +2620,12 @@ certificate SHA-256 digest Giá trị băm SHA-256
|
||||
@plural {n} object selected|{n} objects selected Đã chọn {n} đối tượng
|
||||
@plural Downloaded {n} PDF|Downloaded {n} PDFs Đã tải xuống {n} PDF
|
||||
@plural {n} calculation now uses the new name.|{n} calculations now use the new name. {n} phép tính giờ dùng tên mới.
|
||||
@plural The calculation order has {n} entry that calculates nothing. Fix order removes it.|The calculation order has {n} entries that calculate nothing. Fix order removes them. Thứ tự tính toán có {n} mục không tính gì. "Sửa thứ tự" sẽ xóa chúng.
|
||||
@plural {fields} reads it|{fields} read it {fields} đọc nó
|
||||
@plural {n} field shows an old value|{n} fields show old values {n} trường hiển thị giá trị cũ
|
||||
@plural {field} calculates before {fields}, which it reads.|{field} calculates before {fields}, which it reads. {field} được tính trước {fields} mà nó đọc.
|
||||
@plural {n} more field calculates too early.|{n} more fields calculate too early. Còn {n} trường khác được tính quá sớm.
|
||||
@plural {fields} is missing from the order saved in the PDF, so other PDF viewers may not calculate it.|{fields} are missing from the order saved in the PDF, so other PDF viewers may not calculate them. {fields} không có trong thứ tự lưu trong PDF, nên các trình xem PDF khác có thể không tính.
|
||||
key Ctrl Ctrl
|
||||
key Shift Shift
|
||||
key Delete Delete
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 491 and column 12.
|
@@ -197,6 +197,36 @@
|
||||
Could not save: {e} 无法保存:{e}
|
||||
Earlier in tab order 在 Tab 顺序中前移
|
||||
Later in tab order 在 Tab 顺序中后移
|
||||
Calculation order 计算顺序
|
||||
Fix order 修正顺序
|
||||
Move only what must move, so every field calculates after the fields it reads. 只移动必须移动的字段,使每个字段都在它读取的字段之后计算。
|
||||
Earlier in calculation order 在计算顺序中前移
|
||||
Later in calculation order 在计算顺序中后移
|
||||
Too early 过早
|
||||
Reads {name}, which calculates later, so it shows an old value. 读取 {name},而它在之后才计算,因此显示的是旧值。
|
||||
Loop 循环
|
||||
Reads {names}, which read it back. No order can fix a loop: change one of the formulas. 读取 {names},而它们又读取此字段。任何顺序都无法修正循环:请修改其中一个公式。
|
||||
Not in order 不在顺序中
|
||||
Missing from the calculation order saved in the PDF: other PDF viewers may not calculate it. PDF 中保存的计算顺序缺少此字段:其他 PDF 查看器可能不会计算它。
|
||||
Back to Prepare a form 返回准备表单
|
||||
No field in this form calculates its value yet. Give a field a calculation on the Calculate tab of its properties, and it shows here. 此表单中还没有计算自身值的字段。在字段属性的“计算”选项卡中为字段设置计算后,它会显示在这里。
|
||||
{names} and {last} {names}和{last}
|
||||
{field} reads no other field {field} 不读取其他字段
|
||||
{field} reads {fields} {field} 读取 {fields}
|
||||
No field reads it 没有字段读取它
|
||||
The order saved in the PDF needs tidying PDF 中保存的顺序需要整理
|
||||
Moves only what must move 只移动必须移动的
|
||||
Every field calculates after the fields it reads. 每个字段都在它读取的字段之后计算。
|
||||
Every field outside a loop calculates after the fields it reads. 循环之外的每个字段都在它读取的字段之后计算。
|
||||
{field} reads its own value {field} 读取自身的值
|
||||
{fields} read each other {fields} 相互读取
|
||||
No order can fix a loop. Change one of the formulas. 任何顺序都无法修复循环。请修改其中一个公式。
|
||||
Edit {field}'s formula 编辑 {field} 的公式
|
||||
Order · top calculates first 顺序 · 上方的先计算
|
||||
Script 脚本
|
||||
Links on page 页面上的关联
|
||||
Show on the page which fields each field reads 在页面上显示每个字段读取哪些字段
|
||||
Drag a field to move it, or select it and press {up} or {down}. 拖动字段以移动它,或选中它后按 {up} 或 {down}。
|
||||
From: 从:
|
||||
To: 至:
|
||||
High Resolution 高分辨率
|
||||
@@ -2307,6 +2337,12 @@ animation effects Off 关
|
||||
no output folder was chosen 未选择输出文件夹
|
||||
@plural Downloaded {n} PDF|Downloaded {n} PDFs 已下载 {n} 个 PDF
|
||||
@plural {n} calculation now uses the new name.|{n} calculations now use the new name. {n} 个计算已改用新名称。
|
||||
@plural The calculation order has {n} entry that calculates nothing. Fix order removes it.|The calculation order has {n} entries that calculate nothing. Fix order removes them. 计算顺序中有 {n} 个不计算任何内容的条目。“修正顺序”会将其删除。
|
||||
@plural {fields} reads it|{fields} read it {fields} 读取它
|
||||
@plural {n} field shows an old value|{n} fields show old values {n} 个字段显示旧值
|
||||
@plural {field} calculates before {fields}, which it reads.|{field} calculates before {fields}, which it reads. {field} 在它读取的 {fields} 之前计算。
|
||||
@plural {n} more field calculates too early.|{n} more fields calculate too early. 另有 {n} 个字段计算过早。
|
||||
@plural {fields} is missing from the order saved in the PDF, so other PDF viewers may not calculate it.|{fields} are missing from the order saved in the PDF, so other PDF viewers may not calculate them. {fields} 不在 PDF 中保存的顺序里,其他 PDF 查看器可能不会计算。
|
||||
Scan 扫描
|
||||
Sign a sheet of white paper and take a photo of it in bright, even light (use the flash). Choose the photo or drop it here: PdfCraft finds the signature and removes the paper. 在白纸上签名,并在明亮、均匀的光线下拍照(使用闪光灯)。选择照片或将其拖放到此处:PdfCraft 会找到签名并去除纸张背景。
|
||||
Choose photo… 选择照片…
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 9 and column 16.
|
@@ -153,6 +153,36 @@
|
||||
Could not save: {e} 無法儲存:{e}
|
||||
Earlier in tab order 在 Tab 順序中前移
|
||||
Later in tab order 在 Tab 順序中後移
|
||||
Calculation order 計算順序
|
||||
Fix order 修正順序
|
||||
Move only what must move, so every field calculates after the fields it reads. 只移動必須移動的欄位,讓每個欄位都在它讀取的欄位之後計算。
|
||||
Earlier in calculation order 在計算順序中前移
|
||||
Later in calculation order 在計算順序中後移
|
||||
Too early 過早
|
||||
Reads {name}, which calculates later, so it shows an old value. 讀取 {name},而它之後才計算,因此顯示的是舊值。
|
||||
Loop 迴圈
|
||||
Reads {names}, which read it back. No order can fix a loop: change one of the formulas. 讀取 {names},而它們又讀取此欄位。任何順序都無法修正迴圈:請修改其中一個公式。
|
||||
Not in order 不在順序中
|
||||
Missing from the calculation order saved in the PDF: other PDF viewers may not calculate it. PDF 中儲存的計算順序缺少此欄位:其他 PDF 檢視器可能不會計算它。
|
||||
Back to Prepare a form 返回準備表單
|
||||
No field in this form calculates its value yet. Give a field a calculation on the Calculate tab of its properties, and it shows here. 此表單中還沒有計算自身值的欄位。在欄位內容的「計算」索引標籤中為欄位設定計算後,它會顯示在這裡。
|
||||
{names} and {last} {names}和{last}
|
||||
{field} reads no other field {field} 不讀取其他欄位
|
||||
{field} reads {fields} {field} 讀取 {fields}
|
||||
No field reads it 沒有欄位讀取它
|
||||
The order saved in the PDF needs tidying PDF 中儲存的順序需要整理
|
||||
Moves only what must move 只移動必須移動的
|
||||
Every field calculates after the fields it reads. 每個欄位都在它讀取的欄位之後計算。
|
||||
Every field outside a loop calculates after the fields it reads. 迴圈之外的每個欄位都在它讀取的欄位之後計算。
|
||||
{field} reads its own value {field} 讀取自身的值
|
||||
{fields} read each other {fields} 互相讀取
|
||||
No order can fix a loop. Change one of the formulas. 任何順序都無法修正迴圈。請修改其中一個公式。
|
||||
Edit {field}'s formula 編輯 {field} 的公式
|
||||
Order · top calculates first 順序 · 上方的先計算
|
||||
Script 指令碼
|
||||
Links on page 頁面上的關聯
|
||||
Show on the page which fields each field reads 在頁面上顯示每個欄位讀取哪些欄位
|
||||
Drag a field to move it, or select it and press {up} or {down}. 拖曳欄位即可移動,或選取後按 {up} 或 {down}。
|
||||
From: 從:
|
||||
To: 至:
|
||||
High Resolution 高解析度
|
||||
@@ -2206,6 +2236,12 @@ animation effects Off 關
|
||||
no output folder was chosen 未選擇輸出資料夾
|
||||
@plural Downloaded {n} PDF|Downloaded {n} PDFs 已下載 {n} 個 PDF
|
||||
@plural {n} calculation now uses the new name.|{n} calculations now use the new name. {n} 個計算已改用新名稱。
|
||||
@plural The calculation order has {n} entry that calculates nothing. Fix order removes it.|The calculation order has {n} entries that calculate nothing. Fix order removes them. 計算順序中有 {n} 個不計算任何內容的項目。「修正順序」會將其刪除。
|
||||
@plural {fields} reads it|{fields} read it {fields} 讀取它
|
||||
@plural {n} field shows an old value|{n} fields show old values {n} 個欄位顯示舊值
|
||||
@plural {field} calculates before {fields}, which it reads.|{field} calculates before {fields}, which it reads. {field} 在它讀取的 {fields} 之前計算。
|
||||
@plural {n} more field calculates too early.|{n} more fields calculate too early. 另有 {n} 個欄位計算過早。
|
||||
@plural {fields} is missing from the order saved in the PDF, so other PDF viewers may not calculate it.|{fields} are missing from the order saved in the PDF, so other PDF viewers may not calculate them. {fields} 不在 PDF 中儲存的順序裡,其他 PDF 檢視器可能不會計算。
|
||||
Scan 掃描
|
||||
Sign a sheet of white paper and take a photo of it in bright, even light (use the flash). Choose the photo or drop it here: PdfCraft finds the signature and removes the paper. 在白紙上簽名,並在明亮、均勻的光線下拍照(使用閃光燈)。選擇相片或將其拖放到此處:PdfCraft 會找到簽名並去除紙張背景。
|
||||
Choose photo… 選擇相片…
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 9 and column 16.
|
@@ -31,6 +31,7 @@ macro_rules! tl_ctx {
|
||||
mod a11y_ui;
|
||||
mod actions_ui;
|
||||
mod appearance;
|
||||
mod calc_order_ui;
|
||||
pub mod canvas;
|
||||
mod chrome;
|
||||
mod combine_grid;
|
||||
@@ -188,6 +189,8 @@ impl Mode {
|
||||
pub enum LeftPanel {
|
||||
AllTools,
|
||||
Tool(&'static str),
|
||||
/// Prepare a form ▸ Calculation order, a page of its own; Back returns to Prepare a form.
|
||||
CalculationOrder,
|
||||
}
|
||||
|
||||
/// Right-hand panels, opened from the rail.
|
||||
@@ -1088,10 +1091,12 @@ impl PdfCraftApp {
|
||||
}
|
||||
}
|
||||
|
||||
/// Fields are being edited (Prepare a form is open or a field tool is picked), unless the
|
||||
/// form is being previewed.
|
||||
/// Fields are being edited (Prepare a form or its Calculation order is open, or a field tool
|
||||
/// is picked), unless the form is being previewed.
|
||||
pub fn is_preparing(&self) -> bool {
|
||||
((self.left_open && self.left == LeftPanel::Tool("form")) || matches!(self.quick_tool, QuickTool::Field(_))) && !self.form_preview
|
||||
((self.left_open && matches!(self.left, LeftPanel::Tool("form") | LeftPanel::CalculationOrder))
|
||||
|| matches!(self.quick_tool, QuickTool::Field(_)))
|
||||
&& !self.form_preview
|
||||
}
|
||||
|
||||
/// Open a document the way it asks to be opened: navigation panel, layout, magnification,
|
||||
|
||||
@@ -31,15 +31,20 @@ pub fn left_panel(app: &mut PdfCraftApp, ui: &mut egui::Ui) {
|
||||
Some(g) => tool_detail(app, ui, &t, g),
|
||||
None => app.left = LeftPanel::AllTools,
|
||||
},
|
||||
LeftPanel::CalculationOrder => crate::calc_order_ui::panel(app, ui, &t),
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
fn panel_header(ui: &mut egui::Ui, t: &Tokens, title: &str, back: bool) -> (bool, bool) {
|
||||
/// A panel's title row: Back (with `back` as its tooltip) when given, the title and Close.
|
||||
/// Returns whether Back and Close were clicked.
|
||||
pub(crate) fn panel_header(ui: &mut egui::Ui, t: &Tokens, title: &str, back: Option<&str>) -> (bool, bool) {
|
||||
let mut go_back = false;
|
||||
let mut close = false;
|
||||
ui.horizontal(|ui| {
|
||||
if back && icons::button(ui, "chevron-left", 26.0, false, tl!("Back to all tools")).clicked() {
|
||||
if let Some(tip) = back
|
||||
&& icons::button(ui, "chevron-left", 26.0, false, tip).clicked()
|
||||
{
|
||||
go_back = true;
|
||||
}
|
||||
// Reserve space for Close before laying out the translated title. Long tool names
|
||||
@@ -58,7 +63,7 @@ fn panel_header(ui: &mut egui::Ui, t: &Tokens, title: &str, back: bool) -> (bool
|
||||
}
|
||||
|
||||
fn all_tools(app: &mut PdfCraftApp, ui: &mut egui::Ui, t: &Tokens) {
|
||||
let (_, close) = panel_header(ui, t, "All tools", false);
|
||||
let (_, close) = panel_header(ui, t, "All tools", None);
|
||||
if close {
|
||||
app.left_open = false;
|
||||
}
|
||||
@@ -148,7 +153,7 @@ fn tool_detail(app: &mut PdfCraftApp, ui: &mut egui::Ui, t: &Tokens, g: &'static
|
||||
edit_panel(app, ui, t, g);
|
||||
return;
|
||||
}
|
||||
let (back, close) = panel_header(ui, t, g.label, true);
|
||||
let (back, close) = panel_header(ui, t, g.label, Some(tl!("Back to all tools")));
|
||||
if back {
|
||||
app.left = LeftPanel::AllTools;
|
||||
app.mode = crate::Mode::AllTools;
|
||||
|
||||
@@ -655,3 +655,157 @@ fn actions_tab_adds_and_removes_actions() {
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/// Prepare a form ▸ Calculation order opens as a page of its own, with the form still being
|
||||
/// prepared, says when nothing calculates, and Back returns to Prepare a form.
|
||||
#[test]
|
||||
fn the_calculation_order_is_a_page_of_prepare_a_form() {
|
||||
use pdfcraft_ui_egui::LeftPanel;
|
||||
let mut h = harness();
|
||||
h.state_mut().execute("form.prepare");
|
||||
h.run_steps(3);
|
||||
assert!(h.query_by_label("Field list").is_some());
|
||||
h.get_by_label("Calculation order").click();
|
||||
h.run_steps(3);
|
||||
assert_eq!(h.state().left, LeftPanel::CalculationOrder);
|
||||
assert!(h.state().is_preparing(), "the fields stay editable, so a row can select one");
|
||||
// The page replaces the Prepare a form tools.
|
||||
assert!(h.query_by_label("Field list").is_none());
|
||||
assert!(h.query_by_label_contains("No field in this form calculates its value yet").is_some());
|
||||
h.get_by_label("Back to Prepare a form").click();
|
||||
h.run_steps(3);
|
||||
assert_eq!(h.state().left, LeftPanel::Tool("form"));
|
||||
assert!(h.query_by_label("Field list").is_some());
|
||||
assert!(h.query_by_label("Back to Prepare a form").is_none());
|
||||
// Opened from Preview, the page edits the fields again.
|
||||
h.get_by_label("Preview").click();
|
||||
h.run_steps(3);
|
||||
assert!(h.state().form_preview);
|
||||
h.get_by_label("Calculation order").click();
|
||||
h.run_steps(3);
|
||||
assert!(h.state().is_preparing() && !h.state().form_preview, "Preview ends, so a row can select its field");
|
||||
// Opened (from ⌘K) while the page grid shows, the grid closes and the page shows.
|
||||
h.state_mut().execute("page.organize");
|
||||
h.run_steps(3);
|
||||
assert!(h.state().views[0].organize);
|
||||
h.state_mut().execute("form.calculation_order");
|
||||
h.run_steps(3);
|
||||
assert!(!h.state().views[0].organize);
|
||||
assert!(h.query_by_label_contains("No field in this form calculates its value yet").is_some());
|
||||
}
|
||||
|
||||
/// Prepare a form ▸ Calculation order: a card says which field shows an old value and why, each
|
||||
/// row shows its field's value as the field does, the selected field's arrows, Alt+↑ and a drag
|
||||
/// move it, Fix order puts each field after the fields it reads and the card's Undo takes that
|
||||
/// back, every change is one undo step, and a row selects its field.
|
||||
#[test]
|
||||
fn the_calculation_order_is_moved_dragged_and_fixed() {
|
||||
use egui::{Key, Modifiers};
|
||||
use pdfcraft_engine::form_scripts::{CalcOp, Calculate, Format};
|
||||
use pdfcraft_engine::{Edit, FieldProps, FieldValue, NewField};
|
||||
let mut h = harness();
|
||||
for (i, name) in ["qty", "sub", "total", "other"].into_iter().enumerate() {
|
||||
let y = 200.0 + 30.0 * i as f64;
|
||||
let kind = NewField::Text { multiline: false };
|
||||
h.state_mut().apply_edit(Edit::AddField { page: 0, rect: [20.0, y, 120.0, y + 20.0], kind, name: Some(name.into()) });
|
||||
}
|
||||
let calculate = |name: &str, c: Calculate| Edit::SetFieldProps {
|
||||
name: name.into(),
|
||||
props: Box::new(FieldProps { calculate: Some(c), ..Default::default() }),
|
||||
};
|
||||
// Defined backwards: total, which reads sub, calculates first.
|
||||
h.state_mut().apply_edit(calculate("total", Calculate::Simple { op: CalcOp::Sum, fields: vec!["sub".into()] }));
|
||||
h.state_mut().apply_edit(calculate("sub", Calculate::Notation("qty * 2".into())));
|
||||
h.state_mut().apply_edit(calculate("other", Calculate::Notation("qty + 1".into())));
|
||||
// other shows its value as currency.
|
||||
let currency = Format::Number { decimals: 2, sep: 0, neg: 0, currency: "$".into(), prepend: true };
|
||||
h.state_mut()
|
||||
.apply_edit(Edit::SetFieldProps { name: "other".into(), props: Box::new(FieldProps { format: Some(currency), ..Default::default() }) });
|
||||
h.state_mut().apply_edit(Edit::SetFieldValue { name: "qty".into(), value: FieldValue::Text("3".into()) });
|
||||
h.state_mut().execute("form.prepare");
|
||||
h.run_steps(3);
|
||||
h.get_by_label("Calculation order").click();
|
||||
h.run_steps(3);
|
||||
let order = |h: &Harness<'static, PdfCraftApp>| -> Vec<String> {
|
||||
let s = h.state();
|
||||
s.session.get(s.views[0].id).unwrap().calculation_order().fields.into_iter().map(|f| f.name).collect()
|
||||
};
|
||||
let undo_label = |h: &Harness<'static, PdfCraftApp>| h.state().session.get(h.state().views[0].id).unwrap().can_undo().map(str::to_owned);
|
||||
assert_eq!(order(&h), ["total", "sub", "other"]);
|
||||
// The card says what is wrong, and each row shows its value as the field does: total
|
||||
// calculated before sub, so it still has sub's old value.
|
||||
assert!(h.query_by_label("1 field shows an old value").is_some());
|
||||
assert!(h.query_by_label("total calculates before sub, which it reads.").is_some());
|
||||
for row in ["1. total: 0", "2. sub: 6", "3. other: $4.00"] {
|
||||
assert!(h.query_by_label(row).is_some(), "{row}");
|
||||
}
|
||||
// The selected field's arrows move it.
|
||||
assert!(h.query_by_label("Later in calculation order: total").is_none(), "arrows only on the selected field or the one pointed at");
|
||||
h.get_by_label("1. total: 0").click();
|
||||
h.run_steps(3);
|
||||
h.get_by_label("Later in calculation order: total").click();
|
||||
h.run_steps(3);
|
||||
assert_eq!(order(&h), ["sub", "total", "other"]);
|
||||
assert_eq!(undo_label(&h).as_deref(), Some("Set calculation order"));
|
||||
// Alt+↑ moves it back.
|
||||
h.key_press_modifiers(Modifiers::ALT, Key::ArrowUp);
|
||||
h.run_steps(3);
|
||||
assert_eq!(order(&h), ["total", "sub", "other"]);
|
||||
// Dragging other onto the first row puts it first.
|
||||
let from = h.get_by_label("3. other: $4.00").rect().center();
|
||||
let to = h.get_by_label("1. total: 6").rect().center();
|
||||
h.hover_at(from);
|
||||
h.run_steps(1);
|
||||
h.drag_at(from);
|
||||
h.run_steps(1);
|
||||
for k in 1..=4 {
|
||||
h.hover_at(from + (to - from) * (k as f32 / 4.0));
|
||||
h.run_steps(1);
|
||||
}
|
||||
h.drop_at(to);
|
||||
h.run_steps(4);
|
||||
assert_eq!(order(&h), ["other", "total", "sub"]);
|
||||
// Fix order moves only total, after sub, and the card says the order is right.
|
||||
h.get_by_label("Fix order").click();
|
||||
h.run_steps(3);
|
||||
assert_eq!(order(&h), ["other", "sub", "total"]);
|
||||
assert_eq!(undo_label(&h).as_deref(), Some("Set calculation order"));
|
||||
assert!(h.query_by_label("Every field calculates after the fields it reads.").is_some());
|
||||
assert!(h.query_by_label("Fix order").is_none());
|
||||
// Its Undo takes Fix order back.
|
||||
h.get_by_label("Undo").click();
|
||||
h.run_steps(3);
|
||||
assert_eq!(order(&h), ["other", "total", "sub"]);
|
||||
// A row selects its field.
|
||||
h.get_by_label("3. sub: 6").click();
|
||||
h.run_steps(2);
|
||||
assert_eq!(h.state().views[0].prepare.selected.as_ref().map(|s| s.0.as_str()), Some("sub"));
|
||||
}
|
||||
|
||||
/// Fields that read each other get a card of their own, which Fix order leaves alone, and its
|
||||
/// link opens the first one's formula.
|
||||
#[test]
|
||||
fn a_loop_has_its_own_card_that_opens_the_formula() {
|
||||
use pdfcraft_engine::form_scripts::Calculate;
|
||||
use pdfcraft_engine::{Edit, FieldProps, NewField};
|
||||
use pdfcraft_ui_egui::prepare::FieldTab;
|
||||
let mut h = harness();
|
||||
for (i, (name, formula)) in [("a", "b + 1"), ("b", "a + 1")].into_iter().enumerate() {
|
||||
let y = 200.0 + 30.0 * i as f64;
|
||||
let kind = NewField::Text { multiline: false };
|
||||
h.state_mut().apply_edit(Edit::AddField { page: 0, rect: [20.0, y, 120.0, y + 20.0], kind, name: Some(name.into()) });
|
||||
let props = Box::new(FieldProps { calculate: Some(Calculate::Notation(formula.into())), ..Default::default() });
|
||||
h.state_mut().apply_edit(Edit::SetFieldProps { name: name.into(), props });
|
||||
}
|
||||
h.state_mut().execute("form.prepare");
|
||||
h.run_steps(3);
|
||||
h.get_by_label("Calculation order").click();
|
||||
h.run_steps(3);
|
||||
assert!(h.query_by_label("a and b read each other").is_some());
|
||||
assert!(h.query_by_label("Every field outside a loop calculates after the fields it reads.").is_some());
|
||||
assert!(h.query_by_label("Fix order").is_none(), "no order fixes a loop");
|
||||
h.get_by_label("Edit a's formula").click();
|
||||
h.run_steps(3);
|
||||
let draft = h.state().field_props.as_ref().map(|d| (d.field.clone(), d.tab));
|
||||
assert_eq!(draft, Some(("a".to_owned(), FieldTab::Calculate)));
|
||||
}
|
||||
|
||||
+2
-1
@@ -143,7 +143,7 @@ total matches the parity estimate.
|
||||
| M7 | Content editing (text, images, header/footer, watermark) | 250–500 | 20% | 100–180 | Done: header & footer, watermarks, backgrounds, Bates; added text and images that stay editable (move, resize, format, rotate, flip, crop, replace); links (Link tool, Link Properties, create from URLs, remove all). Done since: Edit text preserves Arabic/Hebrew `/ActualText` typing order, with font-independent regressions. Done since (#1116): editable text regions grouped across compatible words and subset fonts, one rich-text editor over a background with the source text removed, embedded sfnt faces reused as editor faces, and visible (clipped) bounds for cropped-image selection and resize. Exclusive crops now resize across nested states and content streams, with shared clips fixed.<br>Done since: #594 ordinary paragraph drags preserve overlapping source text; UI/engine regressions, native save/reopen, independent-reader checks and full CI passed in the Linux test environment. #1200 candidate: local GoToR links open in desktop tabs and through root-confined automation; appearance-only edits preserve existing actions. Named destinations remain unapplied and `/NewWindow` is a tab hint. #1316: replacing a line or paragraph keeps a neighbouring line whose glyph box overlaps when the baselines differ; a second copy on the same baseline is still replaced. Missing: editing existing text and images in place (the longest pole), image/PDF watermarks |
|
||||
| M7 | Content editing (text, images, header/footer, watermark) | 250–500 | 20% | 100–180 | Done: header & footer, watermarks, backgrounds, Bates; added text and images that stay editable (move, resize, format, rotate, flip, crop, replace); links (Link tool, Link Properties, create from URLs, remove all). #3212: Headers, Bates numbers, watermarks and added text stay visible after unfinished marked content, without revealing hidden content. Tracked editable text distinguishes repeated glyph spacing from word gaps, with synthetic paragraph/object regressions. Missing: editing existing text and images in place (the longest pole), watermark print/screen visibility and repeat |
|
||||
| M6 | Forms + JavaScript | 160–320 | 50% | 40–75 | Done: filling all field types with regenerated appearances; Prepare a form (every field type, multi-select/shared properties, move/resize/delete, Field Properties General/Appearance/Position/Options/Format/Validate/Calculate); Acrobat's AF format/keystroke/validate/calculate functions and simplified field notation run natively in Acrobat's event order; tab order; push-button actions; flatten; agent tools. Form data exchange (FDF, XFDF, XML, CSV, text) done; XFDF values retain text across XML comments and processing instructions.<br>Done since: JavaScript engine (boa, sandboxed) running custom keystroke/validate/calculate/format and button scripts, document JavaScripts, console. Missing: Actions tab, wider object model (annotations, layers, dialogs), XFA<br>Done since: Existing simple field-font encodings and Differences are respected when generating appearances; an unencodable value uses a separate Helvetica appearance font without changing the source font. Synthetic reopen regressions cover punctuation, subset fallback and multiline text. Exact font metrics/layout and broader Unicode fallback remain incomplete. |
|
||||
| M6 | Forms + JavaScript | 160–320 | 50% | 40–75 | Done: filling all field types with regenerated appearances; Prepare a form (every field type, multi-select/shared properties, move/resize/delete, Field Properties General/Appearance/Position/Options/Format/Validate/Calculate); Acrobat's AF format/keystroke/validate/calculate functions and simplified field notation run natively in Acrobat's event order; tab order; push-button actions; flatten; agent tools. Form data exchange (FDF, XFDF, XML, CSV, text) done; XFDF values retain text across XML comments and processing instructions.<br>Done since: JavaScript engine (boa, sandboxed) running custom keystroke/validate/calculate/format and button scripts, document JavaScripts, console. Missing: Actions tab, wider object model (annotations, layers, dialogs), XFA<br>Done since: Tab and Shift-Tab wrapping to the same field or another widget of that field refresh the newly opened editor from the accepted value before Save. Synthetic UI regressions cover both directions, same-frame Save, validation refusal and undo/redo. Renaming a field renames it in the calculations that read it (field lists, notation, literal `getField` names), in one undo step, and says how many changed. The calculation order is read, checked, fixed and set (`form_calculation_order`): fields that calculate too early, loops, fields missing from `/CO`; Fix order moves only what must move, and an edited formula keeps its place. |
|
||||
| M6 | Forms + JavaScript | 160–320 | 50% | 40–75 | Done: filling all field types with regenerated appearances; Prepare a form (every field type, multi-select/shared properties, move/resize/delete, Field Properties General/Appearance/Position/Options/Format/Validate/Calculate); Acrobat's AF format/keystroke/validate/calculate functions and simplified field notation run natively in Acrobat's event order; tab order; push-button actions; flatten; agent tools. Form data exchange (FDF, XFDF, XML, CSV, text) done; XFDF values retain text across XML comments and processing instructions.<br>Done since: JavaScript engine (boa, sandboxed) running custom keystroke/validate/calculate/format and button scripts, document JavaScripts, console. Missing: Actions tab, wider object model (annotations, layers, dialogs), XFA<br>Done since: Tab and Shift-Tab wrapping to the same field or another widget of that field refresh the newly opened editor from the accepted value before Save. Synthetic UI regressions cover both directions, same-frame Save, validation refusal and undo/redo. Renaming a field renames it in the calculations that read it (field lists, notation, literal `getField` names), in one undo step, and says how many changed. Prepare a form ▸ Calculation order, a page of its own: each calculated field's formula and value, what is wrong (fields that calculate too early, loops, fields missing from `/CO`) and Fix order, Up/Down, Alt+↑/↓ and drag, and on the page each field's step and arrows to and from the field in focus (`form_calculation_order` headlessly). |
|
||||
| M7 | Content editing (text, images, header/footer, watermark) | 250–500 | 20% | 100–180 | Done: header & footer, watermarks, backgrounds, Bates; added text and images that stay editable (move, resize, format, rotate, flip, crop, replace); links (Link tool, Link Properties, create from URLs, remove all). Missing: editing existing text and images in place (the longest pole), image/PDF watermarks |
|
||||
| M8 | Security + redaction | 100–180 | 68% | 15–30 | Done: opening protected documents, permissions, Protect Using Password, Remove security; redaction (mark text/areas/pages, Search & Redact with patterns, apply removing glyphs, image pixels, vectors, XObject content, annotations and fields, verification, full rewrite on save); Remove hidden information and Sanitize.<br>Done since: redaction codes (U.S. FOIA and Privacy Act sets as overlay text, in Redaction properties and `redact_mark`). Redaction cleans indirect and form structure references, preserving surviving form tags. Redaction retires inherited resource dictionaries, so a parent `/Pages` can't keep a removed XObject reachable; unredacted pages are left untouched. Image redaction removes alternate images and unsupported masks only on affected images. Changed marked-content spans lose replacement descriptions; untouched spans keep theirs. Hidden-text cleanup retires unused named descriptions across inherited/shared page and form resources (64 focused tests and scoped Rust 1.96 Clippy/wasm checks pass; publication CI pending). Missing: certificate security, custom redaction code sets and pattern locales, DCT re-encoding |
|
||||
| M9 | Signatures (PAdES, validation) | 160–280 | 60% | 40–70 | Done: new `sign` crate (DER, X.509, CMS, PKCS #12 on RustCrypto; aws-lc-rs for RSA private keys); PAdES B-B signing (visible, invisible, existing fields, certification with DocMDP); validation with trust store and changes-after-signing classification; self-signed digital IDs; Signatures panel, message bar, sign dialogs; agent tools. Checked with pdfsig and OpenSSL.<br>Done since: macOS Keychain and Windows Current User Personal store signing (software-backed CNG keys), certificate viewer, signed documents protected from rewrites, page validation overlays separate from original signature artwork (baked Not Verified captions remain; #79 open), snapshot tabs that reuse instead of multiplying. Missing: timestamps (B-T), LTV (DSS, OCSP, CRL), FieldMDP, smart cards, PKCS #11 |
|
||||
@@ -202,6 +202,7 @@ M2 (renderer), M7 (content editing), M10 (OCR and Office), M11 (Preflight and st
|
||||
|
||||
| Date | Change | Summary |
|
||||
|---|---|---|
|
||||
| 2026-10-20 | minor | M6: Prepare a form ▸ Calculation order: formulas and values, what is wrong and Fix order, Up/Down, Alt+↑/↓ and drag, links on the page. Estimates unchanged. |
|
||||
| 2026-10-20 | minor | M6: `form_calculation_order` reads, checks, fixes and sets the calculation order; an edited formula keeps its place in `/CO`. Estimates unchanged. |
|
||||
| 2026-10-19 | minor | M6: renaming a field renames it in the calculations that read it; `form_set_props` returns `formulas_updated` and Field Properties says how many changed. Estimates unchanged. |
|
||||
| 2026-10-18 | minor | M5, PR #1971: nested source `/Page` and `/Pages` dictionaries export as null without traversing page content or the page tree. Synthetic saved/reopened three-page regression retains unrelated metadata and aliases. FDF import semantics, copied-graph limits and estimates unchanged. |
|
||||
|
||||
@@ -4594,10 +4594,10 @@ area = "F"
|
||||
tier = "P0"
|
||||
milestone = "M6"
|
||||
status = "shipped"
|
||||
commands = ["form.field.properties"]
|
||||
commands = ["form.field.properties", "form.calculation_order"]
|
||||
tools = ["form_set_props", "form_fill", "form_calculation_order"]
|
||||
evidence = ["crates/forms/src/tests.rs::formats_validation_and_calculations_run_like_acrobat", "crates/forms/src/tests.rs::the_calculation_order_is_checked_fixed_and_kept", "crates/forms/src/tests.rs::a_calculation_order_with_gaps_and_extra_entries", "crates/forms/src/tests.rs::two_fields_with_one_name_keep_their_places_in_the_order", "crates/engine/src/tests.rs::setting_the_calculation_order_recalculates_and_undoes", "crates/automation/tests/automation.rs::the_calculation_order_is_read_fixed_and_set"]
|
||||
notes = "/CO order, then other calculated fields; recalculated after every fill and Clear form. form_calculation_order reads the order with what each formula reads, says which fields read a field calculated later, which read each other in a loop and which /CO leaves out, and sets it, moves one field (as the Up/Down of Acrobat's Set Field Calculation Order dialog) or fixes it (Fix order moves only what must move). A new calculation joins the end of /CO and an edited one keeps its place. The app has no way to see or change the order yet. Acrobat's dialog is known from Adobe's help summary only, not yet observed."
|
||||
evidence = ["crates/forms/src/tests.rs::formats_validation_and_calculations_run_like_acrobat", "crates/forms/src/tests.rs::the_calculation_order_is_checked_fixed_and_kept", "crates/forms/src/tests.rs::a_calculation_order_with_gaps_and_extra_entries", "crates/forms/src/tests.rs::two_fields_with_one_name_keep_their_places_in_the_order", "crates/engine/src/tests.rs::setting_the_calculation_order_recalculates_and_undoes", "crates/automation/tests/automation.rs::the_calculation_order_is_read_fixed_and_set", "crates/ui-egui/tests/prepare.rs::the_calculation_order_is_moved_dragged_and_fixed"]
|
||||
notes = "/CO order, then other calculated fields; recalculated after every fill and Clear form. Order editing: Prepare a form ▸ Calculation order lists the calculated fields in order with their formulas and values, Up/Down arrows (as Acrobat's Set Field Calculation Order dialog), Alt+Up/Down and drag, says which fields read a field calculated later, which read each other in a loop and which /CO leaves out, and Fix order moves only what must move; on the page it numbers each calculated field's step and draws arrows from the fields the focused field reads and to the fields that read it; form_calculation_order reads, sets, moves and fixes it. A new calculation joins the end of /CO and an edited one keeps its place. Acrobat's dialog is known from Adobe's help summary only, not yet observed."
|
||||
|
||||
[[feature]]
|
||||
id = "form.event-order"
|
||||
|
||||
Reference in New Issue
Block a user