From 7f0e6bd19711efad84685ae5177b59c46c541c13 Mon Sep 17 00:00:00 2001 From: u8array Date: Sat, 3 Oct 2026 10:33:36 +0200 Subject: [PATCH] feat(delivery): the delivery select links to the stored objects tab for every named graphic and font --- packages/core/src/lib/storedObjects.test.ts | 42 +++++++++++++++++++ packages/core/src/lib/storedObjects.ts | 29 +++++++++++++ src/components/Fonts/FontManager.test.tsx | 14 +++++++ src/components/Fonts/FontManager.tsx | 6 +++ .../PrinterSettings/StoredFontsTab.tsx | 3 +- .../PrinterSettings/StoredGraphicsTab.tsx | 13 ++---- src/components/Properties/DeliverySelect.tsx | 11 +++-- .../Properties/TemplateSection.test.tsx | 2 +- src/components/Properties/TemplateSection.tsx | 2 +- src/locales/ar.ts | 2 +- src/locales/bg.ts | 2 +- src/locales/cs.ts | 2 +- src/locales/da.ts | 2 +- src/locales/de.ts | 2 +- src/locales/el.ts | 2 +- src/locales/en.ts | 2 +- src/locales/es.ts | 2 +- src/locales/et.ts | 2 +- src/locales/fa.ts | 2 +- src/locales/fi.ts | 2 +- src/locales/fr.ts | 2 +- src/locales/he.ts | 2 +- src/locales/hr.ts | 2 +- src/locales/hu.ts | 2 +- src/locales/it.ts | 2 +- src/locales/ja.ts | 2 +- src/locales/ko.ts | 2 +- src/locales/lt.ts | 2 +- src/locales/lv.ts | 2 +- src/locales/nl.ts | 2 +- src/locales/no.ts | 2 +- src/locales/pl.ts | 2 +- src/locales/pt.ts | 2 +- src/locales/ro.ts | 2 +- src/locales/sk.ts | 2 +- src/locales/sl.ts | 2 +- src/locales/sr.ts | 2 +- src/locales/sv.ts | 2 +- src/locales/tr.ts | 2 +- src/locales/zh-hans.ts | 2 +- src/locales/zh-hant.ts | 2 +- src/registry/image.panel.test.tsx | 20 +++++++-- src/registry/image.panel.tsx | 4 +- 43 files changed, 154 insertions(+), 56 deletions(-) create mode 100644 packages/core/src/lib/storedObjects.test.ts create mode 100644 packages/core/src/lib/storedObjects.ts diff --git a/packages/core/src/lib/storedObjects.test.ts b/packages/core/src/lib/storedObjects.test.ts new file mode 100644 index 00000000..aa5b2e73 --- /dev/null +++ b/packages/core/src/lib/storedObjects.test.ts @@ -0,0 +1,42 @@ +import { describe, it, expect, afterEach } from "vitest"; +import { listsStoredFont, listsStoredGraphic, storedGraphicRows } from "./storedObjects"; +import { putImage, removeImage } from "./imageCache"; +import type { Page } from "../types/Group"; +import type { ImageProps } from "../registry/image"; + +const GFA = "^GFA,4,4,1,00FFFF00"; +const graphic = (id: string, props: Partial, extra: Record = {}) => + ({ id, type: "image", x: 0, y: 0, rotation: 0, props: { imageId: "", widthDots: 8, threshold: 128, ...props }, ...extra }) as Page["objects"][number]; +const recall = (ext?: string): ImageProps => ({ imageId: "", widthDots: 8, threshold: 128, _gfaCache: GFA, storedAs: { device: "R", name: "LOGO", embedInZpl: false, ...(ext ? { ext, recall: "IM" as const } : {}) } }); + +afterEach(() => removeImage("cat")); + +describe("the stored graphics tab's rows", () => { + it("lists an exportable graphic under its printer path and skips one kept out of the export", () => { + const pages: Page[] = [{ objects: [graphic("a", recall()), graphic("b", { ...recall(), storedAs: { device: "R", name: "OTHER" } }, { includeInExport: false })] }]; + const rows = storedGraphicRows(pages); + expect([...rows.keys()]).toEqual(["R:LOGO.GRF"]); + expect(listsStoredGraphic(rows, recall())).toBe(true); + expect(listsStoredGraphic(rows, { ...recall(), storedAs: { device: "R", name: "OTHER" } })).toBe(false); + }); + + it("lists no recall of a file no upload writes", () => { + const rows = storedGraphicRows([{ objects: [graphic("a", recall("PNG"))] }]); + expect(rows.size).toBe(0); + expect(listsStoredGraphic(rows, recall("PNG"))).toBe(false); + }); + + it("lists a cached image without a printer name", () => { + putImage({ id: "cat", name: "cat.png", dataUrl: "data:image/png;base64,", width: 1, height: 1 }); + expect(listsStoredGraphic(new Map(), { imageId: "cat", widthDots: 8, threshold: 128 })).toBe(true); + expect(listsStoredGraphic(new Map(), { imageId: "gone", widthDots: 8, threshold: 128 })).toBe(false); + }); +}); + +describe("the stored fonts tab's rows", () => { + it("lists a TrueType name and a profile entry, not a bare printer name", () => { + expect(listsStoredFont("E:ARIAL.TTF", undefined)).toBe(true); + expect(listsStoredFont("R:MYFONT", undefined)).toBe(false); + expect(listsStoredFont("R:MYFONT", [{ path: "R:MYFONT" }])).toBe(true); + }); +}); diff --git a/packages/core/src/lib/storedObjects.ts b/packages/core/src/lib/storedObjects.ts new file mode 100644 index 00000000..a34521f2 --- /dev/null +++ b/packages/core/src/lib/storedObjects.ts @@ -0,0 +1,29 @@ +// One rule for the stored objects tabs and the links that open them, so a link always lands on a row. +import type { Page } from "../types/Group"; +import { exportableLeaves } from "../types/Group"; +import type { SetupFont } from "../types/PrinterProfile"; +import { uploadKey, type ImageProps } from "../registry/image"; +import { getImage } from "./imageCache"; +import { isTrueTypeFileName } from "./customFonts"; +import { findSetupEntry } from "./setupEntries"; + +export function storedGraphicRows(pages: readonly Page[]): Map { + const rows = new Map(); + for (const page of pages) { + for (const leaf of exportableLeaves(page.objects)) { + const props = leaf.props as ImageProps; + const key = leaf.type === "image" ? uploadKey(props) : undefined; + if (key && !rows.has(key)) rows.set(key, props); + } + } + return rows; +} + +export function listsStoredGraphic(rows: ReadonlyMap, p: ImageProps): boolean { + const key = uploadKey(p); + return (key !== undefined && rows.has(key)) || getImage(p.imageId) !== undefined; +} + +export function listsStoredFont(path: string, setupFonts: readonly SetupFont[] | undefined): boolean { + return isTrueTypeFileName(path) || findSetupEntry(setupFonts, path) !== undefined; +} diff --git a/src/components/Fonts/FontManager.test.tsx b/src/components/Fonts/FontManager.test.tsx index ad1cc748..1cd6f522 100644 --- a/src/components/Fonts/FontManager.test.tsx +++ b/src/components/Fonts/FontManager.test.tsx @@ -208,3 +208,17 @@ describe("FontManager upload", () => { expect(getAllFonts().map((f) => f.name).sort()).toEqual(["E:ARIAL.TTF", "E:MYLOGO.TTF"]); }); }); + +describe("FontManager stored fonts hand-off", () => { + afterEach(() => act(() => useLabelStore.setState({ printerSettingsTab: null }))); + + it("links a TrueType font to the stored fonts tab and leaves a bare printer name unlinked", async () => { + await loadFontBytes(new Uint8Array([0, 1, 0, 0]), "R:MYFONT"); + const r = render(); + expect(r.queryByRole("button", { name: "Manage stored objects: R:MYFONT" })).toBeNull(); + act(() => { + fireEvent.click(r.getByRole("button", { name: "Manage stored objects: E:ARIAL.TTF" })); + }); + expect(useLabelStore.getState().printerSettingsTab).toBe("storedFonts"); + }); +}); diff --git a/src/components/Fonts/FontManager.tsx b/src/components/Fonts/FontManager.tsx index e8576d57..f4fa5e24 100644 --- a/src/components/Fonts/FontManager.tsx +++ b/src/components/Fonts/FontManager.tsx @@ -14,6 +14,7 @@ import type { LiveReason } from '@zplab/core/lib/liveUsage'; import { useT } from '../../hooks/useT'; import { useUpload } from '../../hooks/useUpload'; import { storageKey, storageRefMatchesPath } from '@zplab/core/lib/storagePath'; +import { listsStoredFont } from '@zplab/core/lib/storedObjects'; import { ZPL_DRIVE_PREFIXES, isBuiltinFontId, @@ -151,6 +152,7 @@ export function FontManager() { embedLarge={isEmbedLarge(path)} previewMissing={!getFontFamily(path)} inUse={live.get(storageKey(path))} + listed={listsStoredFont(path, setupFonts)} onAliasChange={(v) => setAliasForPath(path, v)} onDeliveryChange={(v) => deliverPath(path, v)} onRequestDelete={() => setPendingDelete(path)} @@ -240,6 +242,7 @@ interface FontEntryProps { previewMissing: boolean; /** Why the delete is off: who still names the file. */ inUse: LiveReason | undefined; + listed: boolean; onAliasChange: (next: string) => void; onDeliveryChange: (next: ResourceDelivery) => void; onRequestDelete: () => void; @@ -253,11 +256,13 @@ function FontEntry({ embedLarge, previewMissing, inUse, + listed, onAliasChange, onDeliveryChange, onRequestDelete, }: FontEntryProps) { const t = useT(); + const openObjects = useLabelStore((s) => s.setPrinterSettingsTab); // ~DY without a matching ^CW would dump bytes onto the printer that no field can reference. const jobBlocked = alias ? undefined : t.delivery.jobNeedsAlias; // Heads-up when the user picks a built-in letter (0, A-H): ^CW with @@ -319,6 +324,7 @@ function FontEntry({ value={delivery} onChange={onDeliveryChange} blocked={jobBlocked === undefined ? undefined : { job: jobBlocked }} + manage={listed ? { label: t.delivery.manageObjects, open: () => openObjects('storedFonts') } : undefined} /> {overridesBuiltin && (

