File Coverage

blib/lib/PDF/Make/Field.pm
Criterion Covered Total %
statement 106 107 99.0
branch 21 22 95.4
condition 8 8 100.0
subroutine 39 40 97.5
pod 33 33 100.0
total 207 210 98.5


line stmt bran cond sub pod time code
1             package PDF::Make::Field;
2              
3 3     3   13 use strict;
  3         4  
  3         74  
4 3     3   8 use warnings;
  3         15  
  3         196  
5 3     3   11 no warnings qw(redefine prototype); # XS methods are overridden by Perl wrappers
  3         3  
  3         77  
6 3     3   8 use PDF::Make;
  3         4  
  3         77  
7 3     3   9 use PDF::Make::Form;
  3         4  
  3         2956  
8              
9             =head1 NAME
10              
11             PDF::Make::Field - PDF form field for PDF::Make
12              
13             =head1 SYNOPSIS
14              
15             use PDF::Make;
16            
17             my $pdf = PDF::Make->new();
18             my $page = $pdf->add_page(width => 612, height => 792);
19             my $form = $pdf->create_form();
20            
21             # Create and configure a text field
22             my $field = $form->add_text_field(
23             name => 'name',
24             x => 100,
25             y => 700,
26             width => 200,
27             height => 20,
28             );
29            
30             # Set properties
31             $field->set_value('John Doe');
32             $field->readonly(1);
33             $field->align_center();
34            
35             # Add to page
36             $field->add_to_page($page);
37              
38             =head1 DESCRIPTION
39              
40             This class represents a PDF form field. Fields are created via the
41             L methods like C, C, etc.
42              
43             =head1 METHODS
44              
45             =cut
46              
47             # Constructor - internal use only
48             sub _wrap {
49 84     84   110 my ($class, $field, $form) = @_;
50 84         296 return bless {
51             _field => $field,
52             _form => $form,
53             }, $class;
54             }
55              
56             =head2 type
57              
58             my $type = $field->type();
59              
60             Return the field type as a string: 'text', 'button', 'choice', or 'signature'.
61              
62             =cut
63              
64             sub type {
65 6     6 1 2732 return $_[0]->{_field}->type();
66             }
67              
68             =head2 name
69              
70             my $name = $field->name();
71              
72             Return the partial field name.
73              
74             =cut
75              
76             sub name {
77 7     7 1 546 return $_[0]->{_field}->name();
78             }
79              
80             =head2 full_name
81              
82             my $full_name = $field->full_name();
83              
84             Return the full field name (includes parent hierarchy).
85              
86             =cut
87              
88             sub full_name {
89 1     1 1 8 return $_[0]->{_field}->full_name();
90             }
91              
92             =head2 value
93              
94             my $value = $field->value();
95             $field->value('new value');
96              
97             Get or set the field value.
98              
99             =cut
100              
101             sub value {
102 17     17 1 44 my ($self, $val) = @_;
103 17 100       35 if (@_ > 1) {
104 2         10 $self->{_field}->value($val);
105 2         5 return $self;
106             }
107 15         71 return $self->{_field}->value();
108             }
109              
110             =head2 set_value
111              
112             $field->set_value('value');
113              
114             Set the field value.
115              
116             =cut
117              
118             sub set_value {
119 19     19 1 2865 my ($self, $val) = @_;
120 19         73 $self->{_field}->set_value($val);
121 19         30 return $self;
122             }
123              
124             =head2 set_default_value
125              
126             $field->set_default_value('default');
127              
128             Set the default value (used when form is reset).
129              
130             =cut
131              
132             sub set_default_value {
133 1     1 1 5 my ($self, $val) = @_;
134 1         5 $self->{_field}->set_default_value($val);
135 1         1 return $self;
136             }
137              
138             =head2 flags
139              
140             my $flags = $field->flags();
141              
142             Return the field flags as an integer.
143              
144             =cut
145              
146             sub flags {
147 7     7 1 36 return $_[0]->{_field}->flags();
148             }
149              
150             =head2 set_flags
151              
152             $field->set_flags($flags);
153              
154             Set the field flags (replaces existing).
155              
156             =cut
157              
158             sub set_flags {
159 1     1 1 319 my ($self, $flags) = @_;
160 1         14 $self->{_field}->set_flags($flags);
161 1         35 return $self;
162             }
163              
164             =head2 add_flags
165              
166             $field->add_flags($flags);
167              
168             Add flags to the existing set.
169              
170             =cut
171              
172             sub add_flags {
173 2     2 1 5 my ($self, $flags) = @_;
174 2         8 $self->{_field}->add_flags($flags);
175 2         3 return $self;
176             }
177              
178             =head2 clear_flags
179              
180             $field->clear_flags($flags);
181              
182             Clear specific flags.
183              
184             =cut
185              
186             sub clear_flags {
187 1     1 1 3 my ($self, $flags) = @_;
188 1         5 $self->{_field}->clear_flags($flags);
189 1         1 return $self;
190             }
191              
192             =head2 readonly
193              
194             $field->readonly(1); # Make read-only
195             $field->readonly(0); # Make editable
196             my $ro = $field->readonly(); # Alias for is_readonly
197              
198             Set or check the read-only flag.
199              
200             =cut
201              
202             sub readonly {
203 5     5 1 15 my ($self, $val) = @_;
204 5 100       14 if (@_ > 1) {
205 4 100       34 $self->{_field}->readonly($val ? 1 : 0);
206 4         18 return $self;
207             }
208 1         19 return $self->{_field}->is_readonly();
209             }
210              
211             =head2 is_readonly
212              
213             if ($field->is_readonly()) { ... }
214              
215             Check if field is read-only.
216              
217             =cut
218              
219             sub is_readonly {
220 3     3 1 21 return $_[0]->{_field}->is_readonly();
221             }
222              
223             =head2 required
224              
225             $field->required(1); # Mark as required
226             $field->required(0); # Mark as optional
227             my $req = $field->required(); # Alias for is_required
228              
229             Set or check the required flag.
230              
231             =cut
232              
233             sub required {
234 3     3 1 11 my ($self, $val) = @_;
235 3 100       9 if (@_ > 1) {
236 2 50       11 $self->{_field}->required($val ? 1 : 0);
237 2         5 return $self;
238             }
239 1         17 return $self->{_field}->is_required();
240             }
241              
242             =head2 is_required
243              
244             if ($field->is_required()) { ... }
245              
246             Check if field is required.
247              
248             =cut
249              
250             sub is_required {
251 2     2 1 13 return $_[0]->{_field}->is_required();
252             }
253              
254             =head2 noexport
255              
256             $field->noexport(1);
257              
258             Set the no-export flag (field value not included in FDF export).
259              
260             =cut
261              
262             sub noexport {
263 2     2 1 11 my ($self, $val) = @_;
264 2 100       10 $self->{_field}->noexport($val ? 1 : 0);
265 2         5 return $self;
266             }
267              
268             =head2 multiline
269              
270             $field->multiline(1);
271              
272             Enable multiline text input (text fields only).
273              
274             =cut
275              
276             sub multiline {
277 2     2 1 7 my ($self, $val) = @_;
278 2 100       13 $self->{_field}->multiline($val ? 1 : 0);
279 2         4 return $self;
280             }
281              
282             =head2 password
283              
284             $field->password(1);
285              
286             Enable password masking (text fields only).
287              
288             =cut
289              
290             sub password {
291 2     2 1 6 my ($self, $val) = @_;
292 2 100       10 $self->{_field}->password($val ? 1 : 0);
293 2         4 return $self;
294             }
295              
296             =head2 set_da
297              
298             $field->set_da('/Helv 12 Tf 0 g');
299              
300             Set the default appearance string (font, size, color).
301              
302             =cut
303              
304             sub set_da {
305 1     1 1 5 my ($self, $da) = @_;
306 1         4 $self->{_field}->set_da($da);
307 1         2 return $self;
308             }
309              
310             =head2 set_quadding
311              
312             $field->set_quadding(0); # Left
313             $field->set_quadding(1); # Center
314             $field->set_quadding(2); # Right
315              
316             Set text alignment.
317              
318             =cut
319              
320             sub set_quadding {
321 1     1 1 4 my ($self, $q) = @_;
322 1         3 $self->{_field}->set_quadding($q);
323 1         2 return $self;
324             }
325              
326             =head2 align_left
327              
328             $field->align_left();
329              
330             Set left text alignment.
331              
332             =cut
333              
334             sub align_left {
335 1     1 1 7 $_[0]->{_field}->align_left();
336 1         2 return $_[0];
337             }
338              
339             =head2 align_center
340              
341             $field->align_center();
342              
343             Set center text alignment.
344              
345             =cut
346              
347             sub align_center {
348 2     2 1 23 $_[0]->{_field}->align_center();
349 2         5 return $_[0];
350             }
351              
352             =head2 align_right
353              
354             $field->align_right();
355              
356             Set right text alignment.
357              
358             =cut
359              
360             sub align_right {
361 1     1 1 5 $_[0]->{_field}->align_right();
362 1         1 return $_[0];
363             }
364              
365             =head2 set_max_len
366              
367             $field->set_max_len(100);
368              
369             Set maximum character length (text fields only).
370              
371             =cut
372              
373             sub set_max_len {
374 1     1 1 2 my ($self, $len) = @_;
375 1         4 $self->{_field}->set_max_len($len);
376 1         3 return $self;
377             }
378              
379             =head2 add_option
380              
381             $field->add_option('Display Text');
382             $field->add_option('Display Text', 'export_value');
383              
384             Add an option to a choice field.
385              
386             =cut
387              
388             sub add_option {
389 7     7 1 22 my ($self, $display, $export) = @_;
390 7 100       10 if (defined $export) {
391 3         7 $self->{_field}->add_option($display, $export);
392             } else {
393 4         8 $self->{_field}->add_option($display);
394             }
395 7         7 return $self;
396             }
397              
398             =head2 option_count
399              
400             my $count = $field->option_count();
401              
402             Return the number of options (choice fields only).
403              
404             =cut
405              
406             sub option_count {
407 2     2 1 14 return $_[0]->{_field}->option_count();
408             }
409              
410             =head2 options
411              
412             my @opts = $field->options();
413              
414             Return all options as a list of hashrefs with 'display' and 'export' keys.
415              
416             =cut
417              
418             sub options {
419 1     1 1 10 return $_[0]->{_field}->options();
420             }
421              
422             =head2 add_radio_option
423              
424             $group->add_radio_option(
425             x => 100,
426             y => 500,
427             width => 15,
428             height => 15,
429             value => 'Option1',
430             );
431              
432             Add a radio button option to a radio group. Returns the option field.
433              
434             =cut
435              
436             sub add_radio_option {
437 10     10 1 57 my ($self, %opts) = @_;
438            
439 10   100     24 my $x = delete $opts{x} // 0;
440 10   100     19 my $y = delete $opts{y} // 0;
441 10   100     20 my $width = delete $opts{width} // 15;
442 10   100     21 my $height = delete $opts{height} // 15;
443 10 100       39 my $value = delete $opts{value} or die "add_radio_option: value required";
444            
445 9         45 my $option = $self->{_field}->add_radio_option($x, $y, $width, $height, $value);
446            
447 9         19 return PDF::Make::Field->_wrap($option, $self->{_form});
448             }
449              
450             =head2 add_to_page
451              
452             $field->add_to_page($page);
453              
454             Add the field's widget annotation to a page. This makes the field visible.
455              
456             =cut
457              
458             sub add_to_page {
459 43     43 1 997 my ($self, $page) = @_;
460            
461             # Page is already the raw pdfmake_page_t pointer
462 43         175 $self->{_field}->add_to_page($page);
463 43         139 return $self;
464             }
465              
466             =head2 generate_appearance
467              
468             $field->generate_appearance();
469              
470             Generate the appearance stream for this field.
471              
472             =cut
473              
474             sub generate_appearance {
475 1     1 1 20 $_[0]->{_field}->generate_appearance();
476 1         2 return $_[0];
477             }
478              
479             =head2 flatten
480              
481             $field->flatten();
482              
483             Flatten this field: render its value into page content and remove it.
484              
485             =cut
486              
487             sub flatten {
488 1     1 1 17 $_[0]->{_field}->flatten();
489 1         2 return $_[0];
490             }
491              
492             =head2 parent
493              
494             my $parent = $field->parent();
495              
496             Return the parent field (for hierarchical fields).
497              
498             =cut
499              
500             sub parent {
501 2     2 1 857 my $p = $_[0]->{_field}->parent();
502 2 100       6 return unless $p;
503 1         4 return PDF::Make::Field->_wrap($p, $_[0]->{_form});
504             }
505              
506             =head2 children
507              
508             my @children = $field->children();
509              
510             Return child fields (for hierarchical fields).
511              
512             =cut
513              
514             sub children {
515 2     2 1 4 my ($self) = @_;
516 5         11 return map { PDF::Make::Field->_wrap($_, $self->{_form}) }
517 2         17 $self->{_field}->children();
518             }
519              
520             =head2 has_children
521              
522             if ($field->has_children()) { ... }
523              
524             Check if field has children.
525              
526             =cut
527              
528             sub has_children {
529 2     2 1 15 return $_[0]->{_field}->has_children();
530             }
531              
532             # Internal: get raw field pointer
533             sub _field {
534 0     0     return $_[0]->{_field};
535             }
536              
537             1;
538              
539             __END__