mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-11-14 20:36:02 +00:00
Merge pull request #7179 from dotCooCoo/fix/place-read-own-document
Place: a file read apart from the session goes only into its document
This commit is contained in:
@@ -58,6 +58,9 @@ use crate::{EngineError, MAX_COORD};
|
||||
|
||||
const PLACE: &str = "file.place";
|
||||
const QUEUE: &str = "file.place.queue";
|
||||
/// The error of a file read apart from the session while another document is active, or after the
|
||||
/// document it was read for closed ([`Session::place_read`], [`Session::place_queue_read`]).
|
||||
const NOT_ACTIVE: &str = "the document it was prepared for is no longer active";
|
||||
/// The most files one `file.place.queue` loads.
|
||||
const MAX_QUEUE: usize = 100;
|
||||
/// The longest thumbnail side `thumbnail` may ask for (px).
|
||||
@@ -503,11 +506,13 @@ fn fit(natural: Rect, r: Rect) -> Affine {
|
||||
Affine::translate(r.center().to_vec2()) * Affine::scale(k) * Affine::translate(-natural.center().to_vec2())
|
||||
}
|
||||
|
||||
/// What `file.place` takes from the session before it reads the file: the params, the object
|
||||
/// Replace swaps and the artboard under `at`, which a DXF drawing is laid out on
|
||||
/// ([`Session::prepare_place`]). [`PlaceJob::read`] reads and decodes the file without the session,
|
||||
/// on any thread.
|
||||
/// What `file.place` takes from the session before it reads the file: the document it places into,
|
||||
/// the params, the object Replace swaps and the artboard under `at`, which a DXF drawing is laid
|
||||
/// out on ([`Session::prepare_place`]). [`PlaceJob::read`] reads and decodes the file without the
|
||||
/// session, on any thread.
|
||||
pub struct PlaceJob {
|
||||
/// The document it was prepared in (`DocState::uid`).
|
||||
doc: u64,
|
||||
params: Value,
|
||||
old: Option<NodeId>,
|
||||
/// The object Replace swaps as it was when Place started.
|
||||
@@ -560,10 +565,14 @@ impl Session {
|
||||
|
||||
/// Run `file.place` with the params of `read` as a command (checked and journaled as any
|
||||
/// other) that places the file `read` holds instead of reading it again → `file.place`'s
|
||||
/// reply. The object Replace swaps must still be in the document as it was when Place started;
|
||||
/// when the selection changed meanwhile, `select.set` selects that object again first, so a
|
||||
/// replay of the journal replaces the same object.
|
||||
/// reply. The document Place started in must be the active one, and the object Replace swaps
|
||||
/// must still be in it as it was when Place started; when the selection changed meanwhile,
|
||||
/// `select.set` selects that object again first, so a replay of the journal replaces the same
|
||||
/// object.
|
||||
pub fn place_read(&mut self, read: PlaceRead) -> Result<Value> {
|
||||
if self.doc()?.uid != read.job.doc {
|
||||
return Err(bad(PLACE, NOT_ACTIVE));
|
||||
}
|
||||
let params = read.job.params.clone();
|
||||
if let Some(old) = read.job.old {
|
||||
let st = self.doc()?;
|
||||
@@ -615,7 +624,7 @@ fn prepare(s: &Session, p: &Value) -> Result<PlaceJob> {
|
||||
(true, _) => return Err(bad(PLACE, "replace: select the one object to replace")),
|
||||
};
|
||||
let replaced = old.and_then(|id| st.doc.node(id)).cloned();
|
||||
Ok(PlaceJob { params: p.clone(), old, replaced, target: board_at(&st.doc, at) })
|
||||
Ok(PlaceJob { doc: st.uid, params: p.clone(), old, replaced, target: board_at(&st.doc, at) })
|
||||
}
|
||||
|
||||
/// Place the file `read` holds in the active document.
|
||||
@@ -755,6 +764,8 @@ fn queued_files(p: &Value) -> Result<Vec<Value>> {
|
||||
/// ([`Session::prepare_place_queue`]). [`QueueJob::read`] reads them without the session, on any
|
||||
/// thread.
|
||||
pub struct QueueJob {
|
||||
/// The document it was prepared in (`DocState::uid`).
|
||||
doc: u64,
|
||||
params: Value,
|
||||
files: Vec<Value>,
|
||||
}
|
||||
@@ -762,6 +773,8 @@ pub struct QueueJob {
|
||||
/// The files [`QueueJob::read`] read, which [`Session::place_queue_read`] loads the place cursor
|
||||
/// with.
|
||||
pub struct QueueRead {
|
||||
/// The document the files were read for (`DocState::uid`).
|
||||
doc: u64,
|
||||
params: Value,
|
||||
entries: Vec<Value>,
|
||||
files: Vec<Value>,
|
||||
@@ -776,13 +789,13 @@ impl QueueJob {
|
||||
|
||||
/// Read every file for its size and thumbnail, as `file.place.queue` does, without the session.
|
||||
pub fn read(self) -> Result<QueueRead> {
|
||||
read_queue(self.params, self.files)
|
||||
read_queue(self.doc, self.params, self.files)
|
||||
}
|
||||
}
|
||||
|
||||
/// Read each of `queued`, the files of `file.place.queue` with params `p`, for its size and
|
||||
/// thumbnail.
|
||||
fn read_queue(p: Value, queued: Vec<Value>) -> Result<QueueRead> {
|
||||
/// Read each of `queued`, the files of `file.place.queue` with params `p` for the document `doc`,
|
||||
/// for its size and thumbnail.
|
||||
fn read_queue(doc: u64, p: Value, queued: Vec<Value>) -> Result<QueueRead> {
|
||||
let thumbnail = p.get("thumbnail").and_then(Value::as_f64);
|
||||
let (mut entries, mut files, mut skipped) = (vec![], vec![], vec![]);
|
||||
for mut q in queued {
|
||||
@@ -823,7 +836,7 @@ fn read_queue(p: Value, queued: Vec<Value>) -> Result<QueueRead> {
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(QueueRead { params: p, entries, files, skipped })
|
||||
Ok(QueueRead { doc, params: p, entries, files, skipped })
|
||||
}
|
||||
|
||||
impl Session {
|
||||
@@ -834,12 +847,17 @@ impl Session {
|
||||
has_doc(self).map_err(|why| EngineError::Disabled(QUEUE.into(), why))?;
|
||||
check_switches(params, &["link", "template"], QUEUE)?;
|
||||
check_numbers(params, &["thumbnail"], QUEUE)?;
|
||||
Ok(QueueJob { params: params.clone(), files: queued_files(params)? })
|
||||
let files = queued_files(params)?;
|
||||
Ok(QueueJob { doc: self.doc()?.uid, params: params.clone(), files })
|
||||
}
|
||||
|
||||
/// Run `file.place.queue` with the params of `read` as a command that loads the place cursor
|
||||
/// with the files `read` holds instead of reading them again → `file.place.queue`'s reply.
|
||||
/// with the files `read` holds instead of reading them again → `file.place.queue`'s reply. The
|
||||
/// document the files were read for must be the active one.
|
||||
pub fn place_queue_read(&mut self, read: QueueRead) -> Result<Value> {
|
||||
if self.doc()?.uid != read.doc {
|
||||
return Err(bad(QUEUE, NOT_ACTIVE));
|
||||
}
|
||||
let params = read.params.clone();
|
||||
self.queue_hand_off = Some(read);
|
||||
let r = self.execute(QUEUE, ¶ms);
|
||||
|
||||
@@ -365,6 +365,95 @@ fn a_file_read_apart_from_the_session_replaces_what_was_selected_when_place_star
|
||||
}
|
||||
}
|
||||
|
||||
/// Every open document with its art, selection and undo steps, and the journal, tool and tool
|
||||
/// options: what a refused hand-off leaves as it was.
|
||||
type Snapshot = (Vec<(u64, Arc<vectorcraft_doc::Document>, Vec<NodeId>, usize)>, usize, &'static str, Value);
|
||||
|
||||
fn snapshot(s: &Session) -> Snapshot {
|
||||
let docs = s.documents().iter().map(|d| (d.uid, d.doc.clone(), d.selection.objects.clone(), d.history.undo.len())).collect();
|
||||
(docs, s.journal.len(), s.tool_id(), s.tool_options())
|
||||
}
|
||||
|
||||
/// A file read apart from the session is placed only in the document Place started in: with
|
||||
/// another document active, Replace included when that document holds the same object under the
|
||||
/// same id, or after the document closed, nothing changes in any document; with the document
|
||||
/// active again, the file is placed in it.
|
||||
#[test]
|
||||
fn a_file_read_apart_from_the_session_is_placed_only_in_the_document_it_was_read_for() {
|
||||
let blue = file("blue.png", &png(8, 8, [0, 0, 255, 255], None));
|
||||
let not_active = "the document it was prepared for is no longer active";
|
||||
for replace in [false, true] {
|
||||
let p = with(blue.clone(), json!({"replace": replace}));
|
||||
let mut s = session();
|
||||
let square = json!({"x": 10, "y": 10, "width": 20, "height": 20});
|
||||
let a = s.execute("shape.rectangle", &square).unwrap()["id"].clone();
|
||||
let read = s.prepare_place(&p).unwrap().read().unwrap();
|
||||
s.execute("file.new", &json!({"width": 400, "height": 300})).unwrap();
|
||||
let b = s.execute("shape.rectangle", &square).unwrap()["id"].clone();
|
||||
assert_eq!(a, b, "the other document holds an object with the same id");
|
||||
assert!(node(&s, &b) == s.documents()[0].doc.node(NodeId(a.as_u64().unwrap())).unwrap().clone(), "and the same content");
|
||||
let before = snapshot(&s);
|
||||
let err = s.place_read(read).unwrap_err();
|
||||
assert!(err.to_string().contains(not_active), "replace {replace}: {err}");
|
||||
assert!(snapshot(&s) == before, "replace {replace}: nothing placed, selected or journaled in either document");
|
||||
// Active again, the document Place started in takes the file.
|
||||
let read = {
|
||||
s.execute("document.activate", &json!({"index": 0})).unwrap();
|
||||
s.prepare_place(&p).unwrap().read().unwrap()
|
||||
};
|
||||
s.execute("document.activate", &json!({"index": 1})).unwrap();
|
||||
s.execute("document.activate", &json!({"index": 0})).unwrap();
|
||||
let r = s.place_read(read).unwrap();
|
||||
assert_eq!(s.active_index(), Some(0));
|
||||
assert!(s.doc().unwrap().doc.node(NodeId(r["ids"][0].as_u64().unwrap())).is_some(), "replace {replace}: placed in the first document");
|
||||
let others = s.documents()[1].doc.layers.last().unwrap().children().unwrap().len();
|
||||
assert_eq!(others, 1, "replace {replace}: the other document keeps its one object");
|
||||
}
|
||||
// The document Place started in closed: refused in the document left open, and with none left.
|
||||
let mut s = session();
|
||||
let read = s.prepare_place(&blue).unwrap().read().unwrap();
|
||||
s.execute("file.new", &json!({"width": 400, "height": 300})).unwrap();
|
||||
s.execute("file.close", &json!({"index": 0})).unwrap();
|
||||
let before = snapshot(&s);
|
||||
assert!(s.place_read(read).unwrap_err().to_string().contains(not_active));
|
||||
assert!(snapshot(&s) == before, "nothing placed in the document left open");
|
||||
let read = s.prepare_place(&blue).unwrap().read().unwrap();
|
||||
s.execute("file.close", &json!({})).unwrap();
|
||||
let journal = s.journal.len();
|
||||
assert!(s.place_read(read).is_err() && s.journal.len() == journal, "no document left: refused");
|
||||
}
|
||||
|
||||
/// Files read for the place cursor apart from the session load it only in the document they were
|
||||
/// read for: with another document active, or after that document closed, its tool and queue stay
|
||||
/// as they were; with the document active again, the cursor is loaded.
|
||||
#[test]
|
||||
fn files_read_for_the_place_cursor_apart_from_the_session_load_it_only_in_their_document() {
|
||||
let p = json!({"files": [file("a.png", &png(40, 20, [9, 9, 9, 255], None))], "link": false});
|
||||
let not_active = "the document it was prepared for is no longer active";
|
||||
let mut s = session();
|
||||
let read = s.prepare_place_queue(&p).unwrap().read().unwrap();
|
||||
s.execute("file.new", &json!({"width": 400, "height": 300})).unwrap();
|
||||
let before = snapshot(&s);
|
||||
assert!(s.place_queue_read(read).unwrap_err().to_string().contains(not_active));
|
||||
assert!(snapshot(&s) == before && s.tool_id() == "selection", "the other document's tool and queue stay");
|
||||
let read = {
|
||||
s.execute("document.activate", &json!({"index": 0})).unwrap();
|
||||
s.prepare_place_queue(&p).unwrap().read().unwrap()
|
||||
};
|
||||
s.execute("document.activate", &json!({"index": 1})).unwrap();
|
||||
s.execute("document.activate", &json!({"index": 0})).unwrap();
|
||||
assert_eq!(s.place_queue_read(read).unwrap()["count"], 1);
|
||||
assert_eq!(s.tool_id(), "place");
|
||||
// The document they were read for closed.
|
||||
let mut s = session();
|
||||
let read = s.prepare_place_queue(&p).unwrap().read().unwrap();
|
||||
s.execute("file.new", &json!({"width": 400, "height": 300})).unwrap();
|
||||
s.execute("file.close", &json!({"index": 0})).unwrap();
|
||||
let before = snapshot(&s);
|
||||
assert!(s.place_queue_read(read).unwrap_err().to_string().contains(not_active));
|
||||
assert!(snapshot(&s) == before, "the document left open keeps its tool");
|
||||
}
|
||||
|
||||
/// A linked image keeps the preview its file was read with ([`cmd::place::PlaceJob::read`] makes
|
||||
/// it), so placing the read file does not decode the image again; an embedded image has none.
|
||||
#[test]
|
||||
|
||||
@@ -4514,6 +4514,7 @@ axis Both И двете
|
||||
@msg paths contain invalid coordinates пътищата съдържат невалидни координати
|
||||
@msg paths: give at least one file пътища: посочете поне един файл
|
||||
@msg replace: the object to replace was changed or deleted замяна: обектът за замяна е променен или изтрит
|
||||
@msg the document it was prepared for is no longer active документът, за който е подготвено, вече не е активен
|
||||
@msg pattern missing липсва мостра
|
||||
@msg patterns nested too deeply are filled with mid-grey мострите, вложени прекалено дълбоко, се запълват със средно сиво
|
||||
@msg percent must be above 0 and at most 6400, not {p} percent трябва да е над 0 и най-много 6400, а не {p}
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -4909,6 +4909,7 @@ imageTrace Outline Obris
|
||||
@msg paths contain invalid coordinates putanje sadrže nevažeće koordinate
|
||||
@msg paths: give at least one file paths: navedite barem jednu datoteku
|
||||
@msg replace: the object to replace was changed or deleted replace: objekat za zamjenu je promijenjen ili izbrisan
|
||||
@msg the document it was prepared for is no longer active dokument za koji je pripremljeno više nije aktivan
|
||||
@msg pattern missing uzorak nedostaje
|
||||
@msg patterns nested too deeply are filled with mid-grey previše duboko ugniježđeni uzorci ispunjavaju se srednje sivom
|
||||
@msg percent must be above 0 and at most 6400, not {p} percent mora biti iznad 0 i najviše 6400, a ne {p}
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -5967,6 +5967,7 @@ digits Malayalam Malaiàlam
|
||||
@msg Reload the page to go on (changes not saved yet may be lost). Recarrega la pàgina per continuar (els canvis encara no desats es poden perdre).
|
||||
@msg Replace Spine: select a blend and a path Substitueix l’espina: selecciona una fusió i un traçat
|
||||
@msg replace: the object to replace was changed or deleted replace: l’objecte que s’havia de substituir s’ha canviat o suprimit
|
||||
@msg the document it was prepared for is no longer active el document per al qual es va preparar ja no està actiu
|
||||
@msg Reset {_1} Restableix {_1}
|
||||
@msg resolutions must be between 1 and 2400 ppi les resolucions han de ser entre 1 i 2400 ppi
|
||||
@msgplural Restored {n} recovered document: save it to keep it|Restored {n} recovered documents: save them to keep them S’ha restaurat {n} document recuperat: desa’l per conservar-lo|S’han restaurat {n} documents recuperats: desa’ls per conservar-los
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -5076,6 +5076,7 @@ imageTrace Outline Obrys
|
||||
@msg paths contain invalid coordinates cesty obsahují neplatné souřadnice
|
||||
@msg paths: give at least one file paths: zadejte alespoň jeden soubor
|
||||
@msg replace: the object to replace was changed or deleted replace: objekt k nahrazení byl změněn nebo odstraněn
|
||||
@msg the document it was prepared for is no longer active dokument, pro který bylo připraveno, už není aktivní
|
||||
@msg pattern missing chybí vzorek
|
||||
@msg patterns nested too deeply are filled with mid-grey příliš hluboko vnořené vzorky se vyplní středně šedou
|
||||
@msg percent must be above 0 and at most 6400, not {p} percent musí být větší než 0 a nejvýše 6400, ne {p}
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -4614,6 +4614,7 @@ imageTrace Outline Kontur
|
||||
@msg paths contain invalid coordinates stierne indeholder ugyldige koordinater
|
||||
@msg paths: give at least one file stier: angiv mindst én fil
|
||||
@msg replace: the object to replace was changed or deleted erstat: objektet, der skulle erstattes, er ændret eller slettet
|
||||
@msg the document it was prepared for is no longer active dokumentet, det blev forberedt til, er ikke længere aktivt
|
||||
@msg pattern missing mønster mangler
|
||||
@msg patterns nested too deeply are filled with mid-grey mønstre, der er indlejret for dybt, udfyldes med mellemgrå
|
||||
@msg percent must be above 0 and at most 6400, not {p} percent skal være over 0 og højst 6400, ikke {p}
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -4692,6 +4692,7 @@ theme Appearance Erscheinungsbild
|
||||
@msg paths contain invalid coordinates die Pfade enthalten ungültige Koordinaten
|
||||
@msg paths: give at least one file paths: Geben Sie mindestens eine Datei an
|
||||
@msg replace: the object to replace was changed or deleted replace: Das zu ersetzende Objekt wurde geändert oder gelöscht
|
||||
@msg the document it was prepared for is no longer active das Dokument, für das es vorbereitet wurde, ist nicht mehr aktiv
|
||||
@msg pattern missing das Muster fehlt
|
||||
@msg patterns nested too deeply are filled with mid-grey zu tief verschachtelte Muster werden mit mittlerem Grau gefüllt
|
||||
@msg percent must be above 0 and at most 6400, not {p} percent muss über 0 und höchstens 6400 sein, nicht {p}
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -4722,6 +4722,7 @@ digits Malayalam Μαλαγιάλαμ
|
||||
@msg paths contain invalid coordinates οι διαδρομές περιέχουν μη έγκυρες συντεταγμένες
|
||||
@msg paths: give at least one file διαδρομές: δώστε τουλάχιστον ένα αρχείο
|
||||
@msg replace: the object to replace was changed or deleted αντικατάσταση: το αντικείμενο προς αντικατάσταση άλλαξε ή διαγράφηκε
|
||||
@msg the document it was prepared for is no longer active το έγγραφο για το οποίο προετοιμάστηκε δεν είναι πλέον ενεργό
|
||||
@msg pattern missing λείπει το μοτίβο
|
||||
@msg patterns nested too deeply are filled with mid-grey τα πολύ βαθιά ένθετα μοτίβα γεμίζονται με μέτριο γκρι
|
||||
@msg percent must be above 0 and at most 6400, not {p} το percent πρέπει να είναι μεγαλύτερο από 0 και έως 6400, όχι {p}
|
||||
|
||||
|
Can't render this file because it is too large.
|
@@ -4768,6 +4768,7 @@ axis Both Ambos
|
||||
@msg paths contain invalid coordinates los trazados contienen coordenadas no válidas
|
||||
@msg paths: give at least one file paths: indica al menos un archivo
|
||||
@msg replace: the object to replace was changed or deleted replace: se modificó o eliminó el objeto que se iba a reemplazar
|
||||
@msg the document it was prepared for is no longer active el documento para el que se preparó ya no está activo
|
||||
@msg pattern missing falta el motivo
|
||||
@msg patterns nested too deeply are filled with mid-grey los motivos anidados a demasiada profundidad se rellenan de gris medio
|
||||
@msg percent must be above 0 and at most 6400, not {p} percent debe ser mayor que 0 y como máximo 6400, no {p}
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -4982,6 +4982,7 @@ imageTrace Outline Ääriviiva
|
||||
@msg paths contain invalid coordinates polut sisältävät virheellisiä koordinaatteja
|
||||
@msg paths: give at least one file paths: anna vähintään yksi tiedosto
|
||||
@msg replace: the object to replace was changed or deleted replace: korvattavaa objektia on muutettu tai se on poistettu
|
||||
@msg the document it was prepared for is no longer active asiakirja, jota varten se valmisteltiin, ei ole enää aktiivinen
|
||||
@msg pattern missing kuvio puuttuu
|
||||
@msg patterns nested too deeply are filled with mid-grey liian syvälle sisäkkäiset kuviot täytetään keskiharmaalla
|
||||
@msg percent must be above 0 and at most 6400, not {p} percent-arvon on oltava yli 0 ja enintään 6400, ei {p}
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -4757,6 +4757,7 @@ axis Both Les deux
|
||||
@msg paths contain invalid coordinates les tracés contiennent des coordonnées non valides
|
||||
@msg paths: give at least one file paths : indiquez au moins un fichier
|
||||
@msg replace: the object to replace was changed or deleted replace : l’objet à remplacer a été modifié ou supprimé
|
||||
@msg the document it was prepared for is no longer active le document pour lequel il a été préparé n’est plus actif
|
||||
@msg pattern missing motif manquant
|
||||
@msg patterns nested too deeply are filled with mid-grey les motifs imbriqués trop profondément sont remplis de gris moyen
|
||||
@msg percent must be above 0 and at most 6400, not {p} percent doit être supérieur à 0 et au plus égal à 6400, pas {p}
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -7676,6 +7676,7 @@ antiAlias Sharp शार्प
|
||||
@msg Replace Spine: select a blend and a path Spine: एक मिश्रण और एक पाथ चुनें
|
||||
@msg replace: select the one object to replace प्रतिस्थापित करने के लिए एक ऑब्जेक्ट सिलेक्ट करें
|
||||
@msg replace: the object to replace was changed or deleted प्रतिस्थापित करने के लिए ऑब्जेक्ट को बदल दिया गया था या हटा दिया गया
|
||||
@msg the document it was prepared for is no longer active जिस डॉक्यूमेंट के लिए इसे तैयार किया गया था, वह अब सक्रिय नहीं है
|
||||
@msg Reset {_1} रीसेट करें {_1}
|
||||
@msg resolution must be a number or screen|medium|high resolution: रिज़ॉल्यूशन एक नंबर या स्क्रीन होना चाहिए
|
||||
@msg resolution must be between 1 and 2400 ppi resolution: रिज़ॉल्यूशन 1 और 2400 ppi के बीच होना चाहिए
|
||||
|
||||
|
Can't render this file because it is too large.
|
@@ -5478,6 +5478,7 @@ imageTrace Outline Körvonal
|
||||
@msg paths contain invalid coordinates az útvonalakban érvénytelen koordináták vannak
|
||||
@msg paths: give at least one file paths: legalább egy fájlt adj meg
|
||||
@msg replace: the object to replace was changed or deleted replace: a cserélendő objektumot módosították vagy törölték
|
||||
@msg the document it was prepared for is no longer active az a dokumentum, amelyhez előkészítették, már nem aktív
|
||||
@msg pattern missing hiányzik a mintázat
|
||||
@msg patterns nested too deeply are filled with mid-grey a túl mélyen egymásba ágyazott mintázatok helyén középszürke kitöltés áll
|
||||
@msg PDF settings are not an object a PDF-beállítások nem objektumot alkotnak
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -4614,6 +4614,7 @@ imageTrace Outline Kontur
|
||||
@msg paths contain invalid coordinates jalur berisi koordinat yang tidak valid
|
||||
@msg paths: give at least one file jalur: berikan setidaknya satu berkas
|
||||
@msg replace: the object to replace was changed or deleted ganti: objek yang akan diganti telah diubah atau dihapus
|
||||
@msg the document it was prepared for is no longer active dokumen yang menjadi tujuan persiapannya tidak lagi aktif
|
||||
@msg pattern missing pola hilang
|
||||
@msg patterns nested too deeply are filled with mid-grey pola yang bersarang terlalu dalam diisi dengan abu-abu tengah
|
||||
@msg percent must be above 0 and at most 6400, not {p} percent harus di atas 0 dan paling banyak 6400, bukan {p}
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2422 and column 5.
|
@@ -4820,6 +4820,7 @@ axis Both Entrambi
|
||||
@msg paths contain invalid coordinates i tracciati contengono coordinate non valide
|
||||
@msg paths: give at least one file paths: specifica almeno un file
|
||||
@msg replace: the object to replace was changed or deleted replace: l’oggetto da sostituire è stato modificato o eliminato
|
||||
@msg the document it was prepared for is no longer active il documento per cui è stato preparato non è più attivo
|
||||
@msg pattern missing motivo mancante
|
||||
@msg patterns nested too deeply are filled with mid-grey i motivi annidati troppo in profondità vengono riempiti di grigio medio
|
||||
@msg percent must be above 0 and at most 6400, not {p} percent deve essere maggiore di 0 e al massimo 6400, non {p}
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -5183,6 +5183,7 @@ swatch Bright Violet ビビッドバイオレット
|
||||
@msg `{file}` isn't a VectorCraft document, a PDF or a PDF-compatible .ai file `{file}` は VectorCraft ドキュメント、PDF、PDF 互換の .ai ファイルのいずれでもありません
|
||||
@msg paths: give at least one file paths: ファイルを 1 つ以上指定してください
|
||||
@msg replace: the object to replace was changed or deleted replace: 置き換えるオブジェクトは変更または削除されています
|
||||
@msg the document it was prepared for is no longer active 準備したときのドキュメントがもうアクティブではありません
|
||||
@msg Couldn't place {name}: {e} {name} を配置できませんでした: {e}
|
||||
@msg no print service プリントサービスがありません
|
||||
@msg the print job has no data プリントジョブにデータがありません
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -4443,6 +4443,7 @@ font-technology Variable ცვლადი
|
||||
@msg paths contain invalid coordinates ტრაექტორიებში არასწორი კოორდინატებია
|
||||
@msg paths: give at least one file paths: მიუთითეთ ერთი ფაილი მაინც
|
||||
@msg replace: the object to replace was changed or deleted replace: ჩასანაცვლებელი ობიექტი შეიცვალა ან წაიშალა
|
||||
@msg the document it was prepared for is no longer active დოკუმენტი, რომლისთვისაც მომზადდა, აღარ არის აქტიური
|
||||
@msg pattern missing პატერნი აკლია
|
||||
@msg patterns nested too deeply are filled with mid-grey ზედმეტად ღრმად ჩადგმული პატერნები საშუალო ნაცრისფრით ივსება
|
||||
@msg percent must be above 0 and at most 6400, not {p} percent უნდა იყოს 0-ზე მეტი და არაუმეტეს 6400-ისა და არა {p}
|
||||
|
||||
|
Can't render this file because it is too large.
|
@@ -5110,6 +5110,7 @@ theme Appearance 외관
|
||||
@msg `{file}` isn't a VectorCraft document, a PDF or a PDF-compatible .ai file `{file}`은(는) VectorCraft 문서, PDF 또는 PDF 호환 .ai 파일이 아닙니다
|
||||
@msg paths: give at least one file paths: 파일을 하나 이상 지정하세요
|
||||
@msg replace: the object to replace was changed or deleted replace: 바꿀 개체가 변경되었거나 삭제되었습니다
|
||||
@msg the document it was prepared for is no longer active 준비한 문서가 더 이상 활성 상태가 아닙니다
|
||||
@msg Couldn't place {name}: {e} {name}을(를) 가져올 수 없습니다: {e}
|
||||
@msg no print service 인쇄 서비스가 없습니다
|
||||
@msg the print job has no data 인쇄 작업에 데이터가 없습니다
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -5128,6 +5128,7 @@ imageTrace Outline Contour
|
||||
@msg paths contain invalid coordinates paden bevatten ongeldige coördinaten
|
||||
@msg paths: give at least one file paden: geef minstens één bestand
|
||||
@msg replace: the object to replace was changed or deleted vervangen: het te vervangen object is gewijzigd of verwijderd
|
||||
@msg the document it was prepared for is no longer active het document waarvoor het is voorbereid, is niet langer actief
|
||||
@msg pattern missing patroon ontbreekt
|
||||
@msg patterns nested too deeply are filled with mid-grey patronen die te diep genest zijn, worden gevuld met middelgrijs
|
||||
@msg percent must be above 0 and at most 6400, not {p} percent moet boven 0 en maximaal 6400 zijn, niet {p}
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -4902,6 +4902,7 @@ imageTrace Outline Kontur
|
||||
@msg paths contain invalid coordinates ścieżki zawierają nieprawidłowe współrzędne
|
||||
@msg paths: give at least one file paths: podaj co najmniej jeden plik
|
||||
@msg replace: the object to replace was changed or deleted replace: obiekt do zastąpienia został zmieniony lub usunięty
|
||||
@msg the document it was prepared for is no longer active dokument, dla którego to przygotowano, nie jest już aktywny
|
||||
@msg pattern missing brak wzorka
|
||||
@msg patterns nested too deeply are filled with mid-grey zbyt głęboko zagnieżdżone wzorki są wypełniane średnią szarością
|
||||
@msg percent must be above 0 and at most 6400, not {p} percent musi być większy od 0 i nie większy niż 6400, nie {p}
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -4224,6 +4224,7 @@ axis Both Ambos
|
||||
@msg paths contain invalid coordinates os traçados contêm coordenadas inválidas
|
||||
@msg paths: give at least one file paths: informe pelo menos um arquivo
|
||||
@msg replace: the object to replace was changed or deleted replace: o objeto a ser substituído foi alterado ou excluído
|
||||
@msg the document it was prepared for is no longer active o documento para o qual foi preparado não está mais ativo
|
||||
@msg pattern missing padrão ausente
|
||||
@msg patterns nested too deeply are filled with mid-grey padrões aninhados com profundidade excessiva são preenchidos com cinza médio
|
||||
@msg percent must be above 0 and at most 6400, not {p} percent deve ser maior que 0 e no máximo 6400, não {p}
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 6 and column 47.
|
@@ -4805,6 +4805,7 @@ axis Both Оба
|
||||
@msg paths contain invalid coordinates контуры содержат недопустимые координаты
|
||||
@msg paths: give at least one file paths: укажите как минимум один файл
|
||||
@msg replace: the object to replace was changed or deleted replace: заменяемый объект был изменён или удалён
|
||||
@msg the document it was prepared for is no longer active документ, для которого это было подготовлено, больше не активен
|
||||
@msg pattern missing узор отсутствует
|
||||
@msg patterns nested too deeply are filled with mid-grey слишком глубоко вложенные узоры заполняются серым
|
||||
@msg percent must be above 0 and at most 6400, not {p} percent должен быть больше 0 и не более 6400, а не {p}
|
||||
|
||||
|
Can't render this file because it is too large.
|
@@ -4669,6 +4669,7 @@ axis Both Båda
|
||||
@msg paths contain invalid coordinates banorna innehåller ogiltiga koordinater
|
||||
@msg paths: give at least one file paths: ange minst en fil
|
||||
@msg replace: the object to replace was changed or deleted replace: objektet som skulle ersättas har ändrats eller tagits bort
|
||||
@msg the document it was prepared for is no longer active dokumentet som det förbereddes för är inte längre aktivt
|
||||
@msg pattern missing mönster saknas
|
||||
@msg patterns nested too deeply are filled with mid-grey mönster som är kapslade för djupt fylls med mellangrått
|
||||
@msg percent must be above 0 and at most 6400, not {p} percent måste vara över 0 och högst 6400, inte {p}
|
||||
|
||||
|
Can't render this file because it is too large.
|
@@ -4522,6 +4522,7 @@ axis Both Her İkisi
|
||||
@msg paths contain invalid coordinates yollar geçersiz koordinatlar içeriyor
|
||||
@msg paths: give at least one file yollar: en az bir dosya verin
|
||||
@msg replace: the object to replace was changed or deleted değiştir: değiştirilecek nesne değiştirildi veya silindi
|
||||
@msg the document it was prepared for is no longer active hazırlandığı belge artık etkin değil
|
||||
@msg pattern missing desen eksik
|
||||
@msg patterns nested too deeply are filled with mid-grey çok derin iç içe geçmiş desenler orta gri renkle dolu
|
||||
@msg percent must be above 0 and at most 6400, not {p} percent 0'ın üzerinde ve en fazla 6400 olmalıdır, {p} değil
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 5 and column 25.
|
@@ -4804,6 +4804,7 @@ axis Both Обидві
|
||||
@msg paths contain invalid coordinates контури містять неприпустимі координати
|
||||
@msg paths: give at least one file paths: вкажіть щонайменше один файл
|
||||
@msg replace: the object to replace was changed or deleted replace: об’єкт для заміни було змінено або видалено
|
||||
@msg the document it was prepared for is no longer active документ, для якого це було підготовлено, більше не активний
|
||||
@msg pattern missing візерунок відсутній
|
||||
@msg patterns nested too deeply are filled with mid-grey надто глибоко вкладені візерунки заповнюються сірим
|
||||
@msg percent must be above 0 and at most 6400, not {p} percent має бути більше 0 і не більше 6400, а не {p}
|
||||
|
||||
|
Can't render this file because it is too large.
|
@@ -5142,6 +5142,7 @@ theme Appearance Giao diện
|
||||
@msg paths contain invalid coordinates đường dẫn chứa tọa độ không hợp lệ
|
||||
@msg paths: give at least one file đường dẫn: hãy cung cấp ít nhất một tệp
|
||||
@msg replace: the object to replace was changed or deleted thay thế: đối tượng cần thay thế đã bị thay đổi hoặc xóa
|
||||
@msg the document it was prepared for is no longer active tài liệu được chuẩn bị không còn hoạt động
|
||||
@msg pattern missing thiếu họa tiết
|
||||
@msg patterns nested too deeply are filled with mid-grey họa tiết lồng nhau quá sâu được tô bằng màu xám trung tính
|
||||
@msg PDF settings are not an object Cài đặt PDF không phải là đối tượng
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 204 and column 5.
|
@@ -4866,6 +4866,7 @@ imageTrace Outline 轮廓
|
||||
@msg `{file}` isn't a VectorCraft document, a PDF or a PDF-compatible .ai file `{file}` 不是 VectorCraft 文档、PDF 或 PDF 兼容的 .ai 文件
|
||||
@msg paths: give at least one file paths:请至少给出一个文件
|
||||
@msg replace: the object to replace was changed or deleted replace:要替换的对象已被更改或删除
|
||||
@msg the document it was prepared for is no longer active 为其准备的文档已不再处于活动状态
|
||||
@msg Couldn't place {name}: {e} 无法置入 {name}:{e}
|
||||
@msg no print service 没有打印服务
|
||||
@msg the print job has no data 打印作业没有数据
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -2615,6 +2615,7 @@ file-filter Templates 範本
|
||||
@msg `{file}` isn't a VectorCraft document, a PDF or a PDF-compatible .ai file `{file}` 不是 VectorCraft 文件、PDF 或 PDF 相容的 .ai 檔案
|
||||
@msg paths: give at least one file paths:請提供至少一個檔案
|
||||
@msg replace: the object to replace was changed or deleted replace:要取代的物件已被變更或刪除
|
||||
@msg the document it was prepared for is no longer active 為其準備的文件已不再處於使用中
|
||||
@msg Couldn't place {name}: {e} 無法置入 {name}:{e}
|
||||
@msg no print service 沒有列印服務
|
||||
@msg the print job has no data 列印工作沒有資料
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 6 and column 47.
|
@@ -1672,6 +1672,7 @@ Moved from the ROADMAP's "Shipped so far" on 2026-10-10. Update it when a featur
|
||||
- File › Place reads Word 97-2003 `.doc` documents as area type with the same formatting, read from the main text's pieces, the style sheet's paragraph and character styles and direct formatting. Table rows are paragraphs with their cells separated by tabs and fields place as their results; fields without a result, hidden and deleted text, pictures, headers, footers, notes, comments and text boxes are left out, and `warnings` names each kind left out or changed. Encrypted documents, documents last saved with fast save and Word 6.0 and Word 95 documents are refused (`file.place`, `crates/engine/src/tests/textimport.rs`).
|
||||
- Placing a Word 97-2003 `.doc` document works out each style's formatting once and each property run's once, and refuses property pages that are out of order, listed twice or overlap, a style sheet that holds fewer styles than it counts, styles based on each other in a loop, and more than 100,000 runs of character or of paragraph properties, 16 MiB of properties or 100,000 paragraphs, hidden ones included (`file.place`, `crates/engine/src/tests/textimport.rs`).
|
||||
- On the desktop, File › Place reads and decodes files off the UI thread, one at a time, and places each once it is read, with "Placing" in the status bar and the busy spinner until then: the Place dialog's OK, a file dropped on the canvas, a click or drag of the place cursor, and the OK of the PDF, DXF and text import options. The files and thumbnails the place cursor is loaded with are read the same way, and the Place dialog's lines about its files are read on a thread of their own. Files are placed in the order they were started; a file is not placed while a dialog is open or a drag is under way, and a file whose document was closed meanwhile is not placed. `file.place` and `file.place.queue` over MCP and scripts reply as before.
|
||||
- A file read for `file.place`, or files read for the place cursor, apart from the session (`Session::place_read`, `Session::place_queue_read`) go only into the document they were read for: while another document is active, or once that document is closed, they are refused with "the document it was prepared for is no longer active" and no document, selection, tool or undo step changes (`crates/engine/src/tests/place.rs`).
|
||||
- On the desktop, Paste from a menu or shortcut captures another app's bitmap or reads a copied image file on the UI thread, then decodes the image on the file-reading worker. The status bar shows "Pasting" until the image is pasted. Windows device-independent bitmaps and Linux clipboard images are encoded as PNG on that worker. A Copy or Cut made while the image is read keeps its internal clipboard. `edit.paste*` over MCP and scripts reads the bitmap at once.
|
||||
- The pixels of a PNG, JPEG, GIF or WebP file that Place decodes to check them are kept in the image store the renderers share, so the canvas's first frame with the placed image draws them without decoding the file again on the UI thread: File › Place, a file dropped on the canvas, a click or drag of the place cursor, `file.place`, and Paste of such an image. A CMYK JPEG is still decoded when it is first drawn (`crates/ui-egui/src/placing.rs`, `crates/render/src/tests.rs`).
|
||||
- A photo whose EXIF orientation turns or flips it (a camera held upright or upside down) is placed and opened upright, as it was taken; the image is stored as it is seen (#4284). A quarter turn swaps the resolution's axes, so the image keeps its physical size. TIFFs read without the image decoder (grayscale with extra channels, CCITT Group 3, CMYK with one plane per ink) follow their Orientation tag too, and a turned CMYK JPEG or TIFF keeps its inks, at the 8 or 16 bits the file has, as a CMYK TIFF.
|
||||
|
||||
Reference in New Issue
Block a user