pdfium_render/pdf/document/page/
field.rs1pub mod button;
5pub mod checkbox;
6pub mod combo;
7pub mod list;
8pub mod option;
9pub mod options;
10pub(crate) mod private; pub mod radio;
12pub mod signature;
13pub mod text;
14pub mod unknown;
15
16use crate::bindgen::{
17 FPDF_ANNOTATION, FPDF_FORMFIELD_CHECKBOX, FPDF_FORMFIELD_COMBOBOX, FPDF_FORMFIELD_LISTBOX,
18 FPDF_FORMFIELD_PUSHBUTTON, FPDF_FORMFIELD_RADIOBUTTON, FPDF_FORMFIELD_SIGNATURE,
19 FPDF_FORMFIELD_TEXTFIELD, FPDF_FORMFIELD_UNKNOWN, FPDF_FORMHANDLE,
20};
21use crate::bindings::PdfiumLibraryBindings;
22use crate::error::PdfiumError;
23use crate::pdf::appearance_mode::PdfAppearanceMode;
24use crate::pdf::document::page::field::button::PdfFormPushButtonField;
25use crate::pdf::document::page::field::checkbox::PdfFormCheckboxField;
26use crate::pdf::document::page::field::combo::PdfFormComboBoxField;
27use crate::pdf::document::page::field::list::PdfFormListBoxField;
28use crate::pdf::document::page::field::private::internal::{
29 PdfFormFieldFlags, PdfFormFieldPrivate,
30};
31use crate::pdf::document::page::field::radio::PdfFormRadioButtonField;
32use crate::pdf::document::page::field::signature::PdfFormSignatureField;
33use crate::pdf::document::page::field::text::PdfFormTextField;
34use crate::pdf::document::page::field::unknown::PdfFormUnknownField;
35use std::os::raw::c_int;
36
37#[cfg(doc)]
38use crate::pdf::document::form::PdfForm;
39
40#[derive(Debug, Copy, Clone, PartialOrd, PartialEq)]
42pub enum PdfFormFieldType {
43 Unknown = FPDF_FORMFIELD_UNKNOWN as isize,
46 PushButton = FPDF_FORMFIELD_PUSHBUTTON as isize,
47 Checkbox = FPDF_FORMFIELD_CHECKBOX as isize,
48 RadioButton = FPDF_FORMFIELD_RADIOBUTTON as isize,
49 ComboBox = FPDF_FORMFIELD_COMBOBOX as isize,
50 ListBox = FPDF_FORMFIELD_LISTBOX as isize,
51 Text = FPDF_FORMFIELD_TEXTFIELD as isize,
52 Signature = FPDF_FORMFIELD_SIGNATURE as isize,
53}
54
55impl PdfFormFieldType {
56 #[inline]
57 #[allow(dead_code)]
58 pub(crate) fn from_pdfium(value: c_int) -> Result<PdfFormFieldType, PdfiumError> {
59 match value as u32 {
60 FPDF_FORMFIELD_UNKNOWN => Ok(PdfFormFieldType::Unknown),
61 FPDF_FORMFIELD_PUSHBUTTON => Ok(PdfFormFieldType::PushButton),
62 FPDF_FORMFIELD_CHECKBOX => Ok(PdfFormFieldType::Checkbox),
63 FPDF_FORMFIELD_RADIOBUTTON => Ok(PdfFormFieldType::RadioButton),
64 FPDF_FORMFIELD_COMBOBOX => Ok(PdfFormFieldType::ComboBox),
65 FPDF_FORMFIELD_LISTBOX => Ok(PdfFormFieldType::ListBox),
66 FPDF_FORMFIELD_TEXTFIELD => Ok(PdfFormFieldType::Text),
67 FPDF_FORMFIELD_SIGNATURE => Ok(PdfFormFieldType::Signature),
68 _ => Err(PdfiumError::UnknownFormFieldType),
69 }
70 }
71
72 #[inline]
73 #[allow(dead_code)]
74 pub(crate) fn as_pdfium(&self) -> u32 {
76 match self {
77 PdfFormFieldType::Unknown => FPDF_FORMFIELD_UNKNOWN,
78 PdfFormFieldType::PushButton => FPDF_FORMFIELD_PUSHBUTTON,
79 PdfFormFieldType::Checkbox => FPDF_FORMFIELD_CHECKBOX,
80 PdfFormFieldType::RadioButton => FPDF_FORMFIELD_RADIOBUTTON,
81 PdfFormFieldType::ComboBox => FPDF_FORMFIELD_COMBOBOX,
82 PdfFormFieldType::ListBox => FPDF_FORMFIELD_LISTBOX,
83 PdfFormFieldType::Text => FPDF_FORMFIELD_TEXTFIELD,
84 PdfFormFieldType::Signature => FPDF_FORMFIELD_SIGNATURE,
85 }
86 }
87}
88
89pub enum PdfFormField<'a> {
91 PushButton(PdfFormPushButtonField<'a>),
92 Checkbox(PdfFormCheckboxField<'a>),
93 RadioButton(PdfFormRadioButtonField<'a>),
94 ComboBox(PdfFormComboBoxField<'a>),
95 ListBox(PdfFormListBoxField<'a>),
96 Signature(PdfFormSignatureField<'a>),
97 Text(PdfFormTextField<'a>),
98 Unknown(PdfFormUnknownField<'a>),
99}
100
101impl<'a> PdfFormField<'a> {
102 pub(crate) fn from_pdfium(
103 form_handle: FPDF_FORMHANDLE,
104 annotation_handle: FPDF_ANNOTATION,
105 bindings: &'a dyn PdfiumLibraryBindings,
106 ) -> Option<Self> {
107 let result = bindings.FPDFAnnot_GetFormFieldType(form_handle, annotation_handle);
108
109 if result == -1 {
110 return None;
111 }
112
113 let form_field_type =
114 PdfFormFieldType::from_pdfium(result).unwrap_or(PdfFormFieldType::Unknown);
115
116 Some(match form_field_type {
117 PdfFormFieldType::PushButton => PdfFormField::PushButton(
118 PdfFormPushButtonField::from_pdfium(form_handle, annotation_handle, bindings),
119 ),
120 PdfFormFieldType::Checkbox => PdfFormField::Checkbox(
121 PdfFormCheckboxField::from_pdfium(form_handle, annotation_handle, bindings),
122 ),
123 PdfFormFieldType::RadioButton => PdfFormField::RadioButton(
124 PdfFormRadioButtonField::from_pdfium(form_handle, annotation_handle, bindings),
125 ),
126 PdfFormFieldType::ComboBox => PdfFormField::ComboBox(
127 PdfFormComboBoxField::from_pdfium(form_handle, annotation_handle, bindings),
128 ),
129 PdfFormFieldType::ListBox => PdfFormField::ListBox(PdfFormListBoxField::from_pdfium(
130 form_handle,
131 annotation_handle,
132 bindings,
133 )),
134 PdfFormFieldType::Text => PdfFormField::Text(PdfFormTextField::from_pdfium(
135 form_handle,
136 annotation_handle,
137 bindings,
138 )),
139 PdfFormFieldType::Signature => PdfFormField::Signature(
140 PdfFormSignatureField::from_pdfium(form_handle, annotation_handle, bindings),
141 ),
142 _ => PdfFormField::Unknown(PdfFormUnknownField::from_pdfium(
143 form_handle,
144 annotation_handle,
145 bindings,
146 )),
147 })
148 }
149
150 #[inline]
151 pub(crate) fn unwrap_as_trait(&self) -> &dyn PdfFormFieldPrivate<'a> {
152 match self {
153 PdfFormField::PushButton(field) => field,
154 PdfFormField::Checkbox(field) => field,
155 PdfFormField::RadioButton(field) => field,
156 PdfFormField::ComboBox(field) => field,
157 PdfFormField::ListBox(field) => field,
158 PdfFormField::Signature(field) => field,
159 PdfFormField::Text(field) => field,
160 PdfFormField::Unknown(field) => field,
161 }
162 }
163
164 #[inline]
166 pub fn field_type(&self) -> PdfFormFieldType {
167 match self {
168 PdfFormField::PushButton(_) => PdfFormFieldType::PushButton,
169 PdfFormField::Checkbox(_) => PdfFormFieldType::Checkbox,
170 PdfFormField::RadioButton(_) => PdfFormFieldType::RadioButton,
171 PdfFormField::ComboBox(_) => PdfFormFieldType::ComboBox,
172 PdfFormField::ListBox(_) => PdfFormFieldType::ListBox,
173 PdfFormField::Signature(_) => PdfFormFieldType::Signature,
174 PdfFormField::Text(_) => PdfFormFieldType::Text,
175 PdfFormField::Unknown(_) => PdfFormFieldType::Unknown,
176 }
177 }
178
179 #[inline]
182 pub fn as_push_button_field(&self) -> Option<&PdfFormPushButtonField> {
183 match self {
184 PdfFormField::PushButton(field) => Some(field),
185 _ => None,
186 }
187 }
188
189 #[inline]
192 pub fn as_checkbox_field(&self) -> Option<&PdfFormCheckboxField> {
193 match self {
194 PdfFormField::Checkbox(field) => Some(field),
195 _ => None,
196 }
197 }
198
199 #[inline]
202 pub fn as_checkbox_field_mut(&mut self) -> Option<&mut PdfFormCheckboxField<'a>> {
203 match self {
204 PdfFormField::Checkbox(field) => Some(field),
205 _ => None,
206 }
207 }
208
209 #[inline]
212 pub fn as_radio_button_field(&self) -> Option<&PdfFormRadioButtonField> {
213 match self {
214 PdfFormField::RadioButton(field) => Some(field),
215 _ => None,
216 }
217 }
218
219 #[inline]
222 pub fn as_radio_button_field_mut(&mut self) -> Option<&mut PdfFormRadioButtonField<'a>> {
223 match self {
224 PdfFormField::RadioButton(field) => Some(field),
225 _ => None,
226 }
227 }
228
229 #[inline]
232 pub fn as_combo_box_field(&self) -> Option<&PdfFormComboBoxField> {
233 match self {
234 PdfFormField::ComboBox(field) => Some(field),
235 _ => None,
236 }
237 }
238
239 #[inline]
242 pub fn as_list_box_field(&self) -> Option<&PdfFormListBoxField> {
243 match self {
244 PdfFormField::ListBox(field) => Some(field),
245 _ => None,
246 }
247 }
248
249 #[inline]
252 pub fn as_signature_field(&self) -> Option<&PdfFormSignatureField> {
253 match self {
254 PdfFormField::Signature(field) => Some(field),
255 _ => None,
256 }
257 }
258
259 #[inline]
262 pub fn as_text_field(&self) -> Option<&PdfFormTextField> {
263 match self {
264 PdfFormField::Text(field) => Some(field),
265 _ => None,
266 }
267 }
268
269 pub fn as_text_field_mut(&mut self) -> Option<&mut PdfFormTextField<'a>> {
272 match self {
273 PdfFormField::Text(field) => Some(field),
274 _ => None,
275 }
276 }
277
278 #[inline]
281 pub fn as_unknown_field(&self) -> Option<&PdfFormUnknownField> {
282 match self {
283 PdfFormField::Unknown(field) => Some(field),
284 _ => None,
285 }
286 }
287}
288
289pub trait PdfFormFieldCommon {
291 fn name(&self) -> Option<String>;
293
294 fn appearance_stream(&self) -> Option<String>;
296
297 fn appearance_mode_value(&self, appearance_mode: PdfAppearanceMode) -> Option<String>;
300
301 fn is_read_only(&self) -> bool;
307
308 #[cfg(any(feature = "pdfium_future", feature = "pdfium_7350"))]
309 fn set_is_read_only(&mut self, is_read_only: bool) -> Result<(), PdfiumError>;
311
312 fn is_required(&self) -> bool;
318
319 #[cfg(any(feature = "pdfium_future", feature = "pdfium_7350"))]
320 fn set_is_required(&mut self, is_required: bool) -> Result<(), PdfiumError>;
326
327 fn is_exported_on_submit(&self) -> bool;
333
334 #[cfg(any(feature = "pdfium_future", feature = "pdfium_7350"))]
335 fn set_is_exported_on_submit(&mut self, is_exported: bool) -> Result<(), PdfiumError>;
341}
342
343impl<'a, T> PdfFormFieldCommon for T
346where
347 T: PdfFormFieldPrivate<'a>,
348{
349 #[inline]
350 fn name(&self) -> Option<String> {
351 self.name_impl()
352 }
353
354 #[inline]
355 fn appearance_stream(&self) -> Option<String> {
356 self.appearance_stream_impl()
357 }
358
359 #[inline]
360 fn appearance_mode_value(&self, appearance_mode: PdfAppearanceMode) -> Option<String> {
361 self.appearance_mode_value_impl(appearance_mode)
362 }
363
364 #[inline]
365 fn is_read_only(&self) -> bool {
366 self.get_flags_impl().contains(PdfFormFieldFlags::ReadOnly)
367 }
368
369 #[cfg(any(feature = "pdfium_future", feature = "pdfium_7350"))]
370 #[inline]
371 fn set_is_read_only(&mut self, is_read_only: bool) -> Result<(), PdfiumError> {
372 self.update_one_flag_impl(PdfFormFieldFlags::ReadOnly, is_read_only)
373 }
374
375 #[inline]
376 fn is_required(&self) -> bool {
377 self.get_flags_impl().contains(PdfFormFieldFlags::Required)
378 }
379
380 #[cfg(any(feature = "pdfium_future", feature = "pdfium_7350"))]
381 #[inline]
382 fn set_is_required(&mut self, is_required: bool) -> Result<(), PdfiumError> {
383 self.update_one_flag_impl(PdfFormFieldFlags::Required, is_required)
384 }
385
386 #[inline]
387 fn is_exported_on_submit(&self) -> bool {
388 !self.get_flags_impl().contains(PdfFormFieldFlags::NoExport)
389 }
390
391 #[cfg(any(feature = "pdfium_future", feature = "pdfium_7350"))]
392 #[inline]
393 fn set_is_exported_on_submit(&mut self, is_exported: bool) -> Result<(), PdfiumError> {
394 self.update_one_flag_impl(PdfFormFieldFlags::NoExport, !is_exported)
395 }
396}
397
398impl<'a> PdfFormFieldPrivate<'a> for PdfFormField<'a> {
399 #[inline]
400 fn form_handle(&self) -> FPDF_FORMHANDLE {
401 self.unwrap_as_trait().form_handle()
402 }
403
404 #[inline]
405 fn annotation_handle(&self) -> FPDF_ANNOTATION {
406 self.unwrap_as_trait().annotation_handle()
407 }
408
409 #[inline]
410 fn bindings(&self) -> &dyn PdfiumLibraryBindings {
411 self.unwrap_as_trait().bindings()
412 }
413}
414
415impl<'a> From<PdfFormPushButtonField<'a>> for PdfFormField<'a> {
416 #[inline]
417 fn from(field: PdfFormPushButtonField<'a>) -> Self {
418 Self::PushButton(field)
419 }
420}
421
422impl<'a> From<PdfFormCheckboxField<'a>> for PdfFormField<'a> {
423 #[inline]
424 fn from(field: PdfFormCheckboxField<'a>) -> Self {
425 Self::Checkbox(field)
426 }
427}
428
429impl<'a> From<PdfFormRadioButtonField<'a>> for PdfFormField<'a> {
430 #[inline]
431 fn from(field: PdfFormRadioButtonField<'a>) -> Self {
432 Self::RadioButton(field)
433 }
434}
435
436impl<'a> From<PdfFormComboBoxField<'a>> for PdfFormField<'a> {
437 #[inline]
438 fn from(field: PdfFormComboBoxField<'a>) -> Self {
439 Self::ComboBox(field)
440 }
441}
442
443impl<'a> From<PdfFormListBoxField<'a>> for PdfFormField<'a> {
444 #[inline]
445 fn from(field: PdfFormListBoxField<'a>) -> Self {
446 Self::ListBox(field)
447 }
448}
449
450impl<'a> From<PdfFormTextField<'a>> for PdfFormField<'a> {
451 #[inline]
452 fn from(field: PdfFormTextField<'a>) -> Self {
453 Self::Text(field)
454 }
455}
456
457impl<'a> From<PdfFormSignatureField<'a>> for PdfFormField<'a> {
458 #[inline]
459 fn from(field: PdfFormSignatureField<'a>) -> Self {
460 Self::Signature(field)
461 }
462}
463
464impl<'a> From<PdfFormUnknownField<'a>> for PdfFormField<'a> {
465 #[inline]
466 fn from(field: PdfFormUnknownField<'a>) -> Self {
467 Self::Unknown(field)
468 }
469}