pub mod button;
pub mod checkbox;
pub mod combo;
pub mod list;
pub mod option;
pub mod options;
pub(crate) mod private; pub mod radio;
pub mod signature;
pub mod text;
pub mod unknown;
use crate::bindgen::{
FPDF_ANNOTATION, FPDF_FORMFIELD_CHECKBOX, FPDF_FORMFIELD_COMBOBOX, FPDF_FORMFIELD_LISTBOX,
FPDF_FORMFIELD_PUSHBUTTON, FPDF_FORMFIELD_RADIOBUTTON, FPDF_FORMFIELD_SIGNATURE,
FPDF_FORMFIELD_TEXTFIELD, FPDF_FORMFIELD_UNKNOWN, FPDF_FORMHANDLE,
};
use crate::bindings::PdfiumLibraryBindings;
use crate::error::PdfiumError;
use crate::pdf::appearance_mode::PdfAppearanceMode;
use crate::pdf::document::page::field::button::PdfFormPushButtonField;
use crate::pdf::document::page::field::checkbox::PdfFormCheckboxField;
use crate::pdf::document::page::field::combo::PdfFormComboBoxField;
use crate::pdf::document::page::field::list::PdfFormListBoxField;
use crate::pdf::document::page::field::private::internal::{
PdfFormFieldFlags, PdfFormFieldPrivate,
};
use crate::pdf::document::page::field::radio::PdfFormRadioButtonField;
use crate::pdf::document::page::field::signature::PdfFormSignatureField;
use crate::pdf::document::page::field::text::PdfFormTextField;
use crate::pdf::document::page::field::unknown::PdfFormUnknownField;
use crate::pdfium::PdfiumLibraryBindingsAccessor;
use std::os::raw::c_int;
#[cfg(doc)]
use crate::pdf::document::form::PdfForm;
#[derive(Debug, Copy, Clone, PartialOrd, PartialEq)]
pub enum PdfFormFieldType {
Unknown = FPDF_FORMFIELD_UNKNOWN as isize,
PushButton = FPDF_FORMFIELD_PUSHBUTTON as isize,
Checkbox = FPDF_FORMFIELD_CHECKBOX as isize,
RadioButton = FPDF_FORMFIELD_RADIOBUTTON as isize,
ComboBox = FPDF_FORMFIELD_COMBOBOX as isize,
ListBox = FPDF_FORMFIELD_LISTBOX as isize,
Text = FPDF_FORMFIELD_TEXTFIELD as isize,
Signature = FPDF_FORMFIELD_SIGNATURE as isize,
}
impl PdfFormFieldType {
#[inline]
#[allow(dead_code)]
pub(crate) fn from_pdfium(value: c_int) -> Result<PdfFormFieldType, PdfiumError> {
match value as u32 {
FPDF_FORMFIELD_UNKNOWN => Ok(PdfFormFieldType::Unknown),
FPDF_FORMFIELD_PUSHBUTTON => Ok(PdfFormFieldType::PushButton),
FPDF_FORMFIELD_CHECKBOX => Ok(PdfFormFieldType::Checkbox),
FPDF_FORMFIELD_RADIOBUTTON => Ok(PdfFormFieldType::RadioButton),
FPDF_FORMFIELD_COMBOBOX => Ok(PdfFormFieldType::ComboBox),
FPDF_FORMFIELD_LISTBOX => Ok(PdfFormFieldType::ListBox),
FPDF_FORMFIELD_TEXTFIELD => Ok(PdfFormFieldType::Text),
FPDF_FORMFIELD_SIGNATURE => Ok(PdfFormFieldType::Signature),
_ => Err(PdfiumError::UnknownFormFieldType),
}
}
#[inline]
#[allow(dead_code)]
pub(crate) fn as_pdfium(&self) -> u32 {
match self {
PdfFormFieldType::Unknown => FPDF_FORMFIELD_UNKNOWN,
PdfFormFieldType::PushButton => FPDF_FORMFIELD_PUSHBUTTON,
PdfFormFieldType::Checkbox => FPDF_FORMFIELD_CHECKBOX,
PdfFormFieldType::RadioButton => FPDF_FORMFIELD_RADIOBUTTON,
PdfFormFieldType::ComboBox => FPDF_FORMFIELD_COMBOBOX,
PdfFormFieldType::ListBox => FPDF_FORMFIELD_LISTBOX,
PdfFormFieldType::Text => FPDF_FORMFIELD_TEXTFIELD,
PdfFormFieldType::Signature => FPDF_FORMFIELD_SIGNATURE,
}
}
}
pub enum PdfFormField<'a> {
PushButton(PdfFormPushButtonField<'a>),
Checkbox(PdfFormCheckboxField<'a>),
RadioButton(PdfFormRadioButtonField<'a>),
ComboBox(PdfFormComboBoxField<'a>),
ListBox(PdfFormListBoxField<'a>),
Signature(PdfFormSignatureField<'a>),
Text(PdfFormTextField<'a>),
Unknown(PdfFormUnknownField<'a>),
}
impl<'a> PdfFormField<'a> {
pub(crate) fn from_pdfium(
form_handle: FPDF_FORMHANDLE,
annotation_handle: FPDF_ANNOTATION,
bindings: &'a dyn PdfiumLibraryBindings,
) -> Option<Self> {
let result = unsafe { bindings.FPDFAnnot_GetFormFieldType(form_handle, annotation_handle) };
if result == -1 {
return None;
}
let form_field_type =
PdfFormFieldType::from_pdfium(result).unwrap_or(PdfFormFieldType::Unknown);
Some(match form_field_type {
PdfFormFieldType::PushButton => PdfFormField::PushButton(
PdfFormPushButtonField::from_pdfium(form_handle, annotation_handle),
),
PdfFormFieldType::Checkbox => PdfFormField::Checkbox(
PdfFormCheckboxField::from_pdfium(form_handle, annotation_handle),
),
PdfFormFieldType::RadioButton => PdfFormField::RadioButton(
PdfFormRadioButtonField::from_pdfium(form_handle, annotation_handle),
),
PdfFormFieldType::ComboBox => PdfFormField::ComboBox(
PdfFormComboBoxField::from_pdfium(form_handle, annotation_handle),
),
PdfFormFieldType::ListBox => PdfFormField::ListBox(PdfFormListBoxField::from_pdfium(
form_handle,
annotation_handle,
)),
PdfFormFieldType::Text => PdfFormField::Text(PdfFormTextField::from_pdfium(
form_handle,
annotation_handle,
)),
PdfFormFieldType::Signature => PdfFormField::Signature(
PdfFormSignatureField::from_pdfium(form_handle, annotation_handle),
),
_ => PdfFormField::Unknown(PdfFormUnknownField::from_pdfium(
form_handle,
annotation_handle,
)),
})
}
#[inline]
pub(crate) fn unwrap_as_trait(&self) -> &dyn PdfFormFieldPrivate<'a> {
match self {
PdfFormField::PushButton(field) => field,
PdfFormField::Checkbox(field) => field,
PdfFormField::RadioButton(field) => field,
PdfFormField::ComboBox(field) => field,
PdfFormField::ListBox(field) => field,
PdfFormField::Signature(field) => field,
PdfFormField::Text(field) => field,
PdfFormField::Unknown(field) => field,
}
}
#[inline]
pub fn field_type(&self) -> PdfFormFieldType {
match self {
PdfFormField::PushButton(_) => PdfFormFieldType::PushButton,
PdfFormField::Checkbox(_) => PdfFormFieldType::Checkbox,
PdfFormField::RadioButton(_) => PdfFormFieldType::RadioButton,
PdfFormField::ComboBox(_) => PdfFormFieldType::ComboBox,
PdfFormField::ListBox(_) => PdfFormFieldType::ListBox,
PdfFormField::Signature(_) => PdfFormFieldType::Signature,
PdfFormField::Text(_) => PdfFormFieldType::Text,
PdfFormField::Unknown(_) => PdfFormFieldType::Unknown,
}
}
#[inline]
pub fn as_push_button_field(&self) -> Option<&PdfFormPushButtonField<'_>> {
match self {
PdfFormField::PushButton(field) => Some(field),
_ => None,
}
}
#[inline]
pub fn as_checkbox_field(&self) -> Option<&PdfFormCheckboxField<'_>> {
match self {
PdfFormField::Checkbox(field) => Some(field),
_ => None,
}
}
#[inline]
pub fn as_checkbox_field_mut(&mut self) -> Option<&mut PdfFormCheckboxField<'a>> {
match self {
PdfFormField::Checkbox(field) => Some(field),
_ => None,
}
}
#[inline]
pub fn as_radio_button_field(&self) -> Option<&PdfFormRadioButtonField<'_>> {
match self {
PdfFormField::RadioButton(field) => Some(field),
_ => None,
}
}
#[inline]
pub fn as_radio_button_field_mut(&mut self) -> Option<&mut PdfFormRadioButtonField<'a>> {
match self {
PdfFormField::RadioButton(field) => Some(field),
_ => None,
}
}
#[inline]
pub fn as_combo_box_field(&self) -> Option<&PdfFormComboBoxField<'_>> {
match self {
PdfFormField::ComboBox(field) => Some(field),
_ => None,
}
}
#[inline]
pub fn as_list_box_field(&self) -> Option<&PdfFormListBoxField<'_>> {
match self {
PdfFormField::ListBox(field) => Some(field),
_ => None,
}
}
#[inline]
pub fn as_signature_field(&self) -> Option<&PdfFormSignatureField<'_>> {
match self {
PdfFormField::Signature(field) => Some(field),
_ => None,
}
}
#[inline]
pub fn as_text_field(&self) -> Option<&PdfFormTextField<'_>> {
match self {
PdfFormField::Text(field) => Some(field),
_ => None,
}
}
pub fn as_text_field_mut(&mut self) -> Option<&mut PdfFormTextField<'a>> {
match self {
PdfFormField::Text(field) => Some(field),
_ => None,
}
}
#[inline]
pub fn as_unknown_field(&self) -> Option<&PdfFormUnknownField<'_>> {
match self {
PdfFormField::Unknown(field) => Some(field),
_ => None,
}
}
}
pub trait PdfFormFieldCommon {
fn name(&self) -> Option<String>;
fn appearance_stream(&self) -> Option<String>;
fn appearance_mode_value(&self, appearance_mode: PdfAppearanceMode) -> Option<String>;
fn is_read_only(&self) -> bool;
#[cfg(any(feature = "pdfium_future", feature = "pdfium_7350"))]
fn set_is_read_only(&mut self, is_read_only: bool) -> Result<(), PdfiumError>;
fn is_required(&self) -> bool;
#[cfg(any(feature = "pdfium_future", feature = "pdfium_7350"))]
fn set_is_required(&mut self, is_required: bool) -> Result<(), PdfiumError>;
fn is_exported_on_submit(&self) -> bool;
#[cfg(any(feature = "pdfium_future", feature = "pdfium_7350"))]
fn set_is_exported_on_submit(&mut self, is_exported: bool) -> Result<(), PdfiumError>;
}
impl<'a, T> PdfFormFieldCommon for T
where
T: PdfFormFieldPrivate<'a>,
{
#[inline]
fn name(&self) -> Option<String> {
self.name_impl()
}
#[inline]
fn appearance_stream(&self) -> Option<String> {
self.appearance_stream_impl()
}
#[inline]
fn appearance_mode_value(&self, appearance_mode: PdfAppearanceMode) -> Option<String> {
self.appearance_mode_value_impl(appearance_mode)
}
#[inline]
fn is_read_only(&self) -> bool {
self.get_flags_impl().contains(PdfFormFieldFlags::ReadOnly)
}
#[cfg(any(feature = "pdfium_future", feature = "pdfium_7350"))]
#[inline]
fn set_is_read_only(&mut self, is_read_only: bool) -> Result<(), PdfiumError> {
self.update_one_flag_impl(PdfFormFieldFlags::ReadOnly, is_read_only)
}
#[inline]
fn is_required(&self) -> bool {
self.get_flags_impl().contains(PdfFormFieldFlags::Required)
}
#[cfg(any(feature = "pdfium_future", feature = "pdfium_7350"))]
#[inline]
fn set_is_required(&mut self, is_required: bool) -> Result<(), PdfiumError> {
self.update_one_flag_impl(PdfFormFieldFlags::Required, is_required)
}
#[inline]
fn is_exported_on_submit(&self) -> bool {
!self.get_flags_impl().contains(PdfFormFieldFlags::NoExport)
}
#[cfg(any(feature = "pdfium_future", feature = "pdfium_7350"))]
#[inline]
fn set_is_exported_on_submit(&mut self, is_exported: bool) -> Result<(), PdfiumError> {
self.update_one_flag_impl(PdfFormFieldFlags::NoExport, !is_exported)
}
}
impl<'a> PdfFormFieldPrivate<'a> for PdfFormField<'a> {
#[inline]
fn form_handle(&self) -> FPDF_FORMHANDLE {
self.unwrap_as_trait().form_handle()
}
#[inline]
fn annotation_handle(&self) -> FPDF_ANNOTATION {
self.unwrap_as_trait().annotation_handle()
}
}
impl<'a> PdfiumLibraryBindingsAccessor<'a> for PdfFormField<'a> {}
#[cfg(feature = "thread_safe")]
unsafe impl<'a> Send for PdfFormField<'a> {}
#[cfg(feature = "thread_safe")]
unsafe impl<'a> Sync for PdfFormField<'a> {}
impl<'a> From<PdfFormPushButtonField<'a>> for PdfFormField<'a> {
#[inline]
fn from(field: PdfFormPushButtonField<'a>) -> Self {
Self::PushButton(field)
}
}
impl<'a> From<PdfFormCheckboxField<'a>> for PdfFormField<'a> {
#[inline]
fn from(field: PdfFormCheckboxField<'a>) -> Self {
Self::Checkbox(field)
}
}
impl<'a> From<PdfFormRadioButtonField<'a>> for PdfFormField<'a> {
#[inline]
fn from(field: PdfFormRadioButtonField<'a>) -> Self {
Self::RadioButton(field)
}
}
impl<'a> From<PdfFormComboBoxField<'a>> for PdfFormField<'a> {
#[inline]
fn from(field: PdfFormComboBoxField<'a>) -> Self {
Self::ComboBox(field)
}
}
impl<'a> From<PdfFormListBoxField<'a>> for PdfFormField<'a> {
#[inline]
fn from(field: PdfFormListBoxField<'a>) -> Self {
Self::ListBox(field)
}
}
impl<'a> From<PdfFormTextField<'a>> for PdfFormField<'a> {
#[inline]
fn from(field: PdfFormTextField<'a>) -> Self {
Self::Text(field)
}
}
impl<'a> From<PdfFormSignatureField<'a>> for PdfFormField<'a> {
#[inline]
fn from(field: PdfFormSignatureField<'a>) -> Self {
Self::Signature(field)
}
}
impl<'a> From<PdfFormUnknownField<'a>> for PdfFormField<'a> {
#[inline]
fn from(field: PdfFormUnknownField<'a>) -> Self {
Self::Unknown(field)
}
}