1 // Copyright 2014 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 FPDFSDK_INCLUDE_FSDK_BASEFORM_H_
8 #define FPDFSDK_INCLUDE_FSDK_BASEFORM_H_
9 
10 #include <map>
11 #include <vector>
12 
13 #include "core/fpdfdoc/include/fpdf_doc.h"
14 #include "core/fxcrt/include/fx_basic.h"
15 #include "core/fxge/include/fx_dib.h"
16 #include "fpdfsdk/include/fsdk_baseannot.h"
17 
18 #if _FX_OS_ == _FX_ANDROID_
19 #include "time.h"
20 #else
21 #include <ctime>
22 #endif
23 
24 class CPDFSDK_Annot;
25 class CPDFSDK_Document;
26 class CPDFSDK_InterForm;
27 class CPDFSDK_PageView;
28 class CPDF_Action;
29 class CPDF_FormField;
30 struct CPWL_Color;
31 
32 #ifdef PDF_ENABLE_XFA
33 class CXFA_FFWidgetHandler;
34 
35 typedef enum _PDFSDK_XFAAActionType {
36   PDFSDK_XFA_Click = 0,
37   PDFSDK_XFA_Full,
38   PDFSDK_XFA_PreOpen,
39   PDFSDK_XFA_PostOpen
40 } PDFSDK_XFAAActionType;
41 #endif  // PDF_ENABLE_XFA
42 
43 struct PDFSDK_FieldAction {
44   PDFSDK_FieldAction();
45   PDFSDK_FieldAction(const PDFSDK_FieldAction& other) = delete;
46 
47   FX_BOOL bModifier;         // in
48   FX_BOOL bShift;            // in
49   int nCommitKey;            // in
50   CFX_WideString sChange;    // in[out]
51   CFX_WideString sChangeEx;  // in
52   FX_BOOL bKeyDown;          // in
53   int nSelEnd;               // in[out]
54   int nSelStart;             // in[out]
55   CFX_WideString sValue;     // in[out]
56   FX_BOOL bWillCommit;       // in
57   FX_BOOL bFieldFull;        // in
58   FX_BOOL bRC;               // in[out]
59 };
60 
61 class CPDFSDK_Widget : public CPDFSDK_BAAnnot {
62  public:
63 #ifdef PDF_ENABLE_XFA
64   CXFA_FFWidget* GetMixXFAWidget() const;
65   CXFA_FFWidget* GetGroupMixXFAWidget();
66   CXFA_FFWidgetHandler* GetXFAWidgetHandler() const;
67 
68   FX_BOOL HasXFAAAction(PDFSDK_XFAAActionType eXFAAAT);
69   FX_BOOL OnXFAAAction(PDFSDK_XFAAActionType eXFAAAT,
70                        PDFSDK_FieldAction& data,
71                        CPDFSDK_PageView* pPageView);
72 
73   void Synchronize(FX_BOOL bSynchronizeElse);
74   void SynchronizeXFAValue();
75   void SynchronizeXFAItems();
76 
77   static void SynchronizeXFAValue(CXFA_FFDocView* pXFADocView,
78                                   CXFA_FFWidget* hWidget,
79                                   CPDF_FormField* pFormField,
80                                   CPDF_FormControl* pFormControl);
81   static void SynchronizeXFAItems(CXFA_FFDocView* pXFADocView,
82                                   CXFA_FFWidget* hWidget,
83                                   CPDF_FormField* pFormField,
84                                   CPDF_FormControl* pFormControl);
85 #endif  // PDF_ENABLE_XFA
86 
87   CPDFSDK_Widget(CPDF_Annot* pAnnot,
88                  CPDFSDK_PageView* pPageView,
89                  CPDFSDK_InterForm* pInterForm);
90   ~CPDFSDK_Widget() override;
91 
92   // CPDFSDK_Annot
93   CFX_ByteString GetSubType() const override;
94   CPDF_Action GetAAction(CPDF_AAction::AActionType eAAT) override;
95   FX_BOOL IsAppearanceValid() override;
96 
97   int GetLayoutOrder() const override;
98 
99   int GetFieldType() const;
100 
101   // Possible values from PDF 32000-1:2008, table 221.
102   // FIELDFLAG_READONLY
103   // FIELDFLAG_REQUIRED
104   // FIELDFLAG_NOEXPORT
105   int GetFieldFlags() const;
106   int GetRotate() const;
107 
108   FX_BOOL GetFillColor(FX_COLORREF& color) const;
109   FX_BOOL GetBorderColor(FX_COLORREF& color) const;
110   FX_BOOL GetTextColor(FX_COLORREF& color) const;
111   FX_FLOAT GetFontSize() const;
112 
113   int GetSelectedIndex(int nIndex) const;
114 #ifndef PDF_ENABLE_XFA
115   CFX_WideString GetValue() const;
116 #else
117   CFX_WideString GetValue(FX_BOOL bDisplay = TRUE) const;
118 #endif  // PDF_ENABLE_XFA
119   CFX_WideString GetDefaultValue() const;
120   CFX_WideString GetOptionLabel(int nIndex) const;
121   int CountOptions() const;
122   FX_BOOL IsOptionSelected(int nIndex) const;
123   int GetTopVisibleIndex() const;
124   bool IsChecked() const;
125   /*
126   BF_ALIGN_LEFT
127   BF_ALIGN_MIDDL
128   BF_ALIGN_RIGHT
129   */
130   int GetAlignment() const;
131   int GetMaxLen() const;
132 #ifdef PDF_ENABLE_XFA
133   CFX_WideString GetName() const;
134 #endif  // PDF_ENABLE_XFA
135   CFX_WideString GetAlternateName() const;
136 
137   // Set Properties.
138   void SetCheck(bool bChecked, bool bNotify);
139   void SetValue(const CFX_WideString& sValue, FX_BOOL bNotify);
140   void SetDefaultValue(const CFX_WideString& sValue);
141   void SetOptionSelection(int index, FX_BOOL bSelected, FX_BOOL bNotify);
142   void ClearSelection(FX_BOOL bNotify);
143   void SetTopVisibleIndex(int index);
144 
145 #ifdef PDF_ENABLE_XFA
146   void ResetAppearance(FX_BOOL bValueChanged);
147 #endif  // PDF_ENABLE_XFA
148   void ResetAppearance(const FX_WCHAR* sValue, FX_BOOL bValueChanged);
149   void ResetFieldAppearance(FX_BOOL bValueChanged);
150   void UpdateField();
151   CFX_WideString OnFormat(FX_BOOL& bFormated);
152 
153   // Message.
154   FX_BOOL OnAAction(CPDF_AAction::AActionType type,
155                     PDFSDK_FieldAction& data,
156                     CPDFSDK_PageView* pPageView);
157 
GetInterForm()158   CPDFSDK_InterForm* GetInterForm() const { return m_pInterForm; }
159   CPDF_FormField* GetFormField() const;
160   CPDF_FormControl* GetFormControl() const;
161   static CPDF_FormControl* GetFormControl(CPDF_InterForm* pInterForm,
162                                           const CPDF_Dictionary* pAnnotDict);
163 
164   void DrawShadow(CFX_RenderDevice* pDevice, CPDFSDK_PageView* pPageView);
165 
166   void SetAppModified();
167   void ClearAppModified();
168   FX_BOOL IsAppModified() const;
169 
170   int32_t GetAppearanceAge() const;
171   int32_t GetValueAge() const;
172 
173  private:
174   void ResetAppearance_PushButton();
175   void ResetAppearance_CheckBox();
176   void ResetAppearance_RadioButton();
177   void ResetAppearance_ComboBox(const FX_WCHAR* sValue);
178   void ResetAppearance_ListBox();
179   void ResetAppearance_TextField(const FX_WCHAR* sValue);
180 
181   CFX_FloatRect GetClientRect() const;
182   CFX_FloatRect GetRotatedRect() const;
183 
184   CFX_ByteString GetBackgroundAppStream() const;
185   CFX_ByteString GetBorderAppStream() const;
186   CFX_Matrix GetMatrix() const;
187 
188   CPWL_Color GetTextPWLColor() const;
189   CPWL_Color GetBorderPWLColor() const;
190   CPWL_Color GetFillPWLColor() const;
191 
192   void AddImageToAppearance(const CFX_ByteString& sAPType, CPDF_Stream* pImage);
193   void RemoveAppearance(const CFX_ByteString& sAPType);
194 
195  public:
196   FX_BOOL IsWidgetAppearanceValid(CPDF_Annot::AppearanceMode mode);
197   void DrawAppearance(CFX_RenderDevice* pDevice,
198                       const CFX_Matrix* pUser2Device,
199                       CPDF_Annot::AppearanceMode mode,
200                       const CPDF_RenderOptions* pOptions) override;
201 
202   FX_BOOL HitTest(FX_FLOAT pageX, FX_FLOAT pageY);
203 
204  private:
205   CPDFSDK_InterForm* const m_pInterForm;
206   FX_BOOL m_bAppModified;
207   int32_t m_nAppAge;
208   int32_t m_nValueAge;
209 
210 #ifdef PDF_ENABLE_XFA
211   mutable CXFA_FFWidget* m_hMixXFAWidget;
212   mutable CXFA_FFWidgetHandler* m_pWidgetHandler;
213 #endif  // PDF_ENABLE_XFA
214 };
215 
216 #ifdef PDF_ENABLE_XFA
217 class CPDFSDK_XFAWidget : public CPDFSDK_Annot {
218  public:
219   CPDFSDK_XFAWidget(CXFA_FFWidget* pAnnot,
220                     CPDFSDK_PageView* pPageView,
221                     CPDFSDK_InterForm* pInterForm);
~CPDFSDK_XFAWidget()222   ~CPDFSDK_XFAWidget() override {}
223 
224   FX_BOOL IsXFAField() override;
225   CXFA_FFWidget* GetXFAWidget() const override;
226   CFX_ByteString GetType() const override;
227   CFX_ByteString GetSubType() const override;
228   CFX_FloatRect GetRect() const override;
229 
GetInterForm()230   CPDFSDK_InterForm* GetInterForm() { return m_pInterForm; }
231 
232  private:
233   CPDFSDK_InterForm* m_pInterForm;
234   CXFA_FFWidget* m_hXFAWidget;
235 };
236 #endif  // PDF_ENABLE_XFA
237 
238 class CPDFSDK_InterForm : public IPDF_FormNotify {
239  public:
240   explicit CPDFSDK_InterForm(CPDFSDK_Document* pDocument);
241   ~CPDFSDK_InterForm() override;
242 
GetInterForm()243   CPDF_InterForm* GetInterForm() const { return m_pInterForm.get(); }
GetDocument()244   CPDFSDK_Document* GetDocument() const { return m_pDocument; }
245 
246   FX_BOOL HighlightWidgets();
247 
248   CPDFSDK_Widget* GetSibling(CPDFSDK_Widget* pWidget, FX_BOOL bNext) const;
249   CPDFSDK_Widget* GetWidget(CPDF_FormControl* pControl) const;
250   void GetWidgets(const CFX_WideString& sFieldName,
251                   std::vector<CPDFSDK_Widget*>* widgets) const;
252   void GetWidgets(CPDF_FormField* pField,
253                   std::vector<CPDFSDK_Widget*>* widgets) const;
254 
255   void AddMap(CPDF_FormControl* pControl, CPDFSDK_Widget* pWidget);
256   void RemoveMap(CPDF_FormControl* pControl);
257 
258   void EnableCalculate(FX_BOOL bEnabled);
259   FX_BOOL IsCalculateEnabled() const;
260 
261 #ifdef PDF_ENABLE_XFA
262   void AddXFAMap(CXFA_FFWidget* hWidget, CPDFSDK_XFAWidget* pWidget);
263   void RemoveXFAMap(CXFA_FFWidget* hWidget);
264   CPDFSDK_XFAWidget* GetXFAWidget(CXFA_FFWidget* hWidget);
265   void XfaEnableCalculate(FX_BOOL bEnabled);
266   FX_BOOL IsXfaCalculateEnabled() const;
267   FX_BOOL IsXfaValidationsEnabled();
268   void XfaSetValidationsEnabled(FX_BOOL bEnabled);
269 #endif  // PDF_ENABLE_XFA
270 
271   FX_BOOL OnKeyStrokeCommit(CPDF_FormField* pFormField,
272                             const CFX_WideString& csValue);
273   FX_BOOL OnValidate(CPDF_FormField* pFormField, const CFX_WideString& csValue);
274   void OnCalculate(CPDF_FormField* pFormField = nullptr);
275   CFX_WideString OnFormat(CPDF_FormField* pFormField, FX_BOOL& bFormated);
276 
277   void ResetFieldAppearance(CPDF_FormField* pFormField,
278                             const FX_WCHAR* sValue,
279                             FX_BOOL bValueChanged);
280   void UpdateField(CPDF_FormField* pFormField);
281 
282   FX_BOOL DoAction_Hide(const CPDF_Action& action);
283   FX_BOOL DoAction_SubmitForm(const CPDF_Action& action);
284   FX_BOOL DoAction_ResetForm(const CPDF_Action& action);
285   FX_BOOL DoAction_ImportData(const CPDF_Action& action);
286 
287   std::vector<CPDF_FormField*> GetFieldFromObjects(
288       const std::vector<CPDF_Object*>& objects) const;
289   FX_BOOL IsValidField(CPDF_Dictionary* pFieldDict);
290   FX_BOOL SubmitFields(const CFX_WideString& csDestination,
291                        const std::vector<CPDF_FormField*>& fields,
292                        bool bIncludeOrExclude,
293                        bool bUrlEncoded);
294   FX_BOOL SubmitForm(const CFX_WideString& sDestination, FX_BOOL bUrlEncoded);
295   FX_BOOL ExportFormToFDFTextBuf(CFX_ByteTextBuf& textBuf);
296   FX_BOOL ExportFieldsToFDFTextBuf(const std::vector<CPDF_FormField*>& fields,
297                                    bool bIncludeOrExclude,
298                                    CFX_ByteTextBuf& textBuf);
299   CFX_WideString GetTemporaryFileName(const CFX_WideString& sFileExt);
300 
301 #ifdef PDF_ENABLE_XFA
302   void SynchronizeField(CPDF_FormField* pFormField, FX_BOOL bSynchronizeElse);
303 #endif  // PDF_ENABLE_XFA
304 
305  private:
306   // IPDF_FormNotify:
307   int BeforeValueChange(CPDF_FormField* pField,
308                         const CFX_WideString& csValue) override;
309   void AfterValueChange(CPDF_FormField* pField) override;
310   int BeforeSelectionChange(CPDF_FormField* pField,
311                             const CFX_WideString& csValue) override;
312   void AfterSelectionChange(CPDF_FormField* pField) override;
313   void AfterCheckedStatusChange(CPDF_FormField* pField) override;
314   int BeforeFormReset(CPDF_InterForm* pForm) override;
315   void AfterFormReset(CPDF_InterForm* pForm) override;
316   int BeforeFormImportData(CPDF_InterForm* pForm) override;
317   void AfterFormImportData(CPDF_InterForm* pForm) override;
318 
319   FX_BOOL FDFToURLEncodedData(CFX_WideString csFDFFile,
320                               CFX_WideString csTxtFile);
321   FX_BOOL FDFToURLEncodedData(uint8_t*& pBuf, FX_STRSIZE& nBufSize);
322   int GetPageIndexByAnnotDict(CPDF_Document* pDocument,
323                               CPDF_Dictionary* pAnnotDict) const;
324 
325   using CPDFSDK_WidgetMap = std::map<CPDF_FormControl*, CPDFSDK_Widget*>;
326 
327   CPDFSDK_Document* m_pDocument;
328   std::unique_ptr<CPDF_InterForm> m_pInterForm;
329   CPDFSDK_WidgetMap m_Map;
330 #ifdef PDF_ENABLE_XFA
331   std::map<CXFA_FFWidget*, CPDFSDK_XFAWidget*> m_XFAMap;
332   FX_BOOL m_bXfaCalculate;
333   FX_BOOL m_bXfaValidationsEnabled;
334 #endif  // PDF_ENABLE_XFA
335   FX_BOOL m_bCalculate;
336   FX_BOOL m_bBusy;
337 
338  public:
339   FX_BOOL IsNeedHighLight(int nFieldType);
340   void RemoveAllHighLight();
SetHighlightAlpha(uint8_t alpha)341   void SetHighlightAlpha(uint8_t alpha) { m_iHighlightAlpha = alpha; }
GetHighlightAlpha()342   uint8_t GetHighlightAlpha() { return m_iHighlightAlpha; }
343   void SetHighlightColor(FX_COLORREF clr, int nFieldType);
344   FX_COLORREF GetHighlightColor(int nFieldType);
345 
346  private:
347 #ifndef PDF_ENABLE_XFA
348   static const int kNumFieldTypes = 6;
349 #else   // PDF_ENABLE_XFA
350   static const int kNumFieldTypes = 7;
351 #endif  // PDF_ENABLE_XFA
352 
353   FX_COLORREF m_aHighlightColor[kNumFieldTypes];
354   uint8_t m_iHighlightAlpha;
355   FX_BOOL m_bNeedHightlight[kNumFieldTypes];
356 };
357 
358 class CBA_AnnotIterator {
359  public:
360   enum TabOrder { STRUCTURE = 0, ROW, COLUMN };
361 
362   CBA_AnnotIterator(CPDFSDK_PageView* pPageView,
363                     const CFX_ByteString& sType,
364                     const CFX_ByteString& sSubType);
365   ~CBA_AnnotIterator();
366 
367   CPDFSDK_Annot* GetFirstAnnot();
368   CPDFSDK_Annot* GetLastAnnot();
369   CPDFSDK_Annot* GetNextAnnot(CPDFSDK_Annot* pAnnot);
370   CPDFSDK_Annot* GetPrevAnnot(CPDFSDK_Annot* pAnnot);
371 
372  private:
373   void GenerateResults();
374   static CFX_FloatRect GetAnnotRect(const CPDFSDK_Annot* pAnnot);
375 
376   // Function signature compatible with std::sort().
377   static bool CompareByLeftAscending(const CPDFSDK_Annot* p1,
378                                      const CPDFSDK_Annot* p2);
379   static bool CompareByTopDescending(const CPDFSDK_Annot* p1,
380                                      const CPDFSDK_Annot* p2);
381 
382   TabOrder m_eTabOrder;
383   CPDFSDK_PageView* m_pPageView;
384   CFX_ByteString m_sType;
385   CFX_ByteString m_sSubType;
386   std::vector<CPDFSDK_Annot*> m_Annots;
387 };
388 
389 #endif  // FPDFSDK_INCLUDE_FSDK_BASEFORM_H_
390