Fix Sichtbarkeit von Ist-Stand und Plan im PDF ohne JavaScript
This commit is contained in:
1 parent
fc11c894a5
commit
6a06a5f2a9
1 file changed
+40
@@ -11,6 +11,7 @@ from pathlib import Path
|
|||||||
from typing import Any, Dict, Optional
|
from typing import Any, Dict, Optional
|
||||||
|
|
||||||
from pypdf import PdfReader, PdfWriter
|
from pypdf import PdfReader, PdfWriter
|
||||||
|
from pypdf.generic import NameObject, NumberObject
|
||||||
|
|
||||||
from .config_loader import load_config
|
from .config_loader import load_config
|
||||||
from .exceptions import PdfTemplateError
|
from .exceptions import PdfTemplateError
|
||||||
@@ -73,6 +74,43 @@ def build_field_dict(
|
|||||||
return fields
|
return fields
|
||||||
|
|
||||||
|
|
||||||
|
def _update_widget_visibility(writer: PdfWriter, fields: Dict[str, str]) -> None:
|
||||||
|
"""Un-hide widget annotations for ist.N and plan.N fields that have a value.
|
||||||
|
|
||||||
|
In the PDF template these fields carry annotation flag /F=6 (Print + Hidden)
|
||||||
|
by default. The form's JavaScript (ZeileBerechnen) normally removes the
|
||||||
|
hidden bit at runtime when ``anwesend.N`` is selected. Because we write
|
||||||
|
values directly without executing JavaScript we must clear the hidden bit
|
||||||
|
ourselves for every row where a value is present.
|
||||||
|
"""
|
||||||
|
HIDDEN_FIELD_PREFIXES = ("ist.", "plan.")
|
||||||
|
HIDDEN_BIT = 2 # PDF annotation flag bit 2 = Hidden
|
||||||
|
|
||||||
|
for page in writer.pages:
|
||||||
|
annots = page.get("/Annots")
|
||||||
|
if not annots:
|
||||||
|
continue
|
||||||
|
for annot_ref in annots:
|
||||||
|
annot = annot_ref.get_object()
|
||||||
|
t = str(annot.get("/T", ""))
|
||||||
|
parent = annot.get("/Parent")
|
||||||
|
if parent:
|
||||||
|
par_t = str(parent.get_object().get("/T", ""))
|
||||||
|
full_name = f"{par_t}.{t}"
|
||||||
|
else:
|
||||||
|
full_name = t
|
||||||
|
|
||||||
|
if not any(full_name.startswith(p) for p in HIDDEN_FIELD_PREFIXES):
|
||||||
|
continue
|
||||||
|
|
||||||
|
has_value = bool(fields.get(full_name, ""))
|
||||||
|
current_f = int(annot.get("/F", 4))
|
||||||
|
# Remove hidden bit when value present, keep/set it when absent
|
||||||
|
new_f = (current_f & ~HIDDEN_BIT) if has_value else (current_f | HIDDEN_BIT)
|
||||||
|
if new_f != current_f:
|
||||||
|
annot[NameObject("/F")] = NumberObject(new_f)
|
||||||
|
|
||||||
|
|
||||||
def fill_pdf(
|
def fill_pdf(
|
||||||
attendance: MonthlyAttendance,
|
attendance: MonthlyAttendance,
|
||||||
template_path: str | Path,
|
template_path: str | Path,
|
||||||
@@ -113,6 +151,8 @@ def fill_pdf(
|
|||||||
for page in writer.pages:
|
for page in writer.pages:
|
||||||
writer.update_page_form_field_values(page, fields, auto_regenerate=False)
|
writer.update_page_form_field_values(page, fields, auto_regenerate=False)
|
||||||
|
|
||||||
|
_update_widget_visibility(writer, fields)
|
||||||
|
|
||||||
output_path.parent.mkdir(parents=True, exist_ok=True)
|
output_path.parent.mkdir(parents=True, exist_ok=True)
|
||||||
with output_path.open("wb") as fh:
|
with output_path.open("wb") as fh:
|
||||||
writer.write(fh)
|
writer.write(fh)
|
||||||
Reference in new issue
Block a user