diff --git a/src/components/PrinterSettings/StoredFontsTab.tsx b/src/components/PrinterSettings/StoredFontsTab.tsx index 00280585..9f54a3e7 100644 --- a/src/components/PrinterSettings/StoredFontsTab.tsx +++ b/src/components/PrinterSettings/StoredFontsTab.tsx @@ -4,6 +4,7 @@ import { Tooltip } from "../ui/Tooltip"; import { cachedFontPath, loadFontBytes } from "@zplab/core/lib/fontCache"; import { findSetupEntry, withSetupEntry, withoutSetupEntry } from "@zplab/core/lib/setupEntries"; import { isTrueTypeFileName, prepareFontUpload, printerFontFileName, type FontUploadIssue } from "@zplab/core/lib/customFonts"; +import { listsStoredFont } from "@zplab/core/lib/storedObjects"; import { storageKey, storageRefMatchesPath } from "@zplab/core/lib/storagePath"; import { useCachedFonts } from "../../hooks/useCachedFonts"; import { useUpload } from "../../hooks/useUpload"; @@ -40,7 +41,7 @@ export function StoredFontsTab() { const rows = [ ...(setupFonts ?? []).map((f) => ({ path: f.path, inProfile: true, replayed: f.download !== undefined, issue: f.download === undefined ? rowIssue(f.path, cachedKeys) : undefined })), ...cachedPaths - .filter((path) => isTrueTypeFileName(path) && !findSetupEntry(setupFonts, path)) + .filter((path) => listsStoredFont(path, setupFonts) && !findSetupEntry(setupFonts, path)) .map((path) => ({ path, inProfile: false, replayed: false, issue: undefined })), ]; diff --git a/src/components/PrinterSettings/StoredGraphicsTab.tsx b/src/components/PrinterSettings/StoredGraphicsTab.tsx index 0615026c..809348e7 100644 --- a/src/components/PrinterSettings/StoredGraphicsTab.tsx +++ b/src/components/PrinterSettings/StoredGraphicsTab.tsx @@ -10,8 +10,8 @@ import { sanitizeStorageName, setupEntryKey, uploadedGraphicPath } from "@zplab/ import { findSetupEntry, setupEntryHoldsOther, withSetupEntry, withoutSetupEntry } from "@zplab/core/lib/setupEntries"; import { buttonCls, disabledCls, zplCommandTagCls } from "../ui/formStyles"; import { useCachedImages } from "../../hooks/useCachedImages"; -import { exportableLeaves } from "@zplab/core/types/Group"; -import { canSendSetupGraphic, setupGraphicFits, setupGraphicOf, setupGraphicState, uploadKey, type ImageProps } from "@zplab/core/registry/image"; +import { canSendSetupGraphic, setupGraphicFits, setupGraphicOf, setupGraphicState, type ImageProps } from "@zplab/core/registry/image"; +import { storedGraphicRows } from "@zplab/core/lib/storedObjects"; import { removeImage } from "@zplab/core/lib/imageCache"; import { imageUsage } from "@zplab/core/lib/imageUsage"; import type { LiveReason } from "@zplab/core/lib/liveUsage"; @@ -25,14 +25,7 @@ export function StoredGraphicsTab() { const patchPrinterProfileWith = useLabelStore((s) => s.patchPrinterProfileWith); const loc = t.printerSettings.objects; - const rows = new Map(); - for (const page of pages) { - for (const leaf of exportableLeaves(page.objects)) { - const props = leaf.props as ImageProps; - const key = leaf.type === "image" ? uploadKey(props) : undefined; - if (key && !rows.has(key)) rows.set(key, props); - } - } + const rows = storedGraphicRows(pages); const profileOnly = (setupGraphics ?? []).filter((g) => !rows.has(setupEntryKey(g))); const put = (entry: SetupGraphic) => patchPrinterProfileWith((p) => ({ setupGraphics: withSetupEntry(p.setupGraphics, entry) })); diff --git a/src/components/Properties/DeliverySelect.tsx b/src/components/Properties/DeliverySelect.tsx index 1c03edc0..f7cb96d5 100644 --- a/src/components/Properties/DeliverySelect.tsx +++ b/src/components/Properties/DeliverySelect.tsx @@ -14,13 +14,12 @@ interface Props { blocked?: Partial>; /** A warning about the chosen way, shown under the hint. */ issue?: string; - /** Jumps to the printer tab that provisions the file, offered once the file is delivered at setup. */ - onOpenSetup?: { label: string; open: () => void }; + manage?: { label: string; open: () => void }; disabled?: boolean; } /** One control for every file the printer needs, so job, setup and printer cannot diverge across two widgets. */ -export function DeliverySelect({ value, onChange, resource, subject, blocked, issue, onOpenSetup, disabled }: Props) { +export function DeliverySelect({ value, onChange, resource, subject, blocked, issue, manage, disabled }: Props) { const t = useT(); const hints: Record = resource === 'format' ? { job: t.delivery.formatJobHint, setup: t.delivery.formatSetupHint, printer: t.delivery.formatPrinterHint } @@ -45,9 +44,9 @@ export function DeliverySelect({ value, onChange, resource, subject, blocked, is />

{hints[value]}

{issue &&

{issue}

} - {value === 'setup' && onOpenSetup && ( - )} diff --git a/src/components/Properties/TemplateSection.test.tsx b/src/components/Properties/TemplateSection.test.tsx index ec3546d3..53f09809 100644 --- a/src/components/Properties/TemplateSection.test.tsx +++ b/src/components/Properties/TemplateSection.test.tsx @@ -96,7 +96,7 @@ describe("TemplateSection", () => { setPages([{ objects: [], storedFormatPath: "E:JOB.ZPL", storedFormatDelivery: "setup" }]); const r = render(); act(() => { - fireEvent.click(r.getByRole("button", { name: en.template.openSetupScript })); + fireEvent.click(r.getByRole("button", { name: `${en.template.openSetupScript}: E:JOB.ZPL` })); }); expect(state().printerSettingsTab).toBe("clockTime"); }); diff --git a/src/components/Properties/TemplateSection.tsx b/src/components/Properties/TemplateSection.tsx index 08271a3b..1a7af70a 100644 --- a/src/components/Properties/TemplateSection.tsx +++ b/src/components/Properties/TemplateSection.tsx @@ -41,7 +41,7 @@ export function TemplateSection({ locked }: { locked: boolean }) { onChange={(next) => setDelivery(next === "job" ? undefined : next)} blocked={blocked === undefined ? undefined : { setup: blocked, printer: blocked }} issue={issue === "contested" && chosen !== undefined ? blocked : undefined} - onOpenSetup={{ label: t.template.openSetupScript, open: () => setPrinterSettingsTab("clockTime") }} + manage={way === "setup" ? { label: t.template.openSetupScript, open: () => setPrinterSettingsTab("clockTime") } : undefined} />
diff --git a/src/locales/ar.ts b/src/locales/ar.ts index 993d694d..13d629a6 100644 --- a/src/locales/ar.ts +++ b/src/locales/ar.ts @@ -1282,7 +1282,6 @@ const ar = { storage: 'تخزين الطابعة', storeOnPrinterHint: 'يشير إلى رسم مخزن في الطابعة عبر ^XG. يحدد التسليم ما إذا كانت البايتات تُرسل مع كل مهمة، أو مرة واحدة في نص الإعداد، أو لا تُرسل إطلاقًا.', storeInline: 'تضمين مباشر', - openObjects: 'إدارة الكائنات المخزّنة', }, symbol: { symbol: 'رمز', @@ -1734,6 +1733,7 @@ const ar = { jobNeedsAlias: 'يحتاج اسمًا مستعارًا، ليتمكن ^CW من تسمية الملف.', setupNeedsBytes: 'يحتاج بيانات الصورة لترميز الرفع.', jobNeedsBytes: 'يحتاج بيانات الصورة لإرسالها مع مهمة الطباعة.', + manageObjects: 'إدارة الكائنات المخزّنة', opaqueBytes: 'تبقى البيانات كما استُورِدت ولا يمكن تخزينها على الطابعة.', formatJobHint: 'كل مهمة طباعة تخزّن التنسيق من جديد وتطبعه بصفوف مجموعة بيانات.', formatSetupHint: 'يخزّن نص إعداد ملف الطابعة هذا التنسيق مرة واحدة. تكتفي المهام بإرسال البيانات.', diff --git a/src/locales/bg.ts b/src/locales/bg.ts index 6367aad7..82ad613c 100644 --- a/src/locales/bg.ts +++ b/src/locales/bg.ts @@ -1282,7 +1282,6 @@ const bg = { storage: 'Памет на принтера', storeOnPrinterHint: 'Реферира графика, съхранена в принтера, чрез ^XG. Доставката определя дали байтовете се изпращат с всяко задание, веднъж в скрипта за настройка, или изобщо не се изпращат.', storeInline: 'Вграждане', - openObjects: 'Управление на съхранените обекти', }, symbol: { symbol: 'Символ', @@ -1734,6 +1733,7 @@ const bg = { jobNeedsAlias: 'Изисква псевдоним, за да може ^CW да именува файла.', setupNeedsBytes: 'Изисква данните на изображението, за да кодира качването.', jobNeedsBytes: 'Изисква данните на изображението, за да бъдат изпратени със заданието за печат.', + manageObjects: 'Управление на съхранените обекти', opaqueBytes: 'Данните остават както са импортирани и не могат да се съхранят на принтера.', formatJobHint: 'Всяко задание за печат съхранява формата отново и го отпечатва с редовете на набор от данни.', formatSetupHint: 'Скриптът за настройка на този принтерен профил съхранява формата веднъж. Заданията изпращат само данните.', diff --git a/src/locales/cs.ts b/src/locales/cs.ts index ee11796d..73fea2c1 100644 --- a/src/locales/cs.ts +++ b/src/locales/cs.ts @@ -1282,7 +1282,6 @@ const cs = { storage: 'Úložiště tiskárny', storeOnPrinterHint: 'Odkazuje na grafiku uloženou v tiskárně pomocí ^XG. Doručení určuje, zda se bajty odešlou s každou úlohou, jednou v instalačním skriptu, nebo vůbec.', storeInline: 'Vložit přímo', - openObjects: 'Spravovat uložené objekty', }, symbol: { symbol: 'Symbol', @@ -1734,6 +1733,7 @@ const cs = { jobNeedsAlias: 'Vyžaduje alias, aby ^CW mohl soubor pojmenovat.', setupNeedsBytes: 'Vyžaduje obrazová data ke kódování nahrávání.', jobNeedsBytes: 'Vyžaduje obrazová data pro odeslání s tiskovou úlohou.', + manageObjects: 'Spravovat uložené objekty', opaqueBytes: 'Data zůstávají tak, jak byla importována, a nelze je uložit do tiskárny.', formatJobHint: 'Každá tisková úloha znovu uloží formát a vytiskne ho s řádky datové sady.', formatSetupHint: 'Instalační skript tohoto profilu tiskárny uloží formát jednou. Úlohy odesílají jen data.', diff --git a/src/locales/da.ts b/src/locales/da.ts index 7d10a6cf..f27d0d63 100644 --- a/src/locales/da.ts +++ b/src/locales/da.ts @@ -1282,7 +1282,6 @@ const da = { storage: 'Printer-lager', storeOnPrinterHint: 'Refererer en grafik gemt på printeren via ^XG. Leveringen afgør, om bytene sendes med hvert job, én gang i opsætningsscriptet, eller slet ikke.', storeInline: 'Indlejr direkte', - openObjects: 'Administrer gemte objekter', }, symbol: { symbol: 'Symbol', @@ -1734,6 +1733,7 @@ const da = { jobNeedsAlias: 'Kræver et alias, så en ^CW kan navngive filen.', setupNeedsBytes: 'Kræver billeddataene for at kode uploadet.', jobNeedsBytes: 'Kræver billeddataene for at sende dem med printjobbet.', + manageObjects: 'Administrer gemte objekter', opaqueBytes: 'Dataene forbliver som importeret og kan ikke lagres på printeren.', formatJobHint: 'Hvert printjob gemmer formatet igen og udskriver det med rækkerne fra et datasæt.', formatSetupHint: 'Opsætningsscriptet til denne printerprofil gemmer formatet én gang. Job sender kun dataene.', diff --git a/src/locales/de.ts b/src/locales/de.ts index b1000740..04fa7d52 100644 --- a/src/locales/de.ts +++ b/src/locales/de.ts @@ -1319,7 +1319,6 @@ const de = { storage: 'Drucker-Speicher', storeOnPrinterHint: 'Referenziert eine Grafik auf der Drucker-Storage via ^XG. Die Bereitstellung entscheidet, ob die Bytes mit jedem Job, einmalig im Setup-Skript oder gar nicht mitgesendet werden.', storeInline: 'Inline einbetten', - openObjects: 'Gespeicherte Objekte verwalten', }, symbol: { symbol: 'Symbol', @@ -1771,6 +1770,7 @@ const de = { jobNeedsAlias: 'Braucht einen Alias, damit ein ^CW die Datei benennen kann.', setupNeedsBytes: 'Braucht die Bilddaten, um den Upload zu kodieren.', jobNeedsBytes: 'Braucht Bilddaten, die mit dem Auftrag gesendet werden.', + manageObjects: 'Gespeicherte Objekte verwalten', opaqueBytes: 'Die Bytes bleiben wie importiert und lassen sich nicht auf dem Drucker ablegen.', formatJobHint: 'Jeder Druckjob speichert das Format erneut und druckt es mit den Zeilen eines Datensatzes.', formatSetupHint: 'Das Setup-Skript dieses Druckerprofils speichert das Format einmalig. Jobs senden nur die Daten.', diff --git a/src/locales/el.ts b/src/locales/el.ts index c9d95f8a..6ebfb1ed 100644 --- a/src/locales/el.ts +++ b/src/locales/el.ts @@ -1282,7 +1282,6 @@ const el = { storage: 'Αποθήκευση εκτυπωτή', storeOnPrinterHint: 'Αναφέρεται σε γραφικό αποθηκευμένο στον εκτυπωτή μέσω ^XG. Η παράδοση καθορίζει αν τα bytes αποστέλλονται με κάθε εργασία, μία φορά στο σενάριο εγκατάστασης, ή καθόλου.', storeInline: 'Ενσωμάτωση', - openObjects: 'Διαχείριση αποθηκευμένων αντικειμένων', }, symbol: { symbol: 'Σύμβολο', @@ -1734,6 +1733,7 @@ const el = { jobNeedsAlias: 'Απαιτεί ψευδώνυμο, ώστε μια ^CW να μπορεί να ονομάσει το αρχείο.', setupNeedsBytes: 'Απαιτεί τα δεδομένα της εικόνας για την κωδικοποίηση της μεταφόρτωσης.', jobNeedsBytes: 'Απαιτεί τα δεδομένα της εικόνας για να σταλούν με την εργασία εκτύπωσης.', + manageObjects: 'Διαχείριση αποθηκευμένων αντικειμένων', opaqueBytes: 'Τα δεδομένα παραμένουν όπως εισήχθησαν και δεν μπορούν να αποθηκευτούν στον εκτυπωτή.', formatJobHint: 'Κάθε εργασία εκτύπωσης αποθηκεύει ξανά τη μορφή και την εκτυπώνει με τις γραμμές ενός συνόλου δεδομένων.', formatSetupHint: 'Το σενάριο εγκατάστασης αυτού του προφίλ εκτυπωτή αποθηκεύει τη μορφή μία φορά. Οι εργασίες στέλνουν μόνο τα δεδομένα.', diff --git a/src/locales/en.ts b/src/locales/en.ts index d26b5ab3..5c8d1f35 100644 --- a/src/locales/en.ts +++ b/src/locales/en.ts @@ -1319,7 +1319,6 @@ const en = { storage: 'Printer storage', storeOnPrinterHint: 'Reference a graphic stored on the printer via ^XG. The delivery decides whether the bytes ship with every job, once in the setup script, or not at all.', storeInline: 'Embed inline', - openObjects: 'Manage stored objects', }, symbol: { symbol: 'Symbol', @@ -1771,6 +1770,7 @@ const en = { jobNeedsAlias: 'Needs an alias, so that a ^CW can name the file.', setupNeedsBytes: 'Needs the image data to encode the upload.', jobNeedsBytes: 'Needs image data to send with the job.', + manageObjects: 'Manage stored objects', opaqueBytes: 'The bytes stay as imported and cannot be stored on the printer.', formatJobHint: 'Every job stores the format again and prints it with the rows of a dataset.', formatSetupHint: 'The setup script of this printer profile stores the format once. Jobs only send the data.', diff --git a/src/locales/es.ts b/src/locales/es.ts index 2837b313..b306ef95 100644 --- a/src/locales/es.ts +++ b/src/locales/es.ts @@ -1282,7 +1282,6 @@ const es = { storage: 'Almacenamiento de impresora', storeOnPrinterHint: 'Referencia un gráfico almacenado en la impresora con ^XG. La entrega decide si los bytes se envían con cada trabajo, una vez en el script de configuración, o nunca.', storeInline: 'Incrustar en línea', - openObjects: 'Gestionar objetos guardados', }, symbol: { symbol: 'Símbolo', @@ -1734,6 +1733,7 @@ const es = { jobNeedsAlias: 'Necesita un alias, para que un ^CW pueda nombrar el archivo.', setupNeedsBytes: 'Necesita los datos de la imagen para codificar la carga.', jobNeedsBytes: 'Necesita los datos de la imagen para enviarlos con el trabajo de impresión.', + manageObjects: 'Gestionar objetos guardados', opaqueBytes: 'Los datos permanecen como se importaron y no se pueden almacenar en la impresora.', formatJobHint: 'Cada trabajo de impresión almacena de nuevo el formato y lo imprime con las filas de un conjunto de datos.', formatSetupHint: 'El script de configuración de este perfil de impresora almacena el formato una vez. Los trabajos solo envían los datos.', diff --git a/src/locales/et.ts b/src/locales/et.ts index 2bb3cbd4..c9eb534a 100644 --- a/src/locales/et.ts +++ b/src/locales/et.ts @@ -1282,7 +1282,6 @@ const et = { storage: 'Printeri salvestus', storeOnPrinterHint: 'Viitab printerisse salvestatud graafikale ^XG kaudu. Edastus määrab, kas baidid saadetakse iga tööga, üks kord seadistusskriptis või üldse mitte.', storeInline: 'Manusta otse', - openObjects: 'Halda salvestatud objekte', }, symbol: { symbol: 'Sümbol', @@ -1734,6 +1733,7 @@ const et = { jobNeedsAlias: 'Vajab varjunime, et ^CW saaks faili nimetada.', setupNeedsBytes: 'Vajab pildiandmeid, et üleslaadimist kodeerida.', jobNeedsBytes: 'Vajab pildiandmeid, et need prinditööga kaasa saata.', + manageObjects: 'Halda salvestatud objekte', opaqueBytes: 'Andmed jäävad sellisena, nagu imporditi, ja neid ei saa printerisse salvestada.', formatJobHint: 'Iga prinditöö salvestab vormingu uuesti ja prindib selle andmestiku ridadega.', formatSetupHint: 'Selle printeriprofiili seadistusskript salvestab vormingu üks kord. Tööd saadavad ainult andmed.', diff --git a/src/locales/fa.ts b/src/locales/fa.ts index 24d18ec6..59b3f78d 100644 --- a/src/locales/fa.ts +++ b/src/locales/fa.ts @@ -1282,7 +1282,6 @@ const fa = { storage: 'ذخیره چاپگر', storeOnPrinterHint: 'به یک گرافیک ذخیره‌شده در چاپگر از طریق ^XG ارجاع می‌دهد. تحویل مشخص می‌کند که بایت‌ها با هر کار ارسال شوند، یک بار در اسکریپت راه‌اندازی ارسال شوند، یا اصلاً ارسال نشوند.', storeInline: 'جاسازی درون‌خطی', - openObjects: 'مدیریت اشیاء ذخیره‌شده', }, symbol: { symbol: 'نماد', @@ -1734,6 +1733,7 @@ const fa = { jobNeedsAlias: 'به نام مستعار نیاز دارد تا یک ^CW بتواند فایل را نام‌گذاری کند.', setupNeedsBytes: 'برای رمزگذاری بارگذاری به داده‌های تصویر نیاز دارد.', jobNeedsBytes: 'برای ارسال با کار چاپ به داده‌های تصویر نیاز دارد.', + manageObjects: 'مدیریت اشیاء ذخیره‌شده', opaqueBytes: 'داده‌ها همان‌طور که وارد شده‌اند باقی می‌مانند و نمی‌توان آن‌ها را روی چاپگر ذخیره کرد.', formatJobHint: 'هر کار چاپ قالب را دوباره ذخیره می‌کند و آن را با ردیف‌های یک مجموعه داده چاپ می‌کند.', formatSetupHint: 'اسکریپت راه‌اندازی این نمایه چاپگر قالب را یک بار ذخیره می‌کند. کارها فقط داده‌ها را ارسال می‌کنند.', diff --git a/src/locales/fi.ts b/src/locales/fi.ts index ca174688..01aa68a7 100644 --- a/src/locales/fi.ts +++ b/src/locales/fi.ts @@ -1282,7 +1282,6 @@ const fi = { storage: 'Tulostimen tallennus', storeOnPrinterHint: 'Viittaa tulostimelle tallennettuun grafiikkaan ^XG:llä. Toimitus määrää, lähetetäänkö tavut jokaisen työn mukana, kerran asennusskriptissä vai ei lainkaan.', storeInline: 'Upota suoraan', - openObjects: 'Hallitse tallennettuja objekteja', }, symbol: { symbol: 'Symboli', @@ -1734,6 +1733,7 @@ const fi = { jobNeedsAlias: 'Vaatii aliaksen, jotta ^CW voi nimetä tiedoston.', setupNeedsBytes: 'Vaatii kuvatiedot lataamisen koodaamiseksi.', jobNeedsBytes: 'Vaatii kuvatiedot lähetettäväksi tulostustyön mukana.', + manageObjects: 'Hallitse tallennettuja objekteja', opaqueBytes: 'Tiedot pysyvät sellaisina kuin ne tuotiin, eikä niitä voi tallentaa tulostimeen.', formatJobHint: 'Jokainen tulostustyö tallentaa muodon uudelleen ja tulostaa sen datajoukon riveillä.', formatSetupHint: 'Tämän tulostinprofiilin asennusskripti tallentaa muodon kerran. Työt lähettävät vain datan.', diff --git a/src/locales/fr.ts b/src/locales/fr.ts index 357057e4..ee9985ec 100644 --- a/src/locales/fr.ts +++ b/src/locales/fr.ts @@ -1282,7 +1282,6 @@ const fr = { storage: 'Stockage de l’imprimante', storeOnPrinterHint: 'Référence un graphique stocké sur l’imprimante via ^XG. La livraison décide si les octets sont envoyés avec chaque travail, une fois dans le script d’installation, ou jamais.', storeInline: 'Intégrer en ligne', - openObjects: 'Gérer les objets stockés', }, symbol: { symbol: 'Symbole', @@ -1734,6 +1733,7 @@ const fr = { jobNeedsAlias: "Nécessite un alias, pour qu'un ^CW puisse nommer le fichier.", setupNeedsBytes: "Nécessite les données de l'image pour encoder le téléversement.", jobNeedsBytes: "Nécessite les données de l'image pour les envoyer avec le travail d'impression.", + manageObjects: 'Gérer les objets stockés', opaqueBytes: "Les données restent telles qu'importées et ne peuvent pas être stockées sur l'imprimante.", formatJobHint: "Chaque travail d'impression stocke à nouveau le format et l'imprime avec les lignes d'un jeu de données.", formatSetupHint: "Le script d'installation de ce profil d'imprimante stocke le format une fois. Les travaux n'envoient que les données.", diff --git a/src/locales/he.ts b/src/locales/he.ts index 9c57b554..6a4ce9ba 100644 --- a/src/locales/he.ts +++ b/src/locales/he.ts @@ -1282,7 +1282,6 @@ const he = { storage: 'אחסון מדפסת', storeOnPrinterHint: 'מפנה לגרפיקה השמורה במדפסת באמצעות ^XG. האספקה קובעת אם הבתים נשלחים עם כל עבודה, פעם אחת בסקריפט ההתקנה, או שלא נשלחים כלל.', storeInline: 'הטמע בתוך', - openObjects: 'ניהול אובייקטים שמורים', }, symbol: { symbol: 'סמל', @@ -1734,6 +1733,7 @@ const he = { jobNeedsAlias: 'דורש כינוי, כדי ש-^CW יוכל לתת שם לקובץ.', setupNeedsBytes: 'דורש את נתוני התמונה כדי לקדד את ההעלאה.', jobNeedsBytes: 'דורש את נתוני התמונה כדי לשלוח אותם עם עבודת ההדפסה.', + manageObjects: 'ניהול אובייקטים שמורים', opaqueBytes: 'הנתונים נשארים כפי שיובאו ולא ניתן לאחסן אותם במדפסת.', formatJobHint: 'כל עבודת הדפסה שומרת את הפורמט מחדש ומדפיסה אותו עם שורות של מערך נתונים.', formatSetupHint: 'סקריפט ההתקנה של פרופיל מדפסת זה שומר את הפורמט פעם אחת. עבודות שולחות רק את הנתונים.', diff --git a/src/locales/hr.ts b/src/locales/hr.ts index 3def6590..88b9f8df 100644 --- a/src/locales/hr.ts +++ b/src/locales/hr.ts @@ -1282,7 +1282,6 @@ const hr = { storage: 'Pohrana pisača', storeOnPrinterHint: 'Referencira grafiku pohranjenu na pisaču putem ^XG. Isporuka određuje šalju li se bajtovi sa svakim zadatkom, jednom u instalacijskoj skripti ili uopće ne.', storeInline: 'Ugradi izravno', - openObjects: 'Upravljaj pohranjenim objektima', }, symbol: { symbol: 'Simbol', @@ -1734,6 +1733,7 @@ const hr = { jobNeedsAlias: 'Zahtijeva alias, kako bi ^CW mogao imenovati datoteku.', setupNeedsBytes: 'Zahtijeva podatke slike za kodiranje prijenosa.', jobNeedsBytes: 'Zahtijeva podatke slike za slanje s ispisnim zadatkom.', + manageObjects: 'Upravljaj pohranjenim objektima', opaqueBytes: 'Podaci ostaju kakvi su uvezeni i ne mogu se spremiti na pisač.', formatJobHint: 'Svaki ispisni zadatak ponovno pohranjuje format i ispisuje ga s redcima skupa podataka.', formatSetupHint: 'Instalacijska skripta ovog profila pisača pohranjuje format jednom. Zadaci šalju samo podatke.', diff --git a/src/locales/hu.ts b/src/locales/hu.ts index 6aba7799..ed421714 100644 --- a/src/locales/hu.ts +++ b/src/locales/hu.ts @@ -1282,7 +1282,6 @@ const hu = { storage: 'Nyomtató tárhely', storeOnPrinterHint: 'A nyomtatón tárolt grafikára hivatkozik ^XG-vel. A továbbítás dönti el, hogy a bájtok minden feladattal, egyszer a beállító szkriptben, vagy egyáltalán nem kerülnek elküldésre.', storeInline: 'Beágyazás', - openObjects: 'Tárolt objektumok kezelése', }, symbol: { symbol: 'Szimbólum', @@ -1734,6 +1733,7 @@ const hu = { jobNeedsAlias: 'Aliasra van szükség, hogy egy ^CW elnevezhesse a fájlt.', setupNeedsBytes: 'A feltöltés kódolásához szükség van a kép adataira.', jobNeedsBytes: 'A nyomtatási feladattal való elküldéshez szükség van a kép adataira.', + manageObjects: 'Tárolt objektumok kezelése', opaqueBytes: 'Az adatok az importált formájukban maradnak, és nem menthetők el a nyomtatóra.', formatJobHint: 'Minden nyomtatási feladat újra tárolja a formátumot, és egy adathalmaz soraival nyomtatja ki.', formatSetupHint: 'Ennek a nyomtatóprofilnak a beállító szkriptje egyszer tárolja a formátumot. A feladatok csak az adatokat küldik.', diff --git a/src/locales/it.ts b/src/locales/it.ts index 8cf234fb..48848041 100644 --- a/src/locales/it.ts +++ b/src/locales/it.ts @@ -1282,7 +1282,6 @@ const it = { storage: 'Archiviazione stampante', storeOnPrinterHint: 'Riferimento a una grafica memorizzata sulla stampante tramite ^XG. La consegna decide se i byte vengono inviati con ogni lavoro, una volta nello script di configurazione, oppure mai.', storeInline: 'Incorpora', - openObjects: 'Gestisci gli oggetti memorizzati', }, symbol: { symbol: 'Simbolo', @@ -1734,6 +1733,7 @@ const it = { jobNeedsAlias: 'Richiede un alias, così un ^CW può nominare il file.', setupNeedsBytes: "Richiede i dati dell'immagine per codificare il caricamento.", jobNeedsBytes: "Richiede i dati dell'immagine per inviarli con il lavoro di stampa.", + manageObjects: 'Gestisci gli oggetti memorizzati', opaqueBytes: 'I dati restano come importati e non possono essere memorizzati sulla stampante.', formatJobHint: 'Ogni lavoro di stampa memorizza di nuovo il formato e lo stampa con le righe di un set di dati.', formatSetupHint: 'Lo script di configurazione di questo profilo stampante memorizza il formato una volta. I lavori inviano solo i dati.', diff --git a/src/locales/ja.ts b/src/locales/ja.ts index 7b7dd31f..f8d54d6c 100644 --- a/src/locales/ja.ts +++ b/src/locales/ja.ts @@ -1282,7 +1282,6 @@ const ja = { storage: 'プリンター記憶', storeOnPrinterHint: 'プリンターに保存されたグラフィックを ^XG で参照します。配信の設定によって、バイトを各ジョブで送信するか、セットアップスクリプトで一度だけ送信するか、まったく送信しないかが決まります。', storeInline: 'インライン埋め込み', - openObjects: '保存済みオブジェクトを管理', }, symbol: { symbol: 'シンボル', @@ -1734,6 +1733,7 @@ const ja = { jobNeedsAlias: 'エイリアスが必要です。^CW がファイルに名前を付けられるようにするためです。', setupNeedsBytes: 'アップロードを符号化するために画像データが必要です。', jobNeedsBytes: '印刷ジョブと一緒に送信するために画像データが必要です。', + manageObjects: '保存済みオブジェクトを管理', opaqueBytes: 'データはインポートされたままで、プリンターに保存できません。', formatJobHint: '各印刷ジョブは書式を再度保存し、データセットの行と共に印刷します。', formatSetupHint: 'このプリンタープロファイルのセットアップスクリプトが書式を一度だけ保存します。ジョブはデータのみを送信します。', diff --git a/src/locales/ko.ts b/src/locales/ko.ts index 3519a85d..771fd822 100644 --- a/src/locales/ko.ts +++ b/src/locales/ko.ts @@ -1282,7 +1282,6 @@ const ko = { storage: '프린터 저장소', storeOnPrinterHint: '프린터에 저장된 그래픽을 ^XG로 참조합니다. 전달 설정에 따라 바이트가 매 작업마다 전송되는지, 설정 스크립트에 한 번만 전송되는지, 아니면 전혀 전송되지 않는지가 결정됩니다.', storeInline: '인라인 포함', - openObjects: '저장된 개체 관리', }, symbol: { symbol: '심볼', @@ -1734,6 +1733,7 @@ const ko = { jobNeedsAlias: '별칭이 필요합니다. ^CW가 파일 이름을 지정할 수 있도록 하기 위해서입니다.', setupNeedsBytes: '업로드를 인코딩하려면 이미지 데이터가 필요합니다.', jobNeedsBytes: '인쇄 작업과 함께 전송하려면 이미지 데이터가 필요합니다.', + manageObjects: '저장된 개체 관리', opaqueBytes: '데이터는 가져온 그대로 유지되며 프린터에 저장할 수 없습니다.', formatJobHint: '각 인쇄 작업은 포맷을 다시 저장하고 데이터셋의 행과 함께 인쇄합니다.', formatSetupHint: '이 프린터 프로필의 설정 스크립트가 포맷을 한 번만 저장합니다. 작업은 데이터만 전송합니다.', diff --git a/src/locales/lt.ts b/src/locales/lt.ts index 1855d751..6941750b 100644 --- a/src/locales/lt.ts +++ b/src/locales/lt.ts @@ -1282,7 +1282,6 @@ const lt = { storage: 'Spausdintuvo saugykla', storeOnPrinterHint: 'Nurodo spausdintuve saugomą grafiką per ^XG. Pristatymas nulemia, ar baitai siunčiami su kiekviena užduotimi, vieną kartą sąrankos scenarijuje, ar visai nesiunčiami.', storeInline: 'Įterpti tiesiogiai', - openObjects: 'Tvarkyti įrašytus objektus', }, symbol: { symbol: 'Simbolis', @@ -1734,6 +1733,7 @@ const lt = { jobNeedsAlias: 'Reikia slapyvardžio, kad ^CW galėtų įvardyti failą.', setupNeedsBytes: 'Reikia vaizdo duomenų, kad būtų užkoduotas įkėlimas.', jobNeedsBytes: 'Reikia vaizdo duomenų, kad jie būtų išsiųsti su spausdinimo užduotimi.', + manageObjects: 'Tvarkyti įrašytus objektus', opaqueBytes: 'Duomenys išlieka tokie, kokie buvo importuoti, ir jų negalima išsaugoti spausdintuve.', formatJobHint: 'Kiekviena spausdinimo užduotis vėl išsaugo formatą ir spausdina jį su duomenų rinkinio eilutėmis.', formatSetupHint: 'Šio spausdintuvo profilio sąrankos scenarijus išsaugo formatą vieną kartą. Užduotys siunčia tik duomenis.', diff --git a/src/locales/lv.ts b/src/locales/lv.ts index bd829347..341252fe 100644 --- a/src/locales/lv.ts +++ b/src/locales/lv.ts @@ -1282,7 +1282,6 @@ const lv = { storage: 'Printera krātuve', storeOnPrinterHint: 'Atsaucas uz printerī saglabātu grafiku, izmantojot ^XG. Piegāde nosaka, vai baiti tiek sūtīti ar katru darbu, vienreiz iestatīšanas skriptā, vai vispār netiek sūtīti.', storeInline: 'Iegult tieši', - openObjects: 'Pārvaldīt saglabātos objektus', }, symbol: { symbol: 'Simbols', @@ -1734,6 +1733,7 @@ const lv = { jobNeedsAlias: 'Nepieciešams aizstājvārds, lai ^CW varētu nosaukt failu.', setupNeedsBytes: 'Nepieciešami attēla dati, lai kodētu augšupielādi.', jobNeedsBytes: 'Nepieciešami attēla dati, lai tos nosūtītu kopā ar drukas darbu.', + manageObjects: 'Pārvaldīt saglabātos objektus', opaqueBytes: 'Dati paliek tādi, kādi tika importēti, un tos nevar saglabāt printerī.', formatJobHint: 'Katrs drukas darbs saglabā formātu no jauna un drukā to ar datu kopas rindām.', formatSetupHint: 'Šī printera profila iestatīšanas skripts saglabā formātu vienreiz. Darbi sūta tikai datus.', diff --git a/src/locales/nl.ts b/src/locales/nl.ts index 137eb10a..da8c24e8 100644 --- a/src/locales/nl.ts +++ b/src/locales/nl.ts @@ -1282,7 +1282,6 @@ const nl = { storage: 'Printer-opslag', storeOnPrinterHint: 'Verwijst naar een afbeelding op de printer via ^XG. De levering bepaalt of de bytes met elke taak, eenmalig in het installatiescript, of helemaal niet worden meegestuurd.', storeInline: 'Inline insluiten', - openObjects: 'Opgeslagen objecten beheren', }, symbol: { symbol: 'Symbool', @@ -1734,6 +1733,7 @@ const nl = { jobNeedsAlias: 'Vereist een alias, zodat een ^CW het bestand kan benoemen.', setupNeedsBytes: 'Vereist de afbeeldingsgegevens om de upload te coderen.', jobNeedsBytes: 'Vereist de afbeeldingsgegevens om ze met de afdruktaak te verzenden.', + manageObjects: 'Opgeslagen objecten beheren', opaqueBytes: 'De gegevens blijven zoals geïmporteerd en kunnen niet op de printer worden opgeslagen.', formatJobHint: 'Elke afdruktaak slaat het formaat opnieuw op en drukt het af met de rijen van een gegevensset.', formatSetupHint: 'Het installatiescript van dit printerprofiel slaat het formaat eenmalig op. Taken sturen alleen de gegevens.', diff --git a/src/locales/no.ts b/src/locales/no.ts index 522c587c..2ccde42d 100644 --- a/src/locales/no.ts +++ b/src/locales/no.ts @@ -1282,7 +1282,6 @@ const no = { storage: 'Skriverlagring', storeOnPrinterHint: 'Refererer til en grafikk lagret på skriveren via ^XG. Leveringen avgjør om bytene sendes med hver jobb, én gang i oppsettsskriptet, eller ikke i det hele tatt.', storeInline: 'Bygg inn direkte', - openObjects: 'Administrer lagrede objekter', }, symbol: { symbol: 'Symbol', @@ -1734,6 +1733,7 @@ const no = { jobNeedsAlias: 'Krever et alias, slik at en ^CW kan navngi filen.', setupNeedsBytes: 'Krever bildedataene for å kode opplastingen.', jobNeedsBytes: 'Krever bildedataene for å sende dem med utskriftsjobben.', + manageObjects: 'Administrer lagrede objekter', opaqueBytes: 'Dataene forblir som importert og kan ikke lagres på skriveren.', formatJobHint: 'Hver utskriftsjobb lagrer formatet på nytt og skriver det ut med radene fra et datasett.', formatSetupHint: 'Oppsettsskriptet til denne skriverprofilen lagrer formatet én gang. Jobber sender bare dataene.', diff --git a/src/locales/pl.ts b/src/locales/pl.ts index aa58ceaf..c63b34c5 100644 --- a/src/locales/pl.ts +++ b/src/locales/pl.ts @@ -1282,7 +1282,6 @@ const pl = { storage: 'Pamięć drukarki', storeOnPrinterHint: 'Odwołuje się do grafiki przechowywanej na drukarce za pomocą ^XG. Dostarczanie decyduje, czy bajty są wysyłane z każdym zadaniem, raz w skrypcie konfiguracyjnym, czy wcale.', storeInline: 'Osadź bezpośrednio', - openObjects: 'Zarządzaj zapisanymi obiektami', }, symbol: { symbol: 'Symbol', @@ -1734,6 +1733,7 @@ const pl = { jobNeedsAlias: 'Wymaga aliasu, aby ^CW mógł nazwać plik.', setupNeedsBytes: 'Wymaga danych obrazu, aby zakodować przesyłanie.', jobNeedsBytes: 'Wymaga danych obrazu, aby wysłać je z zadaniem drukowania.', + manageObjects: 'Zarządzaj zapisanymi obiektami', opaqueBytes: 'Dane pozostają takie, jak zostały zaimportowane, i nie można ich zapisać w drukarce.', formatJobHint: 'Każde zadanie drukowania ponownie zapisuje format i drukuje go z wierszami zbioru danych.', formatSetupHint: 'Skrypt konfiguracyjny tego profilu drukarki zapisuje format raz. Zadania wysyłają tylko dane.', diff --git a/src/locales/pt.ts b/src/locales/pt.ts index 351b41d4..34fcffe7 100644 --- a/src/locales/pt.ts +++ b/src/locales/pt.ts @@ -1282,7 +1282,6 @@ const pt = { storage: 'Armazenamento da impressora', storeOnPrinterHint: 'Referencia uma imagem armazenada na impressora via ^XG. A entrega decide se os bytes são enviados com cada trabalho, uma vez no script de configuração, ou nunca.', storeInline: 'Incorporar', - openObjects: 'Gerir objetos guardados', }, symbol: { symbol: 'Símbolo', @@ -1734,6 +1733,7 @@ const pt = { jobNeedsAlias: 'Precisa de um alias, para que um ^CW possa nomear o arquivo.', setupNeedsBytes: 'Precisa dos dados da imagem para codificar o envio.', jobNeedsBytes: 'Precisa dos dados da imagem para enviá-los com o trabalho de impressão.', + manageObjects: 'Gerir objetos guardados', opaqueBytes: 'Os dados permanecem como foram importados e não podem ser armazenados na impressora.', formatJobHint: 'Cada trabalho de impressão armazena o formato novamente e o imprime com as linhas de um conjunto de dados.', formatSetupHint: 'O script de configuração deste perfil de impressora armazena o formato uma vez. Os trabalhos apenas enviam os dados.', diff --git a/src/locales/ro.ts b/src/locales/ro.ts index f874238f..00a6acdc 100644 --- a/src/locales/ro.ts +++ b/src/locales/ro.ts @@ -1282,7 +1282,6 @@ const ro = { storage: 'Stocare imprimantă', storeOnPrinterHint: 'Referențiază un grafic stocat pe imprimantă prin ^XG. Livrarea decide dacă octeții sunt trimiși cu fiecare lucrare, o dată în scriptul de configurare, sau deloc.', storeInline: 'Încorporează direct', - openObjects: 'Gestionează obiectele stocate', }, symbol: { symbol: 'Simbol', @@ -1734,6 +1733,7 @@ const ro = { jobNeedsAlias: 'Necesită un alias, pentru ca un ^CW să poată numi fișierul.', setupNeedsBytes: 'Necesită datele imaginii pentru a codifica încărcarea.', jobNeedsBytes: 'Necesită datele imaginii pentru a le trimite odată cu sarcina de imprimare.', + manageObjects: 'Gestionează obiectele stocate', opaqueBytes: 'Datele rămân așa cum au fost importate și nu pot fi stocate pe imprimantă.', formatJobHint: 'Fiecare sarcină de imprimare stochează din nou formatul și îl tipărește cu rândurile unui set de date.', formatSetupHint: 'Scriptul de configurare al acestui profil de imprimantă stochează formatul o dată. Sarcinile trimit doar datele.', diff --git a/src/locales/sk.ts b/src/locales/sk.ts index 5976c699..d10f35df 100644 --- a/src/locales/sk.ts +++ b/src/locales/sk.ts @@ -1282,7 +1282,6 @@ const sk = { storage: 'Úložisko tlačiarne', storeOnPrinterHint: 'Odkazuje na grafiku uloženú v tlačiarni cez ^XG. Doručenie určuje, či sa bajty odošlú s každou úlohou, raz v inštalačnom skripte, alebo vôbec.', storeInline: 'Vložiť priamo', - openObjects: 'Spravovať uložené objekty', }, symbol: { symbol: 'Symbol', @@ -1734,6 +1733,7 @@ const sk = { jobNeedsAlias: 'Vyžaduje alias, aby ^CW mohol súbor pomenovať.', setupNeedsBytes: 'Vyžaduje obrazové dáta na zakódovanie nahrávania.', jobNeedsBytes: 'Vyžaduje obrazové dáta na odoslanie s tlačovou úlohou.', + manageObjects: 'Spravovať uložené objekty', opaqueBytes: 'Dáta zostávajú tak, ako boli importované, a nemožno ich uložiť do tlačiarne.', formatJobHint: 'Každá tlačová úloha znovu uloží formát a vytlačí ho s riadkami dátovej sady.', formatSetupHint: 'Inštalačný skript tohto profilu tlačiarne uloží formát raz. Úlohy odosielajú len údaje.', diff --git a/src/locales/sl.ts b/src/locales/sl.ts index d2863a78..035ca92a 100644 --- a/src/locales/sl.ts +++ b/src/locales/sl.ts @@ -1282,7 +1282,6 @@ const sl = { storage: 'Shramba tiskalnika', storeOnPrinterHint: 'Sklicuje se na grafiko, shranjeno v tiskalniku, prek ^XG. Dostava določa, ali se bajti pošljejo z vsakim opravilom, enkrat v namestitvenem skriptu, ali sploh ne.', storeInline: 'Vstavi neposredno', - openObjects: 'Upravljanje shranjenih predmetov', }, symbol: { symbol: 'Simbol', @@ -1734,6 +1733,7 @@ const sl = { jobNeedsAlias: 'Potrebuje vzdevek, da lahko ^CW poimenuje datoteko.', setupNeedsBytes: 'Potrebuje slikovne podatke za kodiranje nalaganja.', jobNeedsBytes: 'Potrebuje slikovne podatke za pošiljanje s tiskalniškim opravilom.', + manageObjects: 'Upravljanje shranjenih predmetov', opaqueBytes: 'Podatki ostanejo takšni, kot so bili uvoženi, in jih ni mogoče shraniti v tiskalnik.', formatJobHint: 'Vsako tiskalniško opravilo znova shrani obliko zapisa in jo natisne z vrsticami podatkovnega niza.', formatSetupHint: 'Namestitveni skript tega profila tiskalnika shrani obliko zapisa enkrat. Opravila pošljejo samo podatke.', diff --git a/src/locales/sr.ts b/src/locales/sr.ts index ed5dba9f..3bc1591c 100644 --- a/src/locales/sr.ts +++ b/src/locales/sr.ts @@ -1282,7 +1282,6 @@ const sr = { storage: 'Меморија штампача', storeOnPrinterHint: 'Реферише на графику ускладиштену у штампачу преко ^XG. Испорука одређује да ли се бајтови шаљу са сваким послом, једном у скрипти за подешавање, или уопште не.', storeInline: 'Уграђено', - openObjects: 'Управљај сачуваним објектима', }, symbol: { symbol: 'Симбол', @@ -1734,6 +1733,7 @@ const sr = { jobNeedsAlias: 'Захтева алијас, како би ^CW могао да именује датотеку.', setupNeedsBytes: 'Захтева податке слике за кодирање преноса.', jobNeedsBytes: 'Захтева податке слике за слање са послом штампе.', + manageObjects: 'Управљај сачуваним објектима', opaqueBytes: 'Подаци остају такви какви су увезени и не могу се сачувати на штампачу.', formatJobHint: 'Сваки посао штампе поново чува формат и штампа га са редовима скупа података.', formatSetupHint: 'Скрипта за подешавање овог профила штампача чува формат једном. Послови шаљу само податке.', diff --git a/src/locales/sv.ts b/src/locales/sv.ts index 3840fc7b..cd7d4133 100644 --- a/src/locales/sv.ts +++ b/src/locales/sv.ts @@ -1282,7 +1282,6 @@ const sv = { storage: 'Skrivarlagring', storeOnPrinterHint: 'Refererar till en grafik som är lagrad på skrivaren via ^XG. Leveransen avgör om bytena skickas med varje jobb, en gång i installationsskriptet, eller inte alls.', storeInline: 'Bädda in direkt', - openObjects: 'Hantera sparade objekt', }, symbol: { symbol: 'Symbol', @@ -1734,6 +1733,7 @@ const sv = { jobNeedsAlias: 'Kräver ett alias, så att en ^CW kan namnge filen.', setupNeedsBytes: 'Kräver bilddata för att koda uppladdningen.', jobNeedsBytes: 'Kräver bilddata för att skicka med utskriftsjobbet.', + manageObjects: 'Hantera sparade objekt', opaqueBytes: 'Data förblir som importerat och kan inte lagras på skrivaren.', formatJobHint: 'Varje utskriftsjobb lagrar formatet igen och skriver ut det med raderna i en datamängd.', formatSetupHint: 'Installationsskriptet för den här skrivarprofilen lagrar formatet en gång. Jobb skickar bara data.', diff --git a/src/locales/tr.ts b/src/locales/tr.ts index f11d8aad..fc22b01d 100644 --- a/src/locales/tr.ts +++ b/src/locales/tr.ts @@ -1282,7 +1282,6 @@ const tr = { storage: 'Yazıcı depolama', storeOnPrinterHint: 'Yazıcıda saklanan bir grafiğe ^XG ile başvurur. Teslimat, baytların her işle mi, kurulum betiğinde bir kez mi, yoksa hiç gönderilmeyeceğini mi belirler.', storeInline: 'Satır içi göm', - openObjects: 'Kayıtlı nesneleri yönet', }, symbol: { symbol: 'Sembol', @@ -1734,6 +1733,7 @@ const tr = { jobNeedsAlias: 'Bir ^CW dosyayı adlandırabilsin diye takma ad gerektirir.', setupNeedsBytes: 'Yüklemeyi kodlamak için görüntü verilerini gerektirir.', jobNeedsBytes: 'Yazdırma işiyle göndermek için görüntü verilerini gerektirir.', + manageObjects: 'Kayıtlı nesneleri yönet', opaqueBytes: 'Veriler içe aktarıldığı gibi kalır ve yazıcıya kaydedilemez.', formatJobHint: 'Her yazdırma işi biçimi yeniden saklar ve onu bir veri kümesinin satırlarıyla yazdırır.', formatSetupHint: 'Bu yazıcı profilinin kurulum betiği biçimi bir kez saklar. İşler yalnızca verileri gönderir.', diff --git a/src/locales/zh-hans.ts b/src/locales/zh-hans.ts index 87c63f22..a940e885 100644 --- a/src/locales/zh-hans.ts +++ b/src/locales/zh-hans.ts @@ -1282,7 +1282,6 @@ const zhHans = { storage: '打印机存储', storeOnPrinterHint: '通过 ^XG 引用存储在打印机上的图形。交付设置决定字节是随每个作业发送、在安装脚本中一次性发送,还是完全不发送。', storeInline: '内嵌', - openObjects: '管理已存对象', }, symbol: { symbol: '符号', @@ -1734,6 +1733,7 @@ const zhHans = { jobNeedsAlias: '需要别名,以便 ^CW 可以为文件命名。', setupNeedsBytes: '需要图像数据来编码此次上传。', jobNeedsBytes: '需要图像数据以随打印任务一起发送。', + manageObjects: '管理已存对象', opaqueBytes: '数据保持导入时的原样,无法存储在打印机上。', formatJobHint: '每个打印任务都会重新存储格式,并使用数据集的行来打印。', formatSetupHint: '此打印机配置文件的安装脚本一次性存储格式。任务只发送数据。', diff --git a/src/locales/zh-hant.ts b/src/locales/zh-hant.ts index 7a634ba2..2ba64c7e 100644 --- a/src/locales/zh-hant.ts +++ b/src/locales/zh-hant.ts @@ -1282,7 +1282,6 @@ const zhHant = { storage: '印表機儲存', storeOnPrinterHint: '透過 ^XG 引用儲存在印表機上的圖形。交付設定決定位元組隨每個工作傳送、在安裝指令稿中一次傳送,還是完全不傳送。', storeInline: '內嵌', - openObjects: '管理已存物件', }, symbol: { symbol: '符號', @@ -1734,6 +1733,7 @@ const zhHant = { jobNeedsAlias: '需要別名,以便 ^CW 可以為檔案命名。', setupNeedsBytes: '需要影像資料來編碼此次上傳。', jobNeedsBytes: '需要影像資料以隨列印工作一起傳送。', + manageObjects: '管理已存物件', opaqueBytes: '資料保持匯入時的原樣,無法儲存在印表機上。', formatJobHint: '每個列印工作都會重新儲存格式,並使用資料集的列來列印。', formatSetupHint: '此印表機設定檔的安裝指令稿一次儲存格式。工作只傳送資料。', diff --git a/src/registry/image.panel.test.tsx b/src/registry/image.panel.test.tsx index fc2ffd38..6add00dd 100644 --- a/src/registry/image.panel.test.tsx +++ b/src/registry/image.panel.test.tsx @@ -45,7 +45,7 @@ beforeEach(() => { afterEach(() => { cleanup(); removeImage("cat"); - act(() => useLabelStore.setState({ printerProfile: {} })); + act(() => useLabelStore.setState({ printerProfile: {}, printerSettingsTab: null })); }); const option = (r: ReturnType, name: string) => { @@ -275,14 +275,26 @@ describe("image panel delivery", () => { expect(useLabelStore.getState().printerProfile.setupGraphics).toBeUndefined(); }); - it("hands off from the setup-script hint to the stored graphics tab", () => { - act(() => useLabelStore.setState({ printerProfile: { setupGraphics: [{ path: "R:LOGO.GRF", gfa: GFA }] } })); + it("hands off to the stored graphics tab for a recall the tab lists", () => { + act(() => useLabelStore.setState({ pages: [{ objects: [stored({ embedInZpl: false }) as never] }] })); const { getByText } = render( undefined} />); act(() => { fireEvent.click(getByText(/Manage stored objects/)); }); expect(useLabelStore.getState().printerSettingsTab).toBe("storedGraphics"); - act(() => useLabelStore.setState({ printerSettingsTab: null })); + }); + + it("offers the link for a cached image with no printer name", () => { + putImage({ id: "cat", name: "cat.png", dataUrl: "data:image/png;base64,", width: 1, height: 1 }); + const obj = inline(); + const { getByText } = render( undefined} />); + expect(getByText(/Manage stored objects/)).toBeTruthy(); + }); + + it("offers no link for a recall of a file no upload writes", () => { + act(() => useLabelStore.setState({ pages: [{ objects: [stored({ ext: "PNG", recall: "IM", embedInZpl: false }) as never] }] })); + const { queryByText } = render( undefined} />); + expect(queryByText(/Manage stored objects/)).toBeNull(); }); it("shows a refused encode until the object's bytes change", () => { diff --git a/src/registry/image.panel.tsx b/src/registry/image.panel.tsx index 0468bd6a..c2d07935 100644 --- a/src/registry/image.panel.tsx +++ b/src/registry/image.panel.tsx @@ -16,6 +16,7 @@ import { Select } from '../components/ui/Select'; import { IMAGE_PROP_SPECS, isImageRotatable, profileGraphicRecall, recallCommand, recalledSetupEntry, recallStoragePath, retiredSources, setupGraphicState, type ImageProps } from '@zplab/core/registry/image'; import { applyGraphicDelivery, draftGraphicIdentity, graphicDelivery, graphicWayBlocks, providedGraphic, type GraphicWayBlock, type ResourceDelivery } from '@zplab/core/lib/resourceDelivery'; import { findSetupEntry } from '@zplab/core/lib/setupEntries'; +import { listsStoredGraphic, storedGraphicRows } from '@zplab/core/lib/storedObjects'; import { DeliverySelect } from '../components/Properties/DeliverySelect'; import { useCachedImages } from '../hooks/useCachedImages'; import { useLabelStore } from '../store/labelStore'; @@ -78,6 +79,7 @@ export const imagePanel: ObjectTypeUi = { const setupGraphics = useLabelStore((s) => s.printerProfile.setupGraphics); const patchPrinterProfile = useLabelStore((s) => s.patchPrinterProfile); const openObjects = useLabelStore((s) => s.setPrinterSettingsTab); + const listed = useLabelStore((s) => listsStoredGraphic(storedGraphicRows(s.pages), p)); // Held in state so the drafted name does not churn across renders. const [draft, setDraft] = useState(() => draftGraphicIdentity(setupGraphics)); // A draft the profile already holds would adopt that entry's bytes, so redraft before the checks read it. @@ -272,7 +274,7 @@ export const imagePanel: ObjectTypeUi = { blocked={{ job: blocked('job'), setup: blocked('setup'), printer: blocked('printer') }} disabled={locked} issue={issue} - onOpenSetup={{ label: t.registry.image.openObjects, open: () => openObjects('storedGraphics') }} + manage={listed ? { label: t.delivery.manageObjects, open: () => openObjects('storedGraphics') } : undefined} /> {(refusal || (storedAs && setupState === 'tooLarge')) && ( {refusal === 'unshippable' ? t.printerSettings.objects.tooWide : t.printerSettings.objects.tooLarge}