1 // Copyright 2016 PDFium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6 
7 #ifndef CORE_FPDFDOC_CPDF_FORMFIELD_H_
8 #define CORE_FPDFDOC_CPDF_FORMFIELD_H_
9 
10 #include <memory>
11 #include <utility>
12 #include <vector>
13 
14 #include "core/fpdfdoc/cpdf_aaction.h"
15 #include "core/fxcrt/fx_string.h"
16 #include "core/fxcrt/fx_system.h"
17 #include "core/fxcrt/retain_ptr.h"
18 #include "core/fxcrt/unowned_ptr.h"
19 
20 class CPDF_Dictionary;
21 class CPDF_Font;
22 class CPDF_FormControl;
23 class CPDF_InteractiveForm;
24 class CPDF_Object;
25 class CPDF_String;
26 
27 enum class NotificationOption { kDoNotNotify = 0, kNotify };
28 
29 enum class FormFieldType : uint8_t {
30   kUnknown = 0,
31   kPushButton = 1,
32   kCheckBox = 2,
33   kRadioButton = 3,
34   kComboBox = 4,
35   kListBox = 5,
36   kTextField = 6,
37   kSignature = 7,
38 #ifdef PDF_ENABLE_XFA
39   kXFA = 8,  // Generic XFA field, should use value below if possible.
40   kXFA_CheckBox = 9,
41   kXFA_ComboBox = 10,
42   kXFA_ImageField = 11,
43   kXFA_ListBox = 12,
44   kXFA_PushButton = 13,
45   kXFA_Signature = 14,
46   kXFA_TextField = 15
47 #endif  // PDF_ENABLE_XFA
48 };
49 
50 // If values are added to FormFieldType, these will need to be updated.
51 #ifdef PDF_ENABLE_XFA
52 constexpr size_t kFormFieldTypeCount = 16;
53 #else   // PDF_ENABLE_XFA
54 constexpr size_t kFormFieldTypeCount = 8;
55 #endif  // PDF_ENABLE_XFA
56 
57 class CPDF_FormField {
58  public:
59   enum Type {
60     kUnknown,
61     kPushButton,
62     kRadioButton,
63     kCheckBox,
64     kText,
65     kRichText,
66     kFile,
67     kListBox,
68     kComboBox,
69     kSign
70   };
71 
72   CPDF_FormField(CPDF_InteractiveForm* pForm, CPDF_Dictionary* pDict);
73   ~CPDF_FormField();
74 
75   static Optional<FormFieldType> IntToFormFieldType(int value);
76 
77   static const CPDF_Object* GetFieldAttr(const CPDF_Dictionary* pFieldDict,
78                                          const ByteString& name);
79   static CPDF_Object* GetFieldAttr(CPDF_Dictionary* pFieldDict,
80                                    const ByteString& name);
81 
82   static WideString GetFullNameForDict(CPDF_Dictionary* pFieldDict);
83 
84   WideString GetFullName() const;
GetType()85   Type GetType() const { return m_Type; }
86 
GetFieldDict()87   CPDF_Dictionary* GetFieldDict() const { return m_pDict.Get(); }
88   bool ResetField(NotificationOption notify);
89 
90   int CountControls() const;
91   CPDF_FormControl* GetControl(int index) const;
92   int GetControlIndex(const CPDF_FormControl* pControl) const;
93 
94   FormFieldType GetFieldType() const;
95 
96   CPDF_AAction GetAdditionalAction() const;
97   WideString GetAlternateName() const;
98   WideString GetMappingName() const;
99 
100   uint32_t GetFieldFlags() const;
101   ByteString GetDefaultStyle() const;
102 
IsRequired()103   bool IsRequired() const { return m_bRequired; }
IsNoExport()104   bool IsNoExport() const { return m_bNoExport; }
105 
106   WideString GetValue() const;
107   WideString GetDefaultValue() const;
108   bool SetValue(const WideString& value, NotificationOption notify);
109 
110   int GetMaxLen() const;
111   int CountSelectedItems() const;
112   int GetSelectedIndex(int index) const;
113 
114   bool ClearSelection(NotificationOption notify);
115   bool IsItemSelected(int index) const;
116   bool SetItemSelection(int index, bool bSelected, NotificationOption notify);
117 
118   bool IsItemDefaultSelected(int index) const;
119 
120   int GetDefaultSelectedItem() const;
121   int CountOptions() const;
122   WideString GetOptionLabel(int index) const;
123   WideString GetOptionValue(int index) const;
124   int FindOption(const WideString& csOptValue) const;
125 
126   bool CheckControl(int iControlIndex,
127                     bool bChecked,
128                     NotificationOption notify);
129 
130   int GetTopVisibleIndex() const;
131   int CountSelectedOptions() const;
132   int GetSelectedOptionIndex(int index) const;
133   bool IsOptionSelected(int iOptIndex) const;
134   bool SelectOption(int iOptIndex, bool bSelected, NotificationOption notify);
135 
GetFontSize()136   float GetFontSize() const { return m_FontSize; }
GetFont()137   CPDF_Font* GetFont() const { return m_pFont.Get(); }
138 
GetDict()139   CPDF_Dictionary* GetDict() const { return m_pDict.Get(); }
GetForm()140   CPDF_InteractiveForm* GetForm() const { return m_pForm.Get(); }
141 
142   WideString GetCheckValue(bool bDefault) const;
143 
144   void SetOpt(RetainPtr<CPDF_Object> pOpt);
145 
146  private:
147   WideString GetValue(bool bDefault) const;
148   bool SetValue(const WideString& value,
149                 bool bDefault,
150                 NotificationOption notify);
151   void InitFieldFlags();
152   int FindListSel(CPDF_String* str);
153   WideString GetOptionText(int index, int sub_index) const;
154   void LoadDA();
155   bool SetCheckValue(const WideString& value,
156                      bool bDefault,
157                      NotificationOption notify);
158   void SetItemSelectionSelected(int index, const WideString& opt_value);
159   void SetItemSelectionUnselected(int index, const WideString& opt_value);
160   bool NotifyBeforeSelectionChange(const WideString& value);
161   void NotifyAfterSelectionChange();
162   bool NotifyBeforeValueChange(const WideString& value);
163   void NotifyAfterValueChange();
164   bool NotifyListOrComboBoxBeforeChange(const WideString& value);
165   void NotifyListOrComboBoxAfterChange();
166 
167   const CPDF_Object* GetDefaultValueObject() const;
168   const CPDF_Object* GetValueObject() const;
169 
170   // For choice fields.
171   const CPDF_Object* GetSelectedIndicesObject() const;
172 
173   // For choice fields.
174   // Value object takes precedence over selected indices object.
175   const CPDF_Object* GetValueOrSelectedIndicesObject() const;
176 
177   const std::vector<UnownedPtr<CPDF_FormControl>>& GetControls() const;
178 
179   CPDF_FormField::Type m_Type = kUnknown;
180   bool m_bRequired = false;
181   bool m_bNoExport = false;
182   bool m_bIsMultiSelectListBox = false;
183   bool m_bIsUnison = false;
184   float m_FontSize = 0;
185   UnownedPtr<CPDF_InteractiveForm> const m_pForm;
186   RetainPtr<CPDF_Dictionary> const m_pDict;
187   RetainPtr<CPDF_Font> m_pFont;
188 };
189 
190 #endif  // CORE_FPDFDOC_CPDF_FORMFIELD_H_
191