mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-11-09 09:29:44 -06:00
Merge pull request #5118 from dotCooCoo/fix/vars-p1
Variables: art on a locked artboard is not bound or rewritten by a data set
This commit is contained in:
+42
-15
@@ -6,7 +6,7 @@ use std::collections::{BTreeMap, BTreeSet};
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use super::{Document, NodeId, NodeKind, TextKind};
|
||||
use super::{Document, LockedArtboards, NodeId, NodeKind, TextKind};
|
||||
|
||||
/// What a variable drives.
|
||||
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
|
||||
@@ -190,17 +190,32 @@ impl Document {
|
||||
}
|
||||
|
||||
/// Whether a variable may be bound to the object `id`: it is in the document, neither it nor
|
||||
/// anything above it is locked, and nothing above it is hidden. Its own visibility doesn't
|
||||
/// count, as that is what a visibility variable drives.
|
||||
/// anything above it is locked, nothing above it is hidden, and it is not on a locked artboard
|
||||
/// ([`Document::on_locked_artboard`]). Its own visibility doesn't count, as that is what a
|
||||
/// visibility variable drives.
|
||||
pub fn variable_target(&self, id: NodeId) -> bool {
|
||||
self.ancestry(id).is_some_and(|a| a.iter().all(|i| self.node(*i).is_some_and(|n| !n.locked && (n.visible || *i == id))))
|
||||
self.variable_target_with(&self.locked_artboards(), id)
|
||||
}
|
||||
|
||||
/// Whether a data set reads and rewrites the bound object `id`: it is in the document and
|
||||
/// neither it nor anything above it is locked. Hidden objects count, and so do objects in a
|
||||
/// hidden layer or group.
|
||||
/// [`Document::variable_target`] with the locked artboards `locks` of this document, measured
|
||||
/// once for many ids.
|
||||
pub fn variable_target_with(&self, locks: &LockedArtboards, id: NodeId) -> bool {
|
||||
self.ancestry(id).is_some_and(|a| a.iter().all(|i| self.node(*i).is_some_and(|n| !n.locked && (n.visible || *i == id))))
|
||||
&& !locks.holds_id(id)
|
||||
}
|
||||
|
||||
/// Whether a data set reads and rewrites the bound object `id`: it is in the document, neither
|
||||
/// it nor anything above it is locked, and it is not on a locked artboard
|
||||
/// ([`Document::on_locked_artboard`]). Hidden objects count, and so do objects in a hidden
|
||||
/// layer or group.
|
||||
pub fn dataset_target(&self, id: NodeId) -> bool {
|
||||
self.ancestry(id).is_some_and(|a| a.iter().all(|i| self.node(*i).is_some_and(|n| !n.locked)))
|
||||
self.dataset_target_with(&self.locked_artboards(), id)
|
||||
}
|
||||
|
||||
/// [`Document::dataset_target`] with the locked artboards `locks` of this document, measured
|
||||
/// once for many ids.
|
||||
pub fn dataset_target_with(&self, locks: &LockedArtboards, id: NodeId) -> bool {
|
||||
self.ancestry(id).is_some_and(|a| a.iter().all(|i| self.node(*i).is_some_and(|n| !n.locked))) && !locks.holds_id(id)
|
||||
}
|
||||
|
||||
/// The type objects of the story that the type object `id` belongs to, in thread order: the
|
||||
@@ -228,21 +243,32 @@ impl Document {
|
||||
/// Whether a data set reads and rewrites the text of the type object `id`: every frame of its
|
||||
/// story ([`Document::story_of`]) is a [`Document::dataset_target`].
|
||||
pub fn story_target(&self, id: NodeId) -> bool {
|
||||
self.story_of(id).into_iter().all(|f| self.dataset_target(f))
|
||||
self.story_target_with(&self.locked_artboards(), id)
|
||||
}
|
||||
|
||||
/// [`Document::story_target`] with the locked artboards `locks` of this document, measured
|
||||
/// once for many ids.
|
||||
pub fn story_target_with(&self, locks: &LockedArtboards, id: NodeId) -> bool {
|
||||
self.story_of(id).into_iter().all(|f| self.dataset_target_with(locks, f))
|
||||
}
|
||||
|
||||
/// What the object `id` holds for the variable of `kind`: its characters (the whole story
|
||||
/// for a frame of threaded text), whether it shows, or a linked image's path. `None` when the
|
||||
/// object is gone, is not of that kind, has no link path yet (an embedded image), or is locked
|
||||
/// or in a locked layer or group, or for text when a frame of its story is (the document's
|
||||
/// value is whatever it was left at).
|
||||
/// object is gone, is not of that kind, has no link path yet (an embedded image), or is locked,
|
||||
/// in a locked layer or group, or on a locked artboard, or for text when a frame of its story
|
||||
/// is (the document's value is whatever it was left at).
|
||||
pub fn variable_value(&self, id: NodeId, kind: VariableKind) -> Option<DataValue> {
|
||||
if !self.dataset_target(id) {
|
||||
self.variable_value_with(&self.locked_artboards(), id, kind)
|
||||
}
|
||||
|
||||
/// [`Document::variable_value`] with the locked artboards `locks` of this document.
|
||||
fn variable_value_with(&self, locks: &LockedArtboards, id: NodeId, kind: VariableKind) -> Option<DataValue> {
|
||||
if !self.dataset_target_with(locks, id) {
|
||||
return None;
|
||||
}
|
||||
let node = self.node(id)?;
|
||||
match (kind, &node.kind) {
|
||||
(VariableKind::Text, NodeKind::Text(_)) if self.story_target(id) => Some(DataValue::Text(self.story_text(id))),
|
||||
(VariableKind::Text, NodeKind::Text(_)) if self.story_target_with(locks, id) => Some(DataValue::Text(self.story_text(id))),
|
||||
(VariableKind::Visibility, _) => Some(DataValue::Visible(node.visible)),
|
||||
(VariableKind::Image, NodeKind::Image(im)) => im.link.as_ref().map(|l| DataValue::Image(l.path.clone())),
|
||||
(VariableKind::Graph, _) => node.extras().graph.as_ref().map(|g| DataValue::Graph(g.to_csv())),
|
||||
@@ -257,10 +283,11 @@ impl Document {
|
||||
/// still matches what it says.
|
||||
pub fn captured_values(&self) -> BTreeMap<String, DataValue> {
|
||||
let mut out = BTreeMap::new();
|
||||
let locks = self.locked_artboards();
|
||||
for v in &self.variables.variables {
|
||||
// An object driven by several variables of the same kind reads from the first one
|
||||
// bound, so a capture is one value per variable and applies back the same way.
|
||||
let value = self.variables.objects_of(&v.name).into_iter().find_map(|id| self.variable_value(id, v.kind));
|
||||
let value = self.variables.objects_of(&v.name).into_iter().find_map(|id| self.variable_value_with(&locks, id, v.kind));
|
||||
if let Some(value) = value {
|
||||
out.insert(v.name.clone(), value);
|
||||
}
|
||||
|
||||
@@ -138,13 +138,15 @@ fn names_param(p: &Value, cmd: &str, fallback: Option<String>, nothing: &str) ->
|
||||
}
|
||||
}
|
||||
|
||||
/// Refuse what a variable of `kind` can't be bound to: art that is locked or on a hidden or locked
|
||||
/// layer; a text variable only drives type; an image variable only drives an image object.
|
||||
/// Refuse what a variable of `kind` can't be bound to: art that is locked, on a hidden or locked
|
||||
/// layer, or on a locked artboard; a text variable only drives type; an image variable only drives
|
||||
/// an image object.
|
||||
fn check_bindable(doc: &vectorcraft_doc::Document, ids: &[NodeId], kind: VariableKind, cmd: &str) -> Result<()> {
|
||||
let locks = doc.locked_artboards();
|
||||
for id in ids {
|
||||
match doc.node(*id) {
|
||||
None => return Err(EngineError::NoNode(*id)),
|
||||
Some(_) if !doc.variable_target(*id) => return Err(bad(cmd, not_a_target(doc, *id))),
|
||||
Some(_) if !doc.variable_target_with(&locks, *id) => return Err(bad(cmd, not_a_target(doc, *id))),
|
||||
Some(n) if kind == VariableKind::Text && !matches!(n.kind, NodeKind::Text(_)) => {
|
||||
return Err(bad(cmd, format!("node {} is not type", id.0)));
|
||||
}
|
||||
@@ -161,7 +163,7 @@ fn check_bindable(doc: &vectorcraft_doc::Document, ids: &[NodeId], kind: Variabl
|
||||
}
|
||||
|
||||
/// Why `variable_target` refuses `id`: the object is locked, a group or layer that holds it is
|
||||
/// locked, or one that holds it is hidden, checked in that order.
|
||||
/// locked, one that holds it is hidden, or it is on a locked artboard, checked in that order.
|
||||
fn not_a_target(doc: &vectorcraft_doc::Document, id: NodeId) -> String {
|
||||
let holders: Vec<&vectorcraft_doc::Node> =
|
||||
doc.ancestry(id).unwrap_or_default().into_iter().filter(|i| *i != id).filter_map(|i| doc.node(i)).collect();
|
||||
@@ -169,8 +171,10 @@ fn not_a_target(doc: &vectorcraft_doc::Document, id: NodeId) -> String {
|
||||
format!("node {} is locked", id.0)
|
||||
} else if holders.iter().any(|n| n.locked) {
|
||||
format!("node {} is in a locked group or layer", id.0)
|
||||
} else {
|
||||
} else if holders.iter().any(|n| !n.visible) {
|
||||
format!("node {} is in a hidden group or layer", id.0)
|
||||
} else {
|
||||
format!("node {} is on a locked artboard", id.0)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -483,7 +487,7 @@ fn dataset_capture(s: &mut Session, p: &Value) -> Result<Value> {
|
||||
|
||||
/// Update Data Set: write what the bound objects hold now into the row that is active, for each
|
||||
/// variable the row holds. A variable whose objects report no value (locked, inside a locked
|
||||
/// layer or group, or gone) keeps the row's value. With `all`, every other variable the
|
||||
/// layer or group, on a locked artboard, or gone) keeps the row's value. With `all`, every other variable the
|
||||
/// objects report a value for is added to the row. Without an active row there is nothing to
|
||||
/// update, so say so rather than picking one. With every bound object locked, no value is
|
||||
/// written; an update that writes no value adds no undo step.
|
||||
@@ -557,6 +561,20 @@ fn apply_dataset(s: &mut Session, name: &str) -> Result<Value> {
|
||||
for v in &d.variables.variables {
|
||||
pairs.extend(d.variables.objects_of(&v.name).into_iter().map(|id| (id, v.name.clone())));
|
||||
}
|
||||
// Which bound objects the row may rewrite, measured once before any of them changes, so
|
||||
// text that grows onto a locked artboard part way through is still rewritten. Each id is
|
||||
// keyed by whether a text value is meant for it, which checks every frame of its story.
|
||||
let targets: BTreeSet<(NodeId, bool)> = {
|
||||
let locks = d.locked_artboards();
|
||||
let mut out = BTreeSet::new();
|
||||
for (id, var) in &pairs {
|
||||
let text = d.variables.variable(var).is_some_and(|v| v.kind == VariableKind::Text);
|
||||
if if text { d.story_target_with(&locks, *id) } else { d.dataset_target_with(&locks, *id) } {
|
||||
out.insert((*id, text));
|
||||
}
|
||||
}
|
||||
out
|
||||
};
|
||||
// Whether an object is bound to a variable that this row has a value for (the reply's `warning`).
|
||||
let bound = pairs.iter().any(|(_, var)| ds.values.contains_key(var));
|
||||
let mut applied = 0usize;
|
||||
@@ -574,12 +592,12 @@ fn apply_dataset(s: &mut Session, name: &str) -> Result<Value> {
|
||||
continue;
|
||||
}
|
||||
};
|
||||
// Locked art, art in a locked layer or group, and text whose object is gone, can't be
|
||||
// rewritten: skipped and counted, like the rest. Hidden art is rewritten, in a hidden
|
||||
// layer or group too, and stays hidden unless a visibility value shows it. A text value
|
||||
// rewrites the whole story of threaded text, so it skips when any frame of it is locked.
|
||||
let target = if kind == VariableKind::Text { d.story_target(id) } else { d.dataset_target(id) };
|
||||
if !target {
|
||||
// Locked art, art in a locked layer or group or on a locked artboard, and text whose
|
||||
// object is gone, can't be rewritten: skipped and counted, like the rest. Hidden art
|
||||
// is rewritten, in a hidden layer or group too, and stays hidden unless a visibility
|
||||
// value shows it. A text value rewrites the whole story of threaded text, so it skips
|
||||
// when any frame of it is locked or on a locked artboard.
|
||||
if !targets.contains(&(id, kind == VariableKind::Text)) {
|
||||
skipped += 1;
|
||||
continue;
|
||||
}
|
||||
@@ -772,7 +790,7 @@ pub fn specs() -> Vec<CommandSpec> {
|
||||
"Update Data Set",
|
||||
["Window", "Variables"],
|
||||
None,
|
||||
"{all?: bool} write what the bound objects hold now into the active dataset, for each variable the dataset holds; a variable whose objects report no value (locked, inside a locked layer or group, or gone) keeps the dataset's value. `all: true` also adds every other variable the objects report a value for; `left` names the variables it didn't write → {values, left}",
|
||||
"{all?: bool} write what the bound objects hold now into the active dataset, for each variable the dataset holds; a variable whose objects report no value (locked, inside a locked layer or group, on a locked artboard, or gone) keeps the dataset's value. `all: true` also adds every other variable the objects report a value for; `left` names the variables it didn't write → {values, left}",
|
||||
has_doc,
|
||||
dataset_update
|
||||
),
|
||||
|
||||
@@ -438,6 +438,68 @@ fn locked_art_is_neither_bound_nor_rewritten() {
|
||||
assert!(!s.doc().unwrap().doc.node(r).unwrap().visible, "the unlocked rectangle still applied");
|
||||
}
|
||||
|
||||
/// The art on a locked artboard acts as locked art: a data set skips it, Update Data Set reads
|
||||
/// nothing from it, and it takes no new binding. Unlocking the artboard lets the data set rewrite it.
|
||||
#[test]
|
||||
fn art_on_a_locked_artboard_is_neither_bound_nor_rewritten() {
|
||||
let mut s = session();
|
||||
let t = NodeId(s.execute("text.create", &json!({"x": 2050, "y": 50, "text": "cat"})).unwrap()["id"].as_u64().unwrap());
|
||||
let fresh = NodeId(s.execute("text.create", &json!({"x": 2100, "y": 100, "text": "new"})).unwrap()["id"].as_u64().unwrap());
|
||||
let r = rect(&mut s);
|
||||
s.execute("artboard.new", &json!({"x": 2000, "y": 0, "width": 400, "height": 400})).unwrap();
|
||||
s.execute("variable.define", &json!({"name": "Name", "kind": "text"})).unwrap();
|
||||
s.execute("variable.define", &json!({"name": "Show", "kind": "visibility"})).unwrap();
|
||||
s.execute("variable.define", &json!({"name": "Box", "kind": "visibility"})).unwrap();
|
||||
s.execute("variable.bind", &json!({"variable": "Name", "ids": [t.0]})).unwrap();
|
||||
s.execute("variable.bind", &json!({"variable": "Show", "ids": [t.0]})).unwrap();
|
||||
s.execute("variable.bind", &json!({"variable": "Box", "ids": [r.0]})).unwrap();
|
||||
s.execute("dataset.capture", &json!({"name": "A"})).unwrap();
|
||||
s.execute("dataset.new", &json!({"name": "B", "values": {"Name": "Bob", "Show": false, "Box": false}})).unwrap();
|
||||
s.execute("select.none", &json!({})).unwrap();
|
||||
s.execute("artboard.setProps", &json!({"index": 1, "locked": true})).unwrap();
|
||||
|
||||
let e = s.execute("variable.bind", &json!({"variable": "Name", "ids": [fresh.0]})).unwrap_err().to_string();
|
||||
assert!(e.contains(&format!("node {} is on a locked artboard", fresh.0)), "{e}");
|
||||
let v = s.execute("dataset.select", &json!({"name": "B"})).unwrap();
|
||||
assert_eq!((v["applied"].as_u64(), v["skipped"].as_u64()), (Some(1), Some(2)), "{v}");
|
||||
assert_eq!(plain(&s, t), "cat", "the text on the locked artboard was left alone");
|
||||
assert!(s.doc().unwrap().doc.node(t).unwrap().visible, "and still shows");
|
||||
assert!(!s.doc().unwrap().doc.node(r).unwrap().visible, "the rectangle off it applied");
|
||||
// Update Data Set keeps the row's values for the art it can't read.
|
||||
let v = s.execute("dataset.update", &json!({})).unwrap();
|
||||
assert_eq!(v["values"], 1, "{v}");
|
||||
let row = s.doc().unwrap().doc.variables.dataset("B").unwrap().values.clone();
|
||||
assert_eq!(row.get("Name"), Some(&vectorcraft_doc::DataValue::Text("Bob".into())));
|
||||
assert_eq!(row.get("Show"), Some(&vectorcraft_doc::DataValue::Visible(false)));
|
||||
|
||||
s.execute("artboard.setProps", &json!({"index": 1, "locked": false})).unwrap();
|
||||
let v = s.execute("dataset.select", &json!({"name": "B"})).unwrap();
|
||||
assert_eq!((v["applied"].as_u64(), v["skipped"].as_u64()), (Some(3), Some(0)), "{v}");
|
||||
assert_eq!(plain(&s, t), "Bob");
|
||||
}
|
||||
|
||||
/// A locked artboard elsewhere in the document does not stop threaded type on an unlocked artboard
|
||||
/// from having its whole story rewritten, and type on the locked artboard is still left alone.
|
||||
#[test]
|
||||
fn threaded_type_on_an_unlocked_artboard_is_rewritten_beside_a_locked_artboard() {
|
||||
let (mut s, a, b, story) = threaded(200);
|
||||
let far = NodeId(s.execute("text.create", &json!({"x": 2050, "y": 50, "text": "cat"})).unwrap()["id"].as_u64().unwrap());
|
||||
s.execute("artboard.new", &json!({"x": 2000, "y": 0, "width": 400, "height": 400})).unwrap();
|
||||
s.execute("variable.define", &json!({"name": "Name", "kind": "text"})).unwrap();
|
||||
s.execute("variable.define", &json!({"name": "Tail", "kind": "text"})).unwrap();
|
||||
s.execute("variable.bind", &json!({"variable": "Name", "ids": [a.0]})).unwrap();
|
||||
s.execute("variable.bind", &json!({"variable": "Tail", "ids": [far.0]})).unwrap();
|
||||
s.execute("dataset.new", &json!({"name": "B", "values": {"Name": "Bob", "Tail": "dog"}})).unwrap();
|
||||
s.execute("select.none", &json!({})).unwrap();
|
||||
s.execute("artboard.setProps", &json!({"index": 1, "locked": true})).unwrap();
|
||||
|
||||
let v = s.execute("dataset.select", &json!({"name": "B"})).unwrap();
|
||||
assert_eq!((v["applied"].as_u64(), v["skipped"].as_u64()), (Some(1), Some(1)), "{v}");
|
||||
assert_eq!((plain(&s, a), plain(&s, b)), ("Bob".to_string(), String::new()), "the whole story was rewritten");
|
||||
assert_eq!(plain(&s, far), "cat", "the text on the locked artboard was left alone");
|
||||
assert!(!story.is_empty());
|
||||
}
|
||||
|
||||
/// Binding fails for locked art and for art in a hidden or locked group or layer, and the
|
||||
/// error names which of the three applies.
|
||||
#[test]
|
||||
|
||||
@@ -5275,6 +5275,7 @@ digits Malayalam Malaiàlam
|
||||
@msg no user library folder here aquí no hi ha cap carpeta de biblioteca d’usuari
|
||||
@msg no user workspace `{from}` no hi ha l’espai de treball d’usuari `{from}`
|
||||
@msg node {_1} is not text el node {_1} no és text
|
||||
@msg node {_1} is on a locked artboard el node {_1} és en un tauler bloquejat
|
||||
@msg Non-finite dimension Cota no finita
|
||||
@msg not a blend no és una fusió
|
||||
@msg not a DXF drawing no és un dibuix DXF
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -4609,6 +4609,7 @@ imageTrace Outline Obrys
|
||||
@msg no user library folder here zde není složka uživatelských knihoven
|
||||
@msg no user workspace `{from}` uživatelský pracovní prostor `{from}` neexistuje
|
||||
@msg node {_1} is not text uzel {_1} není text
|
||||
@msg node {_1} is on a locked artboard uzel {_1} je na zamčené pracovní ploše
|
||||
@msg not a DXF drawing nejde o výkres DXF
|
||||
@msg not a VectorCraft file: {0} nejde o soubor VectorCraft: {0}
|
||||
@msg not a VectorCraft shortcut set (missing `overrides`) nejde o sadu klávesových zkratek VectorCraft (chybí `overrides`)
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -4218,6 +4218,7 @@ theme Appearance Erscheinungsbild
|
||||
@msg no user library folder here hier gibt es keinen Ordner für Benutzerbibliotheken
|
||||
@msg no user workspace `{from}` kein Benutzerarbeitsbereich `{from}`
|
||||
@msg node {_1} is not text Knoten {_1} ist kein Text
|
||||
@msg node {_1} is on a locked artboard Knoten {_1} liegt auf einer gesperrten Zeichenfläche
|
||||
@msg not a DXF drawing keine DXF-Zeichnung
|
||||
@msg not a VectorCraft file: {0} keine VectorCraft-Datei: {0}
|
||||
@msg not a VectorCraft shortcut set (missing `overrides`) kein VectorCraft-Tastaturbefehlssatz (`overrides` fehlt)
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -4257,6 +4257,7 @@ digits Malayalam Μαλαγιάλαμ
|
||||
@msg no user library folder here δεν υπάρχει φάκελος βιβλιοθήκης χρήστη εδώ
|
||||
@msg no user workspace `{from}` δεν υπάρχει χώρος εργασίας χρήστη `{from}`
|
||||
@msg node {_1} is not text ο κόμβος {_1} δεν είναι κείμενο
|
||||
@msg node {_1} is on a locked artboard ο κόμβος {_1} βρίσκεται σε κλειδωμένο πίνακα σχεδίασης
|
||||
@msg not a DXF drawing δεν είναι σχέδιο DXF
|
||||
@msg not a VectorCraft file: {0} δεν είναι αρχείο VectorCraft: {0}
|
||||
@msg not a VectorCraft shortcut set (missing `overrides`) δεν είναι σύνολο συντομεύσεων VectorCraft (λείπει το `overrides`)
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 163 and column 5.
|
@@ -4302,6 +4302,7 @@ axis Both Ambos
|
||||
@msg no user library folder here aquí no hay ninguna carpeta de bibliotecas de usuario
|
||||
@msg no user workspace `{from}` no existe el espacio de trabajo de usuario `{from}`
|
||||
@msg node {_1} is not text el nodo {_1} no es texto
|
||||
@msg node {_1} is on a locked artboard el nodo {_1} está en una mesa de trabajo bloqueada
|
||||
@msg not a DXF drawing no es un dibujo DXF
|
||||
@msg not a VectorCraft file: {0} no es un archivo de VectorCraft: {0}
|
||||
@msg not a VectorCraft shortcut set (missing `overrides`) no es un conjunto de atajos de VectorCraft (falta `overrides`)
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -4517,6 +4517,7 @@ imageTrace Outline Ääriviiva
|
||||
@msg no user library folder here täällä ei ole käyttäjäkirjastokansiota
|
||||
@msg no user workspace `{from}` ei käyttäjän työtilaa `{from}`
|
||||
@msg node {_1} is not text solmu {_1} ei ole tekstiä
|
||||
@msg node {_1} is on a locked artboard solmu {_1} on lukitulla piirtoalustalla
|
||||
@msg not a DXF drawing ei DXF-piirustus
|
||||
@msg not a VectorCraft file: {0} ei VectorCraft-tiedosto: {0}
|
||||
@msg not a VectorCraft shortcut set (missing `overrides`) ei VectorCraftin pikanäppäinjoukko (`overrides` puuttuu)
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -4292,6 +4292,7 @@ axis Both Les deux
|
||||
@msg no user library folder here aucun dossier de bibliothèques utilisateur ici
|
||||
@msg no user workspace `{from}` aucun espace de travail utilisateur `{from}`
|
||||
@msg node {_1} is not text le nœud {_1} n’est pas du texte
|
||||
@msg node {_1} is on a locked artboard le nœud {_1} est sur un plan de travail verrouillé
|
||||
@msg not a DXF drawing ce n’est pas un dessin DXF
|
||||
@msg not a VectorCraft file: {0} ce n’est pas un fichier VectorCraft : {0}
|
||||
@msg not a VectorCraft shortcut set (missing `overrides`) ce n’est pas un jeu de raccourcis VectorCraft (`overrides` manquant)
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -4976,6 +4976,7 @@ imageTrace Outline Körvonal
|
||||
@msg no user library folder here itt nincs felhasználói könyvtármappa
|
||||
@msg no user workspace `{from}` nincs ilyen felhasználói munkaterület: `{from}`
|
||||
@msg node {_1} is not text a csomópont nem szöveg: {_1}
|
||||
@msg node {_1} is on a locked artboard a csomópont zárolt rajztáblán van: {_1}
|
||||
@msg not a DXF drawing nem DXF-rajz
|
||||
@msg not a file nem fájl
|
||||
@msg not a font file nem betűtípusfájl
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -4344,6 +4344,7 @@ axis Both Entrambi
|
||||
@msg no user library folder here nessuna cartella di librerie utente qui
|
||||
@msg no user workspace `{from}` nessuna area di lavoro utente `{from}`
|
||||
@msg node {_1} is not text il nodo {_1} non è testo
|
||||
@msg node {_1} is on a locked artboard il nodo {_1} è su una tavola da disegno bloccata
|
||||
@msg not a DXF drawing non è un disegno DXF
|
||||
@msg not a VectorCraft file: {0} non è un file VectorCraft: {0}
|
||||
@msg not a VectorCraft shortcut set (missing `overrides`) non è un set di scelte rapide VectorCraft (manca `overrides`)
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -4306,6 +4306,7 @@ swatch Bright Violet ビビッドバイオレット
|
||||
@msg a key object sits on that point そのポイントにはキーオブジェクトがあります
|
||||
@msg no graphic style `{name}` グラフィックスタイル `{name}` が見つかりません
|
||||
@msg node {_1} is not text ノード {_1} はテキストではありません
|
||||
@msg node {_1} is on a locked artboard ノード {_1} はロックされたアートボード上にあります
|
||||
@msg Text Wrap: select a wrap object テキストの回り込み: 回り込みオブジェクトを選択してください
|
||||
@msg layers can't be wrap objects レイヤーは回り込みオブジェクトにできません
|
||||
@msg line {line}: value for `{var}` must be true or false {line} 行目: `{var}` の値には true または false を指定してください
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -4059,6 +4059,7 @@ font-technology Variable ცვლადი
|
||||
@msg no user library folder here აქ მომხმარებლის ბიბლიოთეკის საქაღალდე არ არის
|
||||
@msg no user workspace `{from}` მომხმარებლის სამუშაო სივრცე `{from}` არ არის
|
||||
@msg node {_1} is not text კვანძი {_1} ტექსტი არ არის
|
||||
@msg node {_1} is on a locked artboard კვანძი {_1} ჩაკეტილ სამუშაო დაფაზეა
|
||||
@msg not a DXF drawing ეს არ არის DXF ნახაზი
|
||||
@msg not a VectorCraft file: {0} ეს არ არის VectorCraft-ის ფაილი: {0}
|
||||
@msg not a VectorCraft shortcut set (missing `overrides`) ეს არ არის VectorCraft-ის მალსახმობების ნაკრები (აკლია `overrides`)
|
||||
|
||||
|
Can't render this file because it is too large.
|
@@ -4233,6 +4233,7 @@ theme Appearance 외관
|
||||
@msg a key object sits on that point 그 포인트에 키 개체가 있습니다
|
||||
@msg no graphic style `{name}` `{name}` 그래픽 스타일이 없습니다
|
||||
@msg node {_1} is not text 노드 {_1}은(는) 텍스트가 아닙니다
|
||||
@msg node {_1} is on a locked artboard 노드 {_1}이(가) 잠긴 아트보드에 있습니다
|
||||
@msg Text Wrap: select a wrap object 텍스트 감싸기: 감싸기 개체를 선택하세요
|
||||
@msg layers can't be wrap objects 레이어는 감싸기 개체가 될 수 없습니다
|
||||
@msg line {line}: value for `{var}` must be true or false {line}행: `{var}`의 값은 true 또는 false여야 합니다
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -4432,6 +4432,7 @@ imageTrace Outline Kontur
|
||||
@msg no user library folder here brak folderu bibliotek użytkownika
|
||||
@msg no user workspace `{from}` brak obszaru roboczego użytkownika `{from}`
|
||||
@msg node {_1} is not text węzeł {_1} nie jest tekstem
|
||||
@msg node {_1} is on a locked artboard węzeł {_1} jest na zablokowanym obszarze kompozycji
|
||||
@msg not a DXF drawing to nie jest rysunek DXF
|
||||
@msg not a VectorCraft file: {0} to nie jest plik VectorCraft: {0}
|
||||
@msg not a VectorCraft shortcut set (missing `overrides`) to nie jest zestaw skrótów VectorCraft (brak `overrides`)
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -3887,6 +3887,7 @@ axis Both Ambos
|
||||
@msg no user library folder here nenhuma pasta de biblioteca do usuário aqui
|
||||
@msg no user workspace `{from}` nenhum espaço de trabalho do usuário `{from}`
|
||||
@msg node {_1} is not text o nó {_1} não é texto
|
||||
@msg node {_1} is on a locked artboard o nó {_1} está em uma prancheta bloqueada
|
||||
@msg not a DXF drawing não é um desenho DXF
|
||||
@msg not a VectorCraft file: {0} não é um arquivo do VectorCraft: {0}
|
||||
@msg not a VectorCraft shortcut set (missing `overrides`) não é um conjunto de atalhos do VectorCraft (falta `overrides`)
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 6 and column 47.
|
@@ -4339,6 +4339,7 @@ axis Both Оба
|
||||
@msg no user library folder here здесь нет папки пользовательских библиотек
|
||||
@msg no user workspace `{from}` нет пользовательской рабочей среды `{from}`
|
||||
@msg node {_1} is not text узел {_1} не является текстом
|
||||
@msg node {_1} is on a locked artboard узел {_1} находится на заблокированной монтажной области
|
||||
@msg not a DXF drawing не является чертежом DXF
|
||||
@msg not a VectorCraft file: {0} не является файлом VectorCraft: {0}
|
||||
@msg not a VectorCraft shortcut set (missing `overrides`) не является набором сочетаний клавиш VectorCraft (отсутствует `overrides`)
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -4207,6 +4207,7 @@ axis Both Båda
|
||||
@msg no user library folder here ingen mapp för användarbibliotek här
|
||||
@msg no user workspace `{from}` ingen användararbetslayout `{from}`
|
||||
@msg node {_1} is not text nod {_1} är inte text
|
||||
@msg node {_1} is on a locked artboard nod {_1} ligger på en låst rityta
|
||||
@msg not a DXF drawing inte en DXF-ritning
|
||||
@msg not a VectorCraft file: {0} inte en VectorCraft-fil: {0}
|
||||
@msg not a VectorCraft shortcut set (missing `overrides`) inte en kortkommandouppsättning för VectorCraft (`overrides` saknas)
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 5 and column 25.
|
@@ -4062,6 +4062,7 @@ axis Both Her İkisi
|
||||
@msg no user library folder here burada kullanıcı kitaplığı klasörü yok
|
||||
@msg no user workspace `{from}` kullanıcı çalışma alanı yok `{from}`
|
||||
@msg node {_1} is not text {_1} düğümü metin değil
|
||||
@msg node {_1} is on a locked artboard {_1} düğümü kilitli bir çalışma yüzeyinde
|
||||
@msg not a DXF drawing DXF çizimi değil
|
||||
@msg not a VectorCraft file: {0} bir VectorCraft dosyası değil: {0}
|
||||
@msg not a VectorCraft shortcut set (missing `overrides`) VectorCraft kısayol seti değil ("geçersiz kılmalar" eksik)
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 5 and column 25.
|
@@ -4328,6 +4328,7 @@ axis Both Обидві
|
||||
@msg no user library folder here тут немає папки користувацьких бібліотек
|
||||
@msg no user workspace `{from}` немає користувача робочого середовища `{from}`
|
||||
@msg node {_1} is not text вузол {_1} не є текстом
|
||||
@msg node {_1} is on a locked artboard вузол {_1} розташований на заблокованій монтажній області
|
||||
@msg not a DXF drawing не є кресленням DXF
|
||||
@msg not a VectorCraft file: {0} не є файлом VectorCraft: {0}
|
||||
@msg not a VectorCraft shortcut set (missing `overrides`) не є набором поєднань клавіш VectorCraft (відсутнє `overrides`)
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 177 and column 5.
|
@@ -4628,6 +4628,7 @@ theme Appearance Giao diện
|
||||
@msg no user library folder here không có thư mục thư viện người dùng ở đây
|
||||
@msg no user workspace `{from}` không có không gian làm việc người dùng `{from}`
|
||||
@msg node {_1} is not text nút {_1} không phải là văn bản
|
||||
@msg node {_1} is on a locked artboard nút {_1} nằm trên bảng vẽ bị khóa
|
||||
@msg not a blend không phải đối tượng hòa trộn
|
||||
@msg not a DXF drawing không phải bản vẽ DXF
|
||||
@msg not a file không phải tệp
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 199 and column 5.
|
@@ -4031,6 +4031,7 @@ imageTrace Outline 轮廓
|
||||
@msg a graphic style named `{to}` already exists 名为 `{to}` 的图形样式已存在
|
||||
@msg no graphic style `{name}` 没有图形样式 `{name}`
|
||||
@msg node {_1} is not text 节点 {_1} 不是文字
|
||||
@msg node {_1} is on a locked artboard 节点 {_1} 位于已锁定的画板上
|
||||
@msg Text Wrap: select a wrap object 文本绕排:请选择一个绕排对象
|
||||
@msg layers can't be wrap objects 图层不能作为绕排对象
|
||||
@msg line {line}: value for `{var}` must be true or false 第 {line} 行:`{var}` 的值必须是 true 或 false
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -1938,6 +1938,7 @@ file-filter Templates 範本
|
||||
@msg a graphic style named `{to}` already exists 名為 `{to}` 的繪圖樣式已存在
|
||||
@msg no graphic style `{name}` 沒有繪圖樣式 `{name}`
|
||||
@msg node {_1} is not text 節點 {_1} 不是文字
|
||||
@msg node {_1} is on a locked artboard 節點 {_1} 位於已鎖定的工作區域上
|
||||
@msg Text Wrap: select a wrap object 文字繞圖:請選取繞圖物件
|
||||
@msg layers can't be wrap objects 圖層不能作為繞圖物件
|
||||
@msg line {line}: value for `{var}` must be true or false 第 {line} 行:`{var}` 的值必須是 true 或 false
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 6 and column 47.
|
+2
-2
@@ -1813,7 +1813,7 @@ document stays unmodified.
|
||||
`dataset.select`, `dataset.next` and `dataset.prev` reply `{name, applied, skipped}`. They add `overflow: [id…]`
|
||||
when area type or type on a path whose text they rewrote doesn't fit, as `text.setText` does (see
|
||||
[Fitting area type](#fitting-area-type-auto-size-shrink-text-to-fit-overflow)). They skip an object that is
|
||||
locked or inside a locked layer or group, and count it in `skipped`. They rewrite hidden objects and objects inside
|
||||
locked, inside a locked layer or group, or on a locked artboard, and count it in `skipped`. They rewrite hidden objects and objects inside
|
||||
a hidden layer or group, which stay hidden unless one of the data set's visibility values shows them. When such a
|
||||
layer is shown again, its type holds the data set's text. They apply the values in the order the variables are
|
||||
defined. Of two variables of the same kind on one object, the one defined last wins. `dataset.list`,
|
||||
@@ -1848,7 +1848,7 @@ or no, or a graph value longer than 262,144 bytes.
|
||||
|
||||
`dataset.update {all?}` writes what the bound objects hold now into the active data set, for each variable that the
|
||||
data set holds. A variable whose objects report no value, because they are locked, inside a locked layer or group,
|
||||
or deleted, keeps the data set's value. With `all: true` it also adds every other variable that the
|
||||
on a locked artboard, or deleted, keeps the data set's value. With `all: true` it also adds every other variable that the
|
||||
objects report a value for. The reply gives `values`, the number of values it wrote, and `left`, the variables it
|
||||
did not write. When every bound object is locked, it writes no value and adds no undo step, and `dataset.capture`
|
||||
returns the error "no bound object reports a value (locked objects and embedded images report none)".
|
||||
|
||||
Reference in New Issue
Block a user