pdfium_render/pdf/document/page/field/combo.rs
1//! Defines the [PdfFormComboBoxField] struct, exposing functionality related to a single
2//! form field of type [PdfFormFieldType::ComboBox].
3
4use crate::bindgen::{FPDF_ANNOTATION, FPDF_FORMHANDLE};
5use crate::bindings::PdfiumLibraryBindings;
6use crate::pdf::document::page::field::options::PdfFormFieldOptions;
7use crate::pdf::document::page::field::private::internal::{
8 PdfFormFieldFlags, PdfFormFieldPrivate,
9};
10
11#[cfg(any(feature = "pdfium_future", feature = "pdfium_7350"))]
12use crate::error::PdfiumError;
13
14#[cfg(doc)]
15use {
16 crate::pdf::document::form::PdfForm,
17 crate::pdf::document::page::annotation::PdfPageAnnotationType,
18 crate::pdf::document::page::field::{PdfFormField, PdfFormFieldType},
19};
20
21/// A single [PdfFormField] of type [PdfFormFieldType::ComboBox]. The form field object defines
22/// an interactive drop-down list widget that allows the user to either select a value
23/// from a list of options or type a value into a text field.
24///
25/// Form fields in Pdfium are wrapped inside page annotations of type [PdfPageAnnotationType::Widget]
26/// or [PdfPageAnnotationType::XfaWidget]. User-specified values can be retrieved directly from
27/// each form field object by unwrapping the form field from the annotation, or in bulk from the
28/// [PdfForm::field_values()] function.
29pub struct PdfFormComboBoxField<'a> {
30 form_handle: FPDF_FORMHANDLE,
31 annotation_handle: FPDF_ANNOTATION,
32 options: PdfFormFieldOptions<'a>,
33 bindings: &'a dyn PdfiumLibraryBindings,
34}
35
36impl<'a> PdfFormComboBoxField<'a> {
37 #[inline]
38 pub(crate) fn from_pdfium(
39 form_handle: FPDF_FORMHANDLE,
40 annotation_handle: FPDF_ANNOTATION,
41 bindings: &'a dyn PdfiumLibraryBindings,
42 ) -> Self {
43 PdfFormComboBoxField {
44 form_handle,
45 annotation_handle,
46 options: PdfFormFieldOptions::from_pdfium(form_handle, annotation_handle, bindings),
47 bindings,
48 }
49 }
50
51 /// Returns the [PdfiumLibraryBindings] used by this [PdfFormComboBoxField] object.
52 #[inline]
53 pub fn bindings(&self) -> &'a dyn PdfiumLibraryBindings {
54 self.bindings
55 }
56
57 /// Returns the collection of selectable options in this [PdfFormComboBoxField].
58 pub fn options(&self) -> &PdfFormFieldOptions {
59 &self.options
60 }
61
62 /// Returns the displayed label for the currently selected option in this [PdfFormComboBoxField] object, if any.
63 #[inline]
64 pub fn value(&self) -> Option<String> {
65 self.options()
66 .iter()
67 .find(|option| option.is_set())
68 .and_then(|option| option.label().cloned())
69 }
70
71 /// Returns `true` if this [PdfFormComboBoxField] also includes an editable text box.
72 /// If `false`, this combo box field only includes a drop-down list.
73 #[inline]
74 pub fn has_editable_text_box(&self) -> bool {
75 self.get_flags_impl()
76 .contains(PdfFormFieldFlags::ChoiceEdit)
77 }
78
79 #[cfg(any(feature = "pdfium_future", feature = "pdfium_7350"))]
80 /// Controls whether or not this [PdfFormComboBoxField] includes an editable text box
81 /// in addition to a drop-down list.
82 #[inline]
83 pub fn set_has_editable_text_box(
84 &mut self,
85 has_editable_text_box: bool,
86 ) -> Result<(), PdfiumError> {
87 self.update_one_flag_impl(PdfFormFieldFlags::ChoiceEdit, has_editable_text_box)
88 }
89
90 /// Returns `true` if the option items of this [PdfFormComboBoxField] should be sorted
91 /// alphabetically.
92 ///
93 /// This flag is intended for use by form authoring tools, not by PDF viewer applications.
94 #[inline]
95 pub fn is_sorted(&self) -> bool {
96 self.get_flags_impl()
97 .contains(PdfFormFieldFlags::ChoiceSort)
98 }
99
100 #[cfg(any(feature = "pdfium_future", feature = "pdfium_7350"))]
101 /// Controls whether or not the option items of this [PdfFormComboBoxField] should be
102 /// sorted alphabetically.
103 ///
104 /// This flag is intended for use by form authoring tools, not by PDF viewer applications.
105 #[inline]
106 pub fn set_is_sorted(&mut self, is_sorted: bool) -> Result<(), PdfiumError> {
107 self.update_one_flag_impl(PdfFormFieldFlags::ChoiceSort, is_sorted)
108 }
109
110 /// Returns `true` if more than one of the option items in this [PdfFormComboBoxField]
111 /// may be selected simultaneously. If `false`, only one item at a time may be selected.
112 ///
113 /// This flag was added in PDF version 1.4.
114 pub fn is_multiselect(&self) -> bool {
115 self.get_flags_impl()
116 .contains(PdfFormFieldFlags::ChoiceMultiSelect)
117 }
118
119 #[cfg(any(feature = "pdfium_future", feature = "pdfium_7350"))]
120 /// Controls whether more than one of the option items in this [PdfFormComboBoxField]
121 /// may be selected simultaneously.
122 ///
123 /// This flag was added in PDF version 1.4.
124 pub fn set_is_multiselect(&mut self, is_multiselect: bool) -> Result<(), PdfiumError> {
125 self.update_one_flag_impl(PdfFormFieldFlags::ChoiceMultiSelect, is_multiselect)
126 }
127
128 /// Returns `true` if text entered into the editable text box included in this
129 /// [PdfFormComboBoxField] should be spell checked.
130 ///
131 /// This flag is meaningful only if the [PdfFormComboBoxField::has_editable_text_box()]
132 /// flag is also `true`.
133 ///
134 /// This flag was added in PDF version 1.4.
135 pub fn is_spell_checked(&self) -> bool {
136 !self
137 .get_flags_impl()
138 .contains(PdfFormFieldFlags::TextDoNotSpellCheck)
139 }
140
141 #[cfg(any(feature = "pdfium_future", feature = "pdfium_7350"))]
142 /// Controls whether or not text entered into the editable text box included in this
143 /// [PdfFormComboBoxField] should be spell checked.
144 ///
145 /// This flag was added in PDF version 1.4.
146 pub fn set_is_spell_checked(&mut self, is_spell_checked: bool) -> Result<(), PdfiumError> {
147 self.update_one_flag_impl(PdfFormFieldFlags::TextDoNotSpellCheck, !is_spell_checked)
148 }
149
150 /// Returns `true` if any new value is committed to this [PdfFormComboBoxField]
151 /// as soon as a selection is made with the pointing device. This option enables
152 /// applications to perform an action once a selection is made, without requiring
153 /// the user to exit the field. If `false`, any new value is not committed until the
154 /// user exits the field.
155 ///
156 /// This flag was added in PDF version 1.5.
157 pub fn is_commit_on_selection_change(&self) -> bool {
158 self.get_flags_impl()
159 .contains(PdfFormFieldFlags::ChoiceCommitOnSelectionChange)
160 }
161
162 #[cfg(any(feature = "pdfium_future", feature = "pdfium_7350"))]
163 /// Controls whether or not any new value is committed to this [PdfFormComboBoxField]
164 /// as soon as a selection is made with the pointing device.
165 ///
166 /// This flag was added in PDF version 1.5.
167 pub fn set_is_commit_on_selection_change(
168 &mut self,
169 is_commit_on_selection_change: bool,
170 ) -> Result<(), PdfiumError> {
171 self.update_one_flag_impl(
172 PdfFormFieldFlags::ChoiceCommitOnSelectionChange,
173 is_commit_on_selection_change,
174 )
175 }
176}
177
178impl<'a> PdfFormFieldPrivate<'a> for PdfFormComboBoxField<'a> {
179 #[inline]
180 fn form_handle(&self) -> FPDF_FORMHANDLE {
181 self.form_handle
182 }
183
184 #[inline]
185 fn annotation_handle(&self) -> FPDF_ANNOTATION {
186 self.annotation_handle
187 }
188
189 #[inline]
190 fn bindings(&self) -> &dyn PdfiumLibraryBindings {
191 self.bindings
192 }
193}