PyPDFForm 3.3.0__tar.gz → 3.3.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of PyPDFForm might be problematic. Click here for more details.
- {pypdfform-3.3.0 → pypdfform-3.3.1}/PKG-INFO +1 -1
- {pypdfform-3.3.0 → pypdfform-3.3.1}/PyPDFForm/__init__.py +1 -1
- {pypdfform-3.3.0 → pypdfform-3.3.1}/PyPDFForm/constants.py +4 -0
- {pypdfform-3.3.0 → pypdfform-3.3.1}/PyPDFForm/hooks.py +16 -15
- {pypdfform-3.3.0 → pypdfform-3.3.1}/PyPDFForm/widgets/base.py +36 -0
- {pypdfform-3.3.0 → pypdfform-3.3.1}/PyPDFForm/widgets/checkbox.py +2 -1
- {pypdfform-3.3.0 → pypdfform-3.3.1}/PyPDFForm/widgets/text.py +2 -1
- {pypdfform-3.3.0 → pypdfform-3.3.1}/PyPDFForm.egg-info/PKG-INFO +1 -1
- {pypdfform-3.3.0 → pypdfform-3.3.1}/pyproject.toml +1 -1
- {pypdfform-3.3.0 → pypdfform-3.3.1}/LICENSE +0 -0
- {pypdfform-3.3.0 → pypdfform-3.3.1}/PyPDFForm/adapter.py +0 -0
- {pypdfform-3.3.0 → pypdfform-3.3.1}/PyPDFForm/coordinate.py +0 -0
- {pypdfform-3.3.0 → pypdfform-3.3.1}/PyPDFForm/filler.py +0 -0
- {pypdfform-3.3.0 → pypdfform-3.3.1}/PyPDFForm/font.py +0 -0
- {pypdfform-3.3.0 → pypdfform-3.3.1}/PyPDFForm/image.py +0 -0
- {pypdfform-3.3.0 → pypdfform-3.3.1}/PyPDFForm/middleware/__init__.py +0 -0
- {pypdfform-3.3.0 → pypdfform-3.3.1}/PyPDFForm/middleware/base.py +0 -0
- {pypdfform-3.3.0 → pypdfform-3.3.1}/PyPDFForm/middleware/checkbox.py +0 -0
- {pypdfform-3.3.0 → pypdfform-3.3.1}/PyPDFForm/middleware/dropdown.py +0 -0
- {pypdfform-3.3.0 → pypdfform-3.3.1}/PyPDFForm/middleware/image.py +0 -0
- {pypdfform-3.3.0 → pypdfform-3.3.1}/PyPDFForm/middleware/radio.py +0 -0
- {pypdfform-3.3.0 → pypdfform-3.3.1}/PyPDFForm/middleware/signature.py +0 -0
- {pypdfform-3.3.0 → pypdfform-3.3.1}/PyPDFForm/middleware/text.py +0 -0
- {pypdfform-3.3.0 → pypdfform-3.3.1}/PyPDFForm/patterns.py +0 -0
- {pypdfform-3.3.0 → pypdfform-3.3.1}/PyPDFForm/template.py +0 -0
- {pypdfform-3.3.0 → pypdfform-3.3.1}/PyPDFForm/utils.py +0 -0
- {pypdfform-3.3.0 → pypdfform-3.3.1}/PyPDFForm/watermark.py +0 -0
- {pypdfform-3.3.0 → pypdfform-3.3.1}/PyPDFForm/widgets/__init__.py +0 -0
- {pypdfform-3.3.0 → pypdfform-3.3.1}/PyPDFForm/widgets/bedrock.py +0 -0
- {pypdfform-3.3.0 → pypdfform-3.3.1}/PyPDFForm/widgets/dropdown.py +0 -0
- {pypdfform-3.3.0 → pypdfform-3.3.1}/PyPDFForm/widgets/image.py +0 -0
- {pypdfform-3.3.0 → pypdfform-3.3.1}/PyPDFForm/widgets/radio.py +0 -0
- {pypdfform-3.3.0 → pypdfform-3.3.1}/PyPDFForm/widgets/signature.py +0 -0
- {pypdfform-3.3.0 → pypdfform-3.3.1}/PyPDFForm/wrapper.py +0 -0
- {pypdfform-3.3.0 → pypdfform-3.3.1}/PyPDFForm.egg-info/SOURCES.txt +0 -0
- {pypdfform-3.3.0 → pypdfform-3.3.1}/PyPDFForm.egg-info/dependency_links.txt +0 -0
- {pypdfform-3.3.0 → pypdfform-3.3.1}/PyPDFForm.egg-info/requires.txt +0 -0
- {pypdfform-3.3.0 → pypdfform-3.3.1}/PyPDFForm.egg-info/top_level.txt +0 -0
- {pypdfform-3.3.0 → pypdfform-3.3.1}/README.md +0 -0
- {pypdfform-3.3.0 → pypdfform-3.3.1}/setup.cfg +0 -0
- {pypdfform-3.3.0 → pypdfform-3.3.1}/tests/test_adobe_mode.py +0 -0
- {pypdfform-3.3.0 → pypdfform-3.3.1}/tests/test_create_widget.py +0 -0
- {pypdfform-3.3.0 → pypdfform-3.3.1}/tests/test_dropdown.py +0 -0
- {pypdfform-3.3.0 → pypdfform-3.3.1}/tests/test_extract_values.py +0 -0
- {pypdfform-3.3.0 → pypdfform-3.3.1}/tests/test_fill_max_length_text_field.py +0 -0
- {pypdfform-3.3.0 → pypdfform-3.3.1}/tests/test_fill_method.py +0 -0
- {pypdfform-3.3.0 → pypdfform-3.3.1}/tests/test_functional.py +0 -0
- {pypdfform-3.3.0 → pypdfform-3.3.1}/tests/test_paragraph.py +0 -0
- {pypdfform-3.3.0 → pypdfform-3.3.1}/tests/test_signature.py +0 -0
- {pypdfform-3.3.0 → pypdfform-3.3.1}/tests/test_use_full_widget_name.py +0 -0
- {pypdfform-3.3.0 → pypdfform-3.3.1}/tests/test_widget_attr_trigger.py +0 -0
|
@@ -20,7 +20,7 @@ The library supports various PDF form features, including:
|
|
|
20
20
|
PyPDFForm aims to simplify PDF form manipulation, making it accessible to developers of all skill levels.
|
|
21
21
|
"""
|
|
22
22
|
|
|
23
|
-
__version__ = "3.3.
|
|
23
|
+
__version__ = "3.3.1"
|
|
24
24
|
|
|
25
25
|
from .middleware.text import Text # exposing for setting global font attrs
|
|
26
26
|
from .wrapper import PdfWrapper
|
|
@@ -99,6 +99,10 @@ REQUIRED = 1 << 1
|
|
|
99
99
|
MULTILINE = 1 << 12
|
|
100
100
|
COMB = 1 << 24
|
|
101
101
|
|
|
102
|
+
# reportlab acroform func
|
|
103
|
+
fieldFlags = "fieldFlags"
|
|
104
|
+
required = "required"
|
|
105
|
+
|
|
102
106
|
FONT_SIZE_IDENTIFIER = "Tf"
|
|
103
107
|
FONT_COLOR_IDENTIFIER = " rg"
|
|
104
108
|
DEFAULT_FONT = "Helvetica"
|
|
@@ -359,19 +359,20 @@ def update_field_required(annot: DictionaryObject, val: bool) -> None:
|
|
|
359
359
|
annot (DictionaryObject): The annotation dictionary for the form field.
|
|
360
360
|
val (bool): True to set the field as required, False to make it optional.
|
|
361
361
|
"""
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
)
|
|
362
|
+
# TODO: add a test case when supporting edit required
|
|
363
|
+
# if Parent in annot and Ff not in annot:
|
|
364
|
+
# annot[NameObject(Parent)][NameObject(Ff)] = NumberObject(
|
|
365
|
+
# (
|
|
366
|
+
# int(annot.get(NameObject(Ff), 0)) | REQUIRED
|
|
367
|
+
# if val
|
|
368
|
+
# else int(annot.get(NameObject(Ff), 0)) & ~REQUIRED
|
|
369
|
+
# )
|
|
370
|
+
# )
|
|
371
|
+
# else:
|
|
372
|
+
annot[NameObject(Ff)] = NumberObject(
|
|
373
|
+
(
|
|
374
|
+
int(annot.get(NameObject(Ff), 0)) | REQUIRED
|
|
375
|
+
if val
|
|
376
|
+
else int(annot.get(NameObject(Ff), 0)) & ~REQUIRED
|
|
377
377
|
)
|
|
378
|
+
)
|
|
@@ -10,6 +10,7 @@ for rendering the widget on a PDF page.
|
|
|
10
10
|
# TODO: In `watermarks`, `PdfReader(stream_to_io(stream))` is called, which re-parses the PDF for each widget. If multiple widgets are being processed, consider passing the `PdfReader` object directly to avoid redundant parsing.
|
|
11
11
|
# TODO: In `watermarks`, the list comprehension `[watermark.read() if i == self.page_number - 1 else b"" for i in range(page_count)]` creates a new `BytesIO` object and reads from it for each widget. If many widgets are created, this could be optimized by creating the `BytesIO` object once and passing it around, or by directly returning the watermark bytes and its page number.
|
|
12
12
|
|
|
13
|
+
from inspect import signature
|
|
13
14
|
from io import BytesIO
|
|
14
15
|
from typing import List, Union
|
|
15
16
|
|
|
@@ -17,6 +18,7 @@ from pypdf import PdfReader
|
|
|
17
18
|
from reportlab.lib.colors import Color
|
|
18
19
|
from reportlab.pdfgen.canvas import Canvas
|
|
19
20
|
|
|
21
|
+
from ..constants import fieldFlags, required
|
|
20
22
|
from ..utils import stream_to_io
|
|
21
23
|
|
|
22
24
|
|
|
@@ -95,6 +97,39 @@ class Widget:
|
|
|
95
97
|
if each in kwargs:
|
|
96
98
|
self.hook_params.append((each, kwargs.get(each)))
|
|
97
99
|
|
|
100
|
+
def _required_handler(self, canvas: Canvas) -> None:
|
|
101
|
+
"""
|
|
102
|
+
Handles the 'Required' flag for the widget's AcroForm field.
|
|
103
|
+
|
|
104
|
+
This method inspects the default flags of the AcroForm function associated
|
|
105
|
+
with the widget and modifies them based on the widget's 'required' parameter.
|
|
106
|
+
If the widget is marked as required, the 'required' flag is added to the
|
|
107
|
+
AcroForm field flags; otherwise, it is removed. This ensures the PDF form
|
|
108
|
+
field's required status is correctly reflected.
|
|
109
|
+
|
|
110
|
+
Args:
|
|
111
|
+
canvas (Canvas): The ReportLab canvas object used for PDF operations.
|
|
112
|
+
"""
|
|
113
|
+
default_flags = signature(
|
|
114
|
+
getattr(canvas.acroForm, self.ACRO_FORM_FUNC)
|
|
115
|
+
).parameters.get(fieldFlags)
|
|
116
|
+
default_flags = (
|
|
117
|
+
default_flags.default.split(" ")
|
|
118
|
+
if default_flags and default_flags.default
|
|
119
|
+
else []
|
|
120
|
+
)
|
|
121
|
+
|
|
122
|
+
if self.acro_form_params.get(required):
|
|
123
|
+
default_flags.append(required)
|
|
124
|
+
else:
|
|
125
|
+
if required in default_flags:
|
|
126
|
+
default_flags.remove(required)
|
|
127
|
+
|
|
128
|
+
default_flags = " ".join(list(set(default_flags)))
|
|
129
|
+
self.acro_form_params[fieldFlags] = default_flags
|
|
130
|
+
if required in self.acro_form_params:
|
|
131
|
+
del self.acro_form_params[required]
|
|
132
|
+
|
|
98
133
|
def canvas_operations(self, canvas: Canvas) -> None:
|
|
99
134
|
"""
|
|
100
135
|
Performs canvas operations for the widget.
|
|
@@ -141,6 +176,7 @@ class Widget:
|
|
|
141
176
|
),
|
|
142
177
|
)
|
|
143
178
|
|
|
179
|
+
self._required_handler(canvas)
|
|
144
180
|
self.canvas_operations(canvas)
|
|
145
181
|
|
|
146
182
|
canvas.showPage()
|
|
@@ -25,6 +25,7 @@ class CheckBoxWidget(Widget):
|
|
|
25
25
|
"""
|
|
26
26
|
|
|
27
27
|
USER_PARAMS = [
|
|
28
|
+
("required", "required"),
|
|
28
29
|
("tooltip", "tooltip"),
|
|
29
30
|
("button_style", "buttonStyle"),
|
|
30
31
|
("tick_color", "textColor"),
|
|
@@ -33,5 +34,5 @@ class CheckBoxWidget(Widget):
|
|
|
33
34
|
("border_width", "borderWidth"),
|
|
34
35
|
]
|
|
35
36
|
COLOR_PARAMS = ["tick_color", "bg_color", "border_color"]
|
|
36
|
-
ALLOWED_HOOK_PARAMS = ["
|
|
37
|
+
ALLOWED_HOOK_PARAMS = ["size"]
|
|
37
38
|
ACRO_FORM_FUNC = "checkbox"
|
|
@@ -27,6 +27,7 @@ class TextWidget(Widget):
|
|
|
27
27
|
"""
|
|
28
28
|
|
|
29
29
|
USER_PARAMS = [
|
|
30
|
+
("required", "required"),
|
|
30
31
|
("tooltip", "tooltip"),
|
|
31
32
|
("width", "width"),
|
|
32
33
|
("height", "height"),
|
|
@@ -38,6 +39,6 @@ class TextWidget(Widget):
|
|
|
38
39
|
("max_length", "maxlen"),
|
|
39
40
|
]
|
|
40
41
|
COLOR_PARAMS = ["font_color", "bg_color", "border_color"]
|
|
41
|
-
ALLOWED_HOOK_PARAMS = ["
|
|
42
|
+
ALLOWED_HOOK_PARAMS = ["alignment", "multiline", "comb", "font"]
|
|
42
43
|
NONE_DEFAULTS = ["max_length"]
|
|
43
44
|
ACRO_FORM_FUNC = "textfield"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|