// 원본 묶음 인쇄(TEstPrint.Print 0x10fef98, TFRMESTPRINT2·TFRMPRINTLISTCHECK·TFRMESTPRINTPRIVATE 간지). // 인쇄표 차례대로(공통 설정 행 Index 0 제외) 고른(Checked) 서식마다 간지(PrintGangiShow, 가운데 제목 Name2 · 겹테두리) → 서식 본문. // 웹은 한 문서로 이어 인쇄하고 쪽 번호는 브라우저 쪽 번호를 쓴다(원본은 간지가 쪽 번호를 쓰지 않음 — 웹은 간지 쪽에 번호만 숨김). // 서식 본문은 인쇄 미리보기와 같은 자료(EstForms.data · EstDocs.html). 화면 전용 서식은 건너뛰고 알린다. const EstPrintBatch = (() => { const esc = (v) => String(v ?? "").replace( /[&<>"]/g, (c) => ({ "&": "&", "<": "<", ">": ">", '"': """ })[c], ); function forms(catalog, project) { const saved = project.printBatch?.checked; return catalog .filter((row) => Number(row.Index) !== 0) .map((row) => ({ Index: row.Index, Name: row.Name2 || row.Name || String(row.Index), checked: saved ? saved.includes(row.Index) : Number(row.Checked) === 1, gangi: project.printBatch?.gangi ?? Number(row.PrintGangiShow) === 1, outline: Number(row.PrintGangiOutLineShow ?? 1) === 1, })); } function body(index, project, state) { const output = EstForms.data(index, project, state); if (output) return EstForms.grid(output); const doc = typeof EstDocs !== "undefined" ? EstDocs.html(Number(index), project) : ""; return doc || null; } function document_(list, project, state, gangi) { const skipped = [], parts = []; for (const form of list.filter((f) => f.checked)) { const html = body(form.Index, project, state); if (html == null) { skipped.push(form.Name); continue; } if (gangi) parts.push( `
${esc(form.Name)}
`, ); parts.push(`

${esc(form.Name)}

${html}
`); } const html = `${esc(project.name)} 설계서${parts.join("")}`; return { html, skipped, count: parts.length }; } let catalog = []; async function open(state) { const defaults = await EstApp.api("/api/print-catalog"); const original = new Map((state.project.printCatalog || []).map((row) => [row.Index, row])); catalog = defaults.map((row) => ({ ...row, ...original.get(row.Index) })); render(state); } function render(state) { const list = forms(catalog, state.project); EstApp.showDialog( "묶음 인쇄(설계서 일체)", `

인쇄할 서식을 고르세요. 인쇄표 차례대로 이어 인쇄합니다.

${list.map((f) => ``).join("")}
`, ); } function read(state) { const checked = [...document.querySelectorAll('#dialog-content [name="pb-form"]:checked')].map( (n) => (/^\d+$/.test(n.value) ? Number(n.value) : n.value), ); const gangi = document.querySelector('#dialog-content [name="pb-gangi"]').checked; if (!checked.length) throw Error("인쇄할 서식을 하나 이상 고르세요."); const next = { checked, gangi }; if (JSON.stringify(next) !== JSON.stringify(state.project.printBatch)) EstApp.change((project) => (project.printBatch = next), false); return next; } function build(state) { const { gangi } = read(state), list = forms(catalog, state.project), out = document_(list, state.project, state, gangi), frame = EstApp.byId("print-batch-frame"); frame.srcdoc = out.html; EstApp.byId("print-batch-note").textContent = `서식·간지 ${out.count}개${out.skipped.length ? ` · 화면 전용이라 뺀 서식: ${out.skipped.join(", ")}` : ""}`; return frame; } function handle(name, state) { if (name === "print-batch") open(state).catch((error) => { state.notice = error.message; EstApp.render(); }); else if (name === "print-batch-preview") build(state); else if (name === "print-batch-print") { const frame = build(state); frame.onload = () => frame.contentWindow.print(); } else return false; return true; } return { forms, document: document_, handle }; })();