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