blob: 4e5c9f0065a17151873568a92d48c16e68075cb7 [file] [log] [blame]
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001// 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.
Lei Zhanga6d9f0e2015-06-13 00:48:38 -07004
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07005// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6
Lei Zhangc2fb35f2016-01-05 16:46:58 -08007#include "fpdfsdk/include/fsdk_baseform.h"
8
Tom Sepezb9cc7a02016-02-01 13:42:30 -08009#include <algorithm>
tsepez16a20332016-04-22 14:00:47 -070010#include <map>
Lei Zhangaa8bf7e2015-12-24 19:13:32 -080011#include <memory>
Dan Sinclair3ebd1212016-03-09 09:59:23 -050012#include <vector>
Lei Zhangaa8bf7e2015-12-24 19:13:32 -080013
Dan Sinclair455a4192016-03-16 09:48:56 -040014#include "core/fpdfapi/fpdf_page/include/cpdf_page.h"
Dan Sinclairaa403d32016-03-15 14:57:22 -040015#include "core/fpdfapi/fpdf_parser/include/cfdf_document.h"
16#include "core/fpdfapi/fpdf_parser/include/cpdf_array.h"
17#include "core/fpdfapi/fpdf_parser/include/cpdf_document.h"
Dan Sinclair584b1e62016-03-21 09:15:45 -040018#include "core/fpdfapi/fpdf_parser/include/cpdf_stream.h"
Dan Sinclairedbb3192016-03-21 09:08:24 -040019#include "fpdfsdk/formfiller/cffl_formfiller.h"
Lei Zhangbde53d22015-11-12 22:21:30 -080020#include "fpdfsdk/include/fsdk_actionhandler.h"
21#include "fpdfsdk/include/fsdk_baseannot.h"
Lei Zhangbde53d22015-11-12 22:21:30 -080022#include "fpdfsdk/include/fsdk_define.h"
23#include "fpdfsdk/include/fsdk_mgr.h"
dsinclair64376be2016-03-31 20:03:24 -070024#include "fpdfsdk/javascript/ijs_context.h"
25#include "fpdfsdk/javascript/ijs_runtime.h"
dan sinclair89e904b2016-03-23 19:29:15 -040026#include "fpdfsdk/pdfwindow/PWL_Utils.h"
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070027
Tom Sepez40e9ff32015-11-30 12:39:54 -080028#ifdef PDF_ENABLE_XFA
dsinclair89bdd082016-04-06 10:47:54 -070029#include "fpdfsdk/fpdfxfa/include/fpdfxfa_doc.h"
30#include "fpdfsdk/fpdfxfa/include/fpdfxfa_util.h"
dsinclair7222ea62016-04-06 14:33:07 -070031#include "xfa/fxfa/include/xfa_ffwidget.h"
Tom Sepez40e9ff32015-11-30 12:39:54 -080032#endif // PDF_ENABLE_XFA
33
Nico Weber9d8ec5a2015-08-04 13:00:21 -070034CPDFSDK_Widget::CPDFSDK_Widget(CPDF_Annot* pAnnot,
35 CPDFSDK_PageView* pPageView,
36 CPDFSDK_InterForm* pInterForm)
37 : CPDFSDK_BAAnnot(pAnnot, pPageView),
38 m_pInterForm(pInterForm),
39 m_nAppAge(0),
Tom Sepez40e9ff32015-11-30 12:39:54 -080040 m_nValueAge(0)
41#ifdef PDF_ENABLE_XFA
42 ,
Nico Weber9d8ec5a2015-08-04 13:00:21 -070043 m_hMixXFAWidget(NULL),
Tom Sepez40e9ff32015-11-30 12:39:54 -080044 m_pWidgetHandler(NULL)
45#endif // PDF_ENABLE_XFA
46{
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070047}
48
Nico Weber9d8ec5a2015-08-04 13:00:21 -070049CPDFSDK_Widget::~CPDFSDK_Widget() {}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070050
Tom Sepez51da0932015-11-25 16:05:49 -080051#ifdef PDF_ENABLE_XFA
dsinclairdf4bc592016-03-31 20:34:43 -070052CXFA_FFWidget* CPDFSDK_Widget::GetMixXFAWidget() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070053 CPDFSDK_Document* pSDKDoc = m_pPageView->GetSDKDocument();
Tom Sepez50d12ad2015-11-24 09:50:51 -080054 CPDFXFA_Document* pDoc = pSDKDoc->GetXFADocument();
Nico Weber9d8ec5a2015-08-04 13:00:21 -070055 if (pDoc->GetDocType() == DOCTYPE_STATIC_XFA) {
56 if (!m_hMixXFAWidget) {
dsinclairdf4bc592016-03-31 20:34:43 -070057 if (CXFA_FFDocView* pDocView = pDoc->GetXFADocView()) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070058 CFX_WideString sName;
Lei Zhang99766722016-02-23 11:21:48 -080059 if (GetFieldType() == FIELDTYPE_RADIOBUTTON) {
60 sName = GetAnnotName();
Nico Weber9d8ec5a2015-08-04 13:00:21 -070061 if (sName.IsEmpty())
62 sName = GetName();
Dan Sinclair738b08c2016-03-01 14:45:20 -050063 } else {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070064 sName = GetName();
Dan Sinclair738b08c2016-03-01 14:45:20 -050065 }
Bo Xufdc00a72014-10-28 23:03:33 -070066
Nico Weber9d8ec5a2015-08-04 13:00:21 -070067 if (!sName.IsEmpty())
tsepez70c55202016-04-14 15:32:35 -070068 m_hMixXFAWidget = pDocView->GetWidgetByName(sName);
Nico Weber9d8ec5a2015-08-04 13:00:21 -070069 }
Tom Sepez2f2ffec2015-07-23 14:42:09 -070070 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -070071 return m_hMixXFAWidget;
72 }
Lei Zhanga6d9f0e2015-06-13 00:48:38 -070073
Nico Weber9d8ec5a2015-08-04 13:00:21 -070074 return NULL;
75}
76
dsinclairdf4bc592016-03-31 20:34:43 -070077CXFA_FFWidget* CPDFSDK_Widget::GetGroupMixXFAWidget() {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070078 CPDFSDK_Document* pSDKDoc = m_pPageView->GetSDKDocument();
Tom Sepez50d12ad2015-11-24 09:50:51 -080079 CPDFXFA_Document* pDoc = pSDKDoc->GetXFADocument();
Nico Weber9d8ec5a2015-08-04 13:00:21 -070080 if (pDoc->GetDocType() == DOCTYPE_STATIC_XFA) {
dsinclairdf4bc592016-03-31 20:34:43 -070081 if (CXFA_FFDocView* pDocView = pDoc->GetXFADocView()) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070082 CFX_WideString sName = GetName();
Nico Weber9d8ec5a2015-08-04 13:00:21 -070083 if (!sName.IsEmpty())
tsepez70c55202016-04-14 15:32:35 -070084 return pDocView->GetWidgetByName(sName);
Nico Weber9d8ec5a2015-08-04 13:00:21 -070085 }
86 }
87
Tom Sepez50d12ad2015-11-24 09:50:51 -080088 return nullptr;
Nico Weber9d8ec5a2015-08-04 13:00:21 -070089}
90
dsinclairdf4bc592016-03-31 20:34:43 -070091CXFA_FFWidgetHandler* CPDFSDK_Widget::GetXFAWidgetHandler() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070092 CPDFSDK_Document* pSDKDoc = m_pPageView->GetSDKDocument();
Tom Sepez50d12ad2015-11-24 09:50:51 -080093 CPDFXFA_Document* pDoc = pSDKDoc->GetXFADocument();
Nico Weber9d8ec5a2015-08-04 13:00:21 -070094 if (pDoc->GetDocType() == DOCTYPE_STATIC_XFA) {
95 if (!m_pWidgetHandler) {
dsinclairdf4bc592016-03-31 20:34:43 -070096 if (CXFA_FFDocView* pDocView = pDoc->GetXFADocView()) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070097 m_pWidgetHandler = pDocView->GetWidgetHandler();
98 }
99 }
100 return m_pWidgetHandler;
101 }
102
103 return NULL;
104}
105
106static XFA_EVENTTYPE GetXFAEventType(PDFSDK_XFAAActionType eXFAAAT) {
107 XFA_EVENTTYPE eEventType = XFA_EVENT_Unknown;
108
109 switch (eXFAAAT) {
110 case PDFSDK_XFA_Click:
111 eEventType = XFA_EVENT_Click;
112 break;
113 case PDFSDK_XFA_Full:
114 eEventType = XFA_EVENT_Full;
115 break;
116 case PDFSDK_XFA_PreOpen:
117 eEventType = XFA_EVENT_PreOpen;
118 break;
119 case PDFSDK_XFA_PostOpen:
120 eEventType = XFA_EVENT_PostOpen;
121 break;
122 }
123
124 return eEventType;
125}
126
127static XFA_EVENTTYPE GetXFAEventType(CPDF_AAction::AActionType eAAT,
128 FX_BOOL bWillCommit) {
129 XFA_EVENTTYPE eEventType = XFA_EVENT_Unknown;
130
131 switch (eAAT) {
132 case CPDF_AAction::CursorEnter:
133 eEventType = XFA_EVENT_MouseEnter;
134 break;
135 case CPDF_AAction::CursorExit:
136 eEventType = XFA_EVENT_MouseExit;
137 break;
138 case CPDF_AAction::ButtonDown:
139 eEventType = XFA_EVENT_MouseDown;
140 break;
141 case CPDF_AAction::ButtonUp:
142 eEventType = XFA_EVENT_MouseUp;
143 break;
144 case CPDF_AAction::GetFocus:
145 eEventType = XFA_EVENT_Enter;
146 break;
147 case CPDF_AAction::LoseFocus:
148 eEventType = XFA_EVENT_Exit;
149 break;
150 case CPDF_AAction::PageOpen:
151 break;
152 case CPDF_AAction::PageClose:
153 break;
154 case CPDF_AAction::PageVisible:
155 break;
156 case CPDF_AAction::PageInvisible:
157 break;
158 case CPDF_AAction::KeyStroke:
159 if (!bWillCommit) {
160 eEventType = XFA_EVENT_Change;
161 }
162 break;
163 case CPDF_AAction::Validate:
164 eEventType = XFA_EVENT_Validate;
165 break;
166 case CPDF_AAction::OpenPage:
167 case CPDF_AAction::ClosePage:
168 case CPDF_AAction::Format:
169 case CPDF_AAction::Calculate:
170 case CPDF_AAction::CloseDocument:
171 case CPDF_AAction::SaveDocument:
172 case CPDF_AAction::DocumentSaved:
173 case CPDF_AAction::PrintDocument:
174 case CPDF_AAction::DocumentPrinted:
175 break;
176 }
177
178 return eEventType;
179}
180
181FX_BOOL CPDFSDK_Widget::HasXFAAAction(PDFSDK_XFAAActionType eXFAAAT) {
dsinclairdf4bc592016-03-31 20:34:43 -0700182 if (CXFA_FFWidget* hWidget = GetMixXFAWidget()) {
183 if (CXFA_FFWidgetHandler* pXFAWidgetHandler = GetXFAWidgetHandler()) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700184 XFA_EVENTTYPE eEventType = GetXFAEventType(eXFAAAT);
185
186 if ((eEventType == XFA_EVENT_Click || eEventType == XFA_EVENT_Change) &&
187 GetFieldType() == FIELDTYPE_RADIOBUTTON) {
dsinclairdf4bc592016-03-31 20:34:43 -0700188 if (CXFA_FFWidget* hGroupWidget = GetGroupMixXFAWidget()) {
dsinclair221caf62016-04-04 12:08:40 -0700189 CXFA_WidgetAcc* pAcc = hGroupWidget->GetDataAcc();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700190 if (pXFAWidgetHandler->HasEvent(pAcc, eEventType))
191 return TRUE;
192 }
193 }
194
195 {
dsinclair221caf62016-04-04 12:08:40 -0700196 CXFA_WidgetAcc* pAcc = hWidget->GetDataAcc();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700197 return pXFAWidgetHandler->HasEvent(pAcc, eEventType);
198 }
199 }
200 }
201
202 return FALSE;
203}
204
205FX_BOOL CPDFSDK_Widget::OnXFAAAction(PDFSDK_XFAAActionType eXFAAAT,
206 PDFSDK_FieldAction& data,
207 CPDFSDK_PageView* pPageView) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700208 CPDFSDK_Document* pSDKDoc = m_pPageView->GetSDKDocument();
Tom Sepez50d12ad2015-11-24 09:50:51 -0800209 CPDFXFA_Document* pDoc = pSDKDoc->GetXFADocument();
dsinclairdf4bc592016-03-31 20:34:43 -0700210 if (CXFA_FFWidget* hWidget = GetMixXFAWidget()) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700211 XFA_EVENTTYPE eEventType = GetXFAEventType(eXFAAAT);
212
213 if (eEventType != XFA_EVENT_Unknown) {
dsinclairdf4bc592016-03-31 20:34:43 -0700214 if (CXFA_FFWidgetHandler* pXFAWidgetHandler = GetXFAWidgetHandler()) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700215 CXFA_EventParam param;
216 param.m_eType = eEventType;
217 param.m_wsChange = data.sChange;
218 param.m_iCommitKey = data.nCommitKey;
219 param.m_bShift = data.bShift;
220 param.m_iSelStart = data.nSelStart;
221 param.m_iSelEnd = data.nSelEnd;
222 param.m_wsFullText = data.sValue;
223 param.m_bKeyDown = data.bKeyDown;
224 param.m_bModifier = data.bModifier;
225 param.m_wsNewText = data.sValue;
226 if (data.nSelEnd > data.nSelStart)
227 param.m_wsNewText.Delete(data.nSelStart,
228 data.nSelEnd - data.nSelStart);
229 for (int i = 0; i < data.sChange.GetLength(); i++)
230 param.m_wsNewText.Insert(data.nSelStart, data.sChange[i]);
231 param.m_wsPrevText = data.sValue;
232
233 if ((eEventType == XFA_EVENT_Click || eEventType == XFA_EVENT_Change) &&
234 GetFieldType() == FIELDTYPE_RADIOBUTTON) {
dsinclairdf4bc592016-03-31 20:34:43 -0700235 if (CXFA_FFWidget* hGroupWidget = GetGroupMixXFAWidget()) {
dsinclair221caf62016-04-04 12:08:40 -0700236 CXFA_WidgetAcc* pAcc = hGroupWidget->GetDataAcc();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700237 param.m_pTarget = pAcc;
Wei Li42d1c1c2016-03-22 12:52:50 -0700238 if (pXFAWidgetHandler->ProcessEvent(pAcc, &param) !=
239 XFA_EVENTERROR_Success) {
240 return FALSE;
241 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700242 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700243 }
dsinclair221caf62016-04-04 12:08:40 -0700244 CXFA_WidgetAcc* pAcc = hWidget->GetDataAcc();
Wei Li42d1c1c2016-03-22 12:52:50 -0700245 param.m_pTarget = pAcc;
246 int32_t nRet = pXFAWidgetHandler->ProcessEvent(pAcc, &param);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700247
dsinclairdf4bc592016-03-31 20:34:43 -0700248 if (CXFA_FFDocView* pDocView = pDoc->GetXFADocView()) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700249 pDocView->UpdateDocView();
250 }
Wei Li42d1c1c2016-03-22 12:52:50 -0700251 return nRet == XFA_EVENTERROR_Success;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700252 }
253 }
254 }
255
256 return FALSE;
257}
258
259void CPDFSDK_Widget::Synchronize(FX_BOOL bSynchronizeElse) {
dsinclairdf4bc592016-03-31 20:34:43 -0700260 if (CXFA_FFWidget* hWidget = GetMixXFAWidget()) {
dsinclair221caf62016-04-04 12:08:40 -0700261 CPDF_FormField* pFormField = GetFormField();
262 if (CXFA_WidgetAcc* pWidgetAcc = hWidget->GetDataAcc()) {
263 switch (GetFieldType()) {
264 case FIELDTYPE_CHECKBOX:
265 case FIELDTYPE_RADIOBUTTON: {
266 CPDF_FormControl* pFormCtrl = GetFormControl();
267 XFA_CHECKSTATE eCheckState =
268 pFormCtrl->IsChecked() ? XFA_CHECKSTATE_On : XFA_CHECKSTATE_Off;
269 pWidgetAcc->SetCheckState(eCheckState);
270 } break;
271 case FIELDTYPE_TEXTFIELD:
272 pWidgetAcc->SetValue(pFormField->GetValue(), XFA_VALUEPICTURE_Edit);
273 break;
274 case FIELDTYPE_LISTBOX: {
275 pWidgetAcc->ClearAllSelections();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700276
dsinclair221caf62016-04-04 12:08:40 -0700277 for (int i = 0, sz = pFormField->CountSelectedItems(); i < sz; i++) {
278 int nIndex = pFormField->GetSelectedIndex(i);
279 if (nIndex > -1 && nIndex < pWidgetAcc->CountChoiceListItems())
280 pWidgetAcc->SetItemState(nIndex, TRUE, FALSE);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700281 }
dsinclair221caf62016-04-04 12:08:40 -0700282 } break;
283 case FIELDTYPE_COMBOBOX: {
284 pWidgetAcc->ClearAllSelections();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700285
dsinclair221caf62016-04-04 12:08:40 -0700286 for (int i = 0, sz = pFormField->CountSelectedItems(); i < sz; i++) {
287 int nIndex = pFormField->GetSelectedIndex(i);
288 if (nIndex > -1 && nIndex < pWidgetAcc->CountChoiceListItems())
289 pWidgetAcc->SetItemState(nIndex, TRUE, FALSE);
290 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700291 }
292
dsinclair221caf62016-04-04 12:08:40 -0700293 pWidgetAcc->SetValue(pFormField->GetValue(), XFA_VALUEPICTURE_Edit);
294 break;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700295 }
dsinclair221caf62016-04-04 12:08:40 -0700296
297 if (bSynchronizeElse)
298 pWidgetAcc->ProcessValueChanged();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700299 }
300 }
301}
302
303void CPDFSDK_Widget::SynchronizeXFAValue() {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700304 CPDFSDK_Document* pSDKDoc = m_pPageView->GetSDKDocument();
Tom Sepez50d12ad2015-11-24 09:50:51 -0800305 CPDFXFA_Document* pDoc = pSDKDoc->GetXFADocument();
dsinclairdf4bc592016-03-31 20:34:43 -0700306 CXFA_FFDocView* pXFADocView = pDoc->GetXFADocView();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700307 if (!pXFADocView)
308 return;
309
dsinclairdf4bc592016-03-31 20:34:43 -0700310 if (CXFA_FFWidget* hWidget = GetMixXFAWidget()) {
Tom Sepezbf59a072015-10-21 14:07:23 -0700311 if (GetXFAWidgetHandler()) {
312 CPDFSDK_Widget::SynchronizeXFAValue(pXFADocView, hWidget, GetFormField(),
313 GetFormControl());
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700314 }
315 }
316}
317
318void CPDFSDK_Widget::SynchronizeXFAItems() {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700319 CPDFSDK_Document* pSDKDoc = m_pPageView->GetSDKDocument();
Tom Sepez50d12ad2015-11-24 09:50:51 -0800320 CPDFXFA_Document* pDoc = pSDKDoc->GetXFADocument();
dsinclairdf4bc592016-03-31 20:34:43 -0700321 CXFA_FFDocView* pXFADocView = pDoc->GetXFADocView();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700322 if (!pXFADocView)
323 return;
324
dsinclairdf4bc592016-03-31 20:34:43 -0700325 if (CXFA_FFWidget* hWidget = GetMixXFAWidget()) {
Tom Sepezbf59a072015-10-21 14:07:23 -0700326 if (GetXFAWidgetHandler())
327 SynchronizeXFAItems(pXFADocView, hWidget, GetFormField(), nullptr);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700328 }
329}
330
dsinclairdf4bc592016-03-31 20:34:43 -0700331void CPDFSDK_Widget::SynchronizeXFAValue(CXFA_FFDocView* pXFADocView,
332 CXFA_FFWidget* hWidget,
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700333 CPDF_FormField* pFormField,
334 CPDF_FormControl* pFormControl) {
Lei Zhang5eca3052016-02-22 20:32:21 -0800335 ASSERT(hWidget);
dsinclair221caf62016-04-04 12:08:40 -0700336 ASSERT(pFormControl);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700337
dsinclair221caf62016-04-04 12:08:40 -0700338 switch (pFormField->GetFieldType()) {
339 case FIELDTYPE_CHECKBOX: {
340 if (CXFA_WidgetAcc* pWidgetAcc = hWidget->GetDataAcc()) {
341 pFormField->CheckControl(
342 pFormField->GetControlIndex(pFormControl),
343 pWidgetAcc->GetCheckState() == XFA_CHECKSTATE_On, true);
344 }
345 } break;
346 case FIELDTYPE_RADIOBUTTON: {
347 // TODO(weili): Check whether we need to handle checkbox and radio
348 // button differently, otherwise, merge these two cases.
349 if (CXFA_WidgetAcc* pWidgetAcc = hWidget->GetDataAcc()) {
350 pFormField->CheckControl(
351 pFormField->GetControlIndex(pFormControl),
352 pWidgetAcc->GetCheckState() == XFA_CHECKSTATE_On, true);
353 }
354 } break;
355 case FIELDTYPE_TEXTFIELD: {
356 if (CXFA_WidgetAcc* pWidgetAcc = hWidget->GetDataAcc()) {
357 CFX_WideString sValue;
358 pWidgetAcc->GetValue(sValue, XFA_VALUEPICTURE_Display);
359 pFormField->SetValue(sValue, TRUE);
360 }
361 } break;
362 case FIELDTYPE_LISTBOX: {
363 pFormField->ClearSelection(FALSE);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700364
dsinclair221caf62016-04-04 12:08:40 -0700365 if (CXFA_WidgetAcc* pWidgetAcc = hWidget->GetDataAcc()) {
366 for (int i = 0, sz = pWidgetAcc->CountSelectedItems(); i < sz; i++) {
367 int nIndex = pWidgetAcc->GetSelectedItem(i);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700368
dsinclair221caf62016-04-04 12:08:40 -0700369 if (nIndex > -1 && nIndex < pFormField->CountOptions()) {
370 pFormField->SetItemSelection(nIndex, TRUE, TRUE);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700371 }
372 }
dsinclair221caf62016-04-04 12:08:40 -0700373 }
374 } break;
375 case FIELDTYPE_COMBOBOX: {
376 pFormField->ClearSelection(FALSE);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700377
dsinclair221caf62016-04-04 12:08:40 -0700378 if (CXFA_WidgetAcc* pWidgetAcc = hWidget->GetDataAcc()) {
379 for (int i = 0, sz = pWidgetAcc->CountSelectedItems(); i < sz; i++) {
380 int nIndex = pWidgetAcc->GetSelectedItem(i);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700381
dsinclair221caf62016-04-04 12:08:40 -0700382 if (nIndex > -1 && nIndex < pFormField->CountOptions()) {
383 pFormField->SetItemSelection(nIndex, TRUE, TRUE);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700384 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700385 }
dsinclair221caf62016-04-04 12:08:40 -0700386
387 CFX_WideString sValue;
388 pWidgetAcc->GetValue(sValue, XFA_VALUEPICTURE_Display);
389 pFormField->SetValue(sValue, TRUE);
390 }
391 } break;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700392 }
393}
394
dsinclairdf4bc592016-03-31 20:34:43 -0700395void CPDFSDK_Widget::SynchronizeXFAItems(CXFA_FFDocView* pXFADocView,
396 CXFA_FFWidget* hWidget,
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700397 CPDF_FormField* pFormField,
398 CPDF_FormControl* pFormControl) {
Lei Zhang5eca3052016-02-22 20:32:21 -0800399 ASSERT(hWidget);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700400
dsinclair221caf62016-04-04 12:08:40 -0700401 switch (pFormField->GetFieldType()) {
402 case FIELDTYPE_LISTBOX: {
403 pFormField->ClearSelection(FALSE);
404 pFormField->ClearOptions(TRUE);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700405
dsinclair221caf62016-04-04 12:08:40 -0700406 if (CXFA_WidgetAcc* pWidgetAcc = hWidget->GetDataAcc()) {
407 for (int i = 0, sz = pWidgetAcc->CountChoiceListItems(); i < sz; i++) {
408 CFX_WideString swText;
409 pWidgetAcc->GetChoiceListItem(swText, i);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700410
dsinclair221caf62016-04-04 12:08:40 -0700411 pFormField->InsertOption(swText, i, TRUE);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700412 }
dsinclair221caf62016-04-04 12:08:40 -0700413 }
414 } break;
415 case FIELDTYPE_COMBOBOX: {
416 pFormField->ClearSelection(FALSE);
417 pFormField->ClearOptions(FALSE);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700418
dsinclair221caf62016-04-04 12:08:40 -0700419 if (CXFA_WidgetAcc* pWidgetAcc = hWidget->GetDataAcc()) {
420 for (int i = 0, sz = pWidgetAcc->CountChoiceListItems(); i < sz; i++) {
421 CFX_WideString swText;
422 pWidgetAcc->GetChoiceListItem(swText, i);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700423
dsinclair221caf62016-04-04 12:08:40 -0700424 pFormField->InsertOption(swText, i, FALSE);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700425 }
dsinclair221caf62016-04-04 12:08:40 -0700426 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700427
dsinclair221caf62016-04-04 12:08:40 -0700428 pFormField->SetValue(L"", TRUE);
429 } break;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700430 }
431}
Tom Sepez40e9ff32015-11-30 12:39:54 -0800432#endif // PDF_ENABLE_XFA
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700433
434FX_BOOL CPDFSDK_Widget::IsWidgetAppearanceValid(
435 CPDF_Annot::AppearanceMode mode) {
Wei Li9b761132016-01-29 15:44:20 -0800436 CPDF_Dictionary* pAP = m_pAnnot->GetAnnotDict()->GetDictBy("AP");
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700437 if (!pAP)
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700438 return FALSE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700439
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700440 // Choose the right sub-ap
441 const FX_CHAR* ap_entry = "N";
442 if (mode == CPDF_Annot::Down)
443 ap_entry = "D";
444 else if (mode == CPDF_Annot::Rollover)
445 ap_entry = "R";
446 if (!pAP->KeyExist(ap_entry))
447 ap_entry = "N";
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700448
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700449 // Get the AP stream or subdirectory
tsepezbd567552016-03-29 14:51:50 -0700450 CPDF_Object* psub = pAP->GetDirectObjectBy(ap_entry);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700451 if (!psub)
452 return FALSE;
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700453
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700454 int nFieldType = GetFieldType();
455 switch (nFieldType) {
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700456 case FIELDTYPE_PUSHBUTTON:
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700457 case FIELDTYPE_COMBOBOX:
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700458 case FIELDTYPE_LISTBOX:
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700459 case FIELDTYPE_TEXTFIELD:
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700460 case FIELDTYPE_SIGNATURE:
Dan Sinclairaa435ba2015-10-22 16:45:48 -0400461 return psub->IsStream();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700462 case FIELDTYPE_CHECKBOX:
463 case FIELDTYPE_RADIOBUTTON:
Dan Sinclairf1251c12015-10-20 16:24:45 -0400464 if (CPDF_Dictionary* pSubDict = psub->AsDictionary()) {
tsepez7b1ccf92016-04-14 11:04:57 -0700465 return !!pSubDict->GetStreamBy(GetAppState());
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700466 }
467 return FALSE;
468 }
469 return TRUE;
470}
471
472int CPDFSDK_Widget::GetFieldType() const {
Lei Zhang96660d62015-12-14 18:27:25 -0800473 return GetFormField()->GetFieldType();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700474}
475
476FX_BOOL CPDFSDK_Widget::IsAppearanceValid() {
Tom Sepez51da0932015-11-25 16:05:49 -0800477#ifdef PDF_ENABLE_XFA
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700478 CPDFSDK_Document* pSDKDoc = m_pPageView->GetSDKDocument();
Tom Sepez50d12ad2015-11-24 09:50:51 -0800479 CPDFXFA_Document* pDoc = pSDKDoc->GetXFADocument();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700480 int nDocType = pDoc->GetDocType();
Tom Sepez540c4362015-11-24 13:33:57 -0800481 if (nDocType != DOCTYPE_PDF && nDocType != DOCTYPE_STATIC_XFA)
482 return TRUE;
Tom Sepez40e9ff32015-11-30 12:39:54 -0800483#endif // PDF_ENABLE_XFA
Tom Sepez540c4362015-11-24 13:33:57 -0800484 return CPDFSDK_BAAnnot::IsAppearanceValid();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700485}
486
487int CPDFSDK_Widget::GetFieldFlags() const {
488 CPDF_InterForm* pPDFInterForm = m_pInterForm->GetInterForm();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700489 CPDF_FormControl* pFormControl =
490 pPDFInterForm->GetControlByDict(m_pAnnot->GetAnnotDict());
491 CPDF_FormField* pFormField = pFormControl->GetField();
492 return pFormField->GetFieldFlags();
493}
494
495CFX_ByteString CPDFSDK_Widget::GetSubType() const {
496 int nType = GetFieldType();
497
498 if (nType == FIELDTYPE_SIGNATURE)
499 return BFFT_SIGNATURE;
500 return CPDFSDK_Annot::GetSubType();
501}
502
503CPDF_FormField* CPDFSDK_Widget::GetFormField() const {
Lei Zhang1b700c32015-10-30 23:55:35 -0700504 return GetFormControl()->GetField();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700505}
506
507CPDF_FormControl* CPDFSDK_Widget::GetFormControl() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700508 CPDF_InterForm* pPDFInterForm = m_pInterForm->GetInterForm();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700509 return pPDFInterForm->GetControlByDict(GetAnnotDict());
510}
511
Lei Zhang1b700c32015-10-30 23:55:35 -0700512CPDF_FormControl* CPDFSDK_Widget::GetFormControl(
513 CPDF_InterForm* pInterForm,
514 const CPDF_Dictionary* pAnnotDict) {
Lei Zhang96660d62015-12-14 18:27:25 -0800515 ASSERT(pAnnotDict);
Lei Zhang1b700c32015-10-30 23:55:35 -0700516 return pInterForm->GetControlByDict(pAnnotDict);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700517}
518
519int CPDFSDK_Widget::GetRotate() const {
520 CPDF_FormControl* pCtrl = GetFormControl();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700521 return pCtrl->GetRotation() % 360;
522}
523
Tom Sepez51da0932015-11-25 16:05:49 -0800524#ifdef PDF_ENABLE_XFA
Tom Sepezbf59a072015-10-21 14:07:23 -0700525CFX_WideString CPDFSDK_Widget::GetName() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700526 CPDF_FormField* pFormField = GetFormField();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700527 return pFormField->GetFullName();
528}
Tom Sepez40e9ff32015-11-30 12:39:54 -0800529#endif // PDF_ENABLE_XFA
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700530
531FX_BOOL CPDFSDK_Widget::GetFillColor(FX_COLORREF& color) const {
532 CPDF_FormControl* pFormCtrl = GetFormControl();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700533 int iColorType = 0;
534 color = FX_ARGBTOCOLORREF(pFormCtrl->GetBackgroundColor(iColorType));
535
536 return iColorType != COLORTYPE_TRANSPARENT;
537}
538
539FX_BOOL CPDFSDK_Widget::GetBorderColor(FX_COLORREF& color) const {
540 CPDF_FormControl* pFormCtrl = GetFormControl();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700541 int iColorType = 0;
542 color = FX_ARGBTOCOLORREF(pFormCtrl->GetBorderColor(iColorType));
543
544 return iColorType != COLORTYPE_TRANSPARENT;
545}
546
547FX_BOOL CPDFSDK_Widget::GetTextColor(FX_COLORREF& color) const {
548 CPDF_FormControl* pFormCtrl = GetFormControl();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700549 CPDF_DefaultAppearance da = pFormCtrl->GetDefaultAppearance();
550 if (da.HasColor()) {
551 FX_ARGB argb;
552 int iColorType = COLORTYPE_TRANSPARENT;
553 da.GetColor(argb, iColorType);
554 color = FX_ARGBTOCOLORREF(argb);
555
556 return iColorType != COLORTYPE_TRANSPARENT;
557 }
558
559 return FALSE;
560}
561
562FX_FLOAT CPDFSDK_Widget::GetFontSize() const {
563 CPDF_FormControl* pFormCtrl = GetFormControl();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700564 CPDF_DefaultAppearance pDa = pFormCtrl->GetDefaultAppearance();
565 CFX_ByteString csFont = "";
566 FX_FLOAT fFontSize = 0.0f;
567 pDa.GetFont(csFont, fFontSize);
568
569 return fFontSize;
570}
571
Tom Sepezbf59a072015-10-21 14:07:23 -0700572int CPDFSDK_Widget::GetSelectedIndex(int nIndex) const {
Tom Sepeza8a39e22015-10-12 15:47:07 -0700573#ifdef PDF_ENABLE_XFA
dsinclairdf4bc592016-03-31 20:34:43 -0700574 if (CXFA_FFWidget* hWidget = GetMixXFAWidget()) {
dsinclair221caf62016-04-04 12:08:40 -0700575 if (CXFA_WidgetAcc* pWidgetAcc = hWidget->GetDataAcc()) {
576 if (nIndex < pWidgetAcc->CountSelectedItems())
577 return pWidgetAcc->GetSelectedItem(nIndex);
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700578 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700579 }
Tom Sepeza8a39e22015-10-12 15:47:07 -0700580#endif // PDF_ENABLE_XFA
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700581 CPDF_FormField* pFormField = GetFormField();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700582 return pFormField->GetSelectedIndex(nIndex);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700583}
584
Tom Sepeza8a39e22015-10-12 15:47:07 -0700585#ifdef PDF_ENABLE_XFA
Tom Sepez40e9ff32015-11-30 12:39:54 -0800586CFX_WideString CPDFSDK_Widget::GetValue(FX_BOOL bDisplay) const {
dsinclairdf4bc592016-03-31 20:34:43 -0700587 if (CXFA_FFWidget* hWidget = GetMixXFAWidget()) {
dsinclair221caf62016-04-04 12:08:40 -0700588 if (CXFA_WidgetAcc* pWidgetAcc = hWidget->GetDataAcc()) {
589 CFX_WideString sValue;
590 pWidgetAcc->GetValue(
591 sValue, bDisplay ? XFA_VALUEPICTURE_Display : XFA_VALUEPICTURE_Edit);
592 return sValue;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700593 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700594 }
Tom Sepez40e9ff32015-11-30 12:39:54 -0800595#else
596CFX_WideString CPDFSDK_Widget::GetValue() const {
Tom Sepeza8a39e22015-10-12 15:47:07 -0700597#endif // PDF_ENABLE_XFA
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700598 CPDF_FormField* pFormField = GetFormField();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700599 return pFormField->GetValue();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700600}
601
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700602CFX_WideString CPDFSDK_Widget::GetDefaultValue() const {
603 CPDF_FormField* pFormField = GetFormField();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700604 return pFormField->GetDefaultValue();
605}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700606
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700607CFX_WideString CPDFSDK_Widget::GetOptionLabel(int nIndex) const {
608 CPDF_FormField* pFormField = GetFormField();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700609 return pFormField->GetOptionLabel(nIndex);
610}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700611
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700612int CPDFSDK_Widget::CountOptions() const {
613 CPDF_FormField* pFormField = GetFormField();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700614 return pFormField->CountOptions();
615}
616
Tom Sepezbf59a072015-10-21 14:07:23 -0700617FX_BOOL CPDFSDK_Widget::IsOptionSelected(int nIndex) const {
Tom Sepeza8a39e22015-10-12 15:47:07 -0700618#ifdef PDF_ENABLE_XFA
dsinclairdf4bc592016-03-31 20:34:43 -0700619 if (CXFA_FFWidget* hWidget = GetMixXFAWidget()) {
dsinclair221caf62016-04-04 12:08:40 -0700620 if (CXFA_WidgetAcc* pWidgetAcc = hWidget->GetDataAcc()) {
621 if (nIndex > -1 && nIndex < pWidgetAcc->CountChoiceListItems())
622 return pWidgetAcc->GetItemState(nIndex);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700623
dsinclair221caf62016-04-04 12:08:40 -0700624 return FALSE;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700625 }
626 }
Tom Sepeza8a39e22015-10-12 15:47:07 -0700627#endif // PDF_ENABLE_XFA
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700628 CPDF_FormField* pFormField = GetFormField();
629 return pFormField->IsItemSelected(nIndex);
630}
631
632int CPDFSDK_Widget::GetTopVisibleIndex() const {
633 CPDF_FormField* pFormField = GetFormField();
634 return pFormField->GetTopVisibleIndex();
635}
636
Wei Li97da9762016-03-11 17:00:48 -0800637bool CPDFSDK_Widget::IsChecked() const {
Tom Sepeza8a39e22015-10-12 15:47:07 -0700638#ifdef PDF_ENABLE_XFA
dsinclair221caf62016-04-04 12:08:40 -0700639 if (CXFA_FFWidget* hWidget = GetMixXFAWidget()) {
640 if (CXFA_WidgetAcc* pWidgetAcc = hWidget->GetDataAcc())
641 return pWidgetAcc->GetCheckState() == XFA_CHECKSTATE_On;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700642 }
Tom Sepeza8a39e22015-10-12 15:47:07 -0700643#endif // PDF_ENABLE_XFA
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700644 CPDF_FormControl* pFormCtrl = GetFormControl();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700645 return pFormCtrl->IsChecked();
646}
647
648int CPDFSDK_Widget::GetAlignment() const {
649 CPDF_FormControl* pFormCtrl = GetFormControl();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700650 return pFormCtrl->GetControlAlignment();
651}
652
653int CPDFSDK_Widget::GetMaxLen() const {
654 CPDF_FormField* pFormField = GetFormField();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700655 return pFormField->GetMaxLen();
656}
657
Wei Li97da9762016-03-11 17:00:48 -0800658void CPDFSDK_Widget::SetCheck(bool bChecked, bool bNotify) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700659 CPDF_FormControl* pFormCtrl = GetFormControl();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700660 CPDF_FormField* pFormField = pFormCtrl->GetField();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700661 pFormField->CheckControl(pFormField->GetControlIndex(pFormCtrl), bChecked,
662 bNotify);
Tom Sepez51da0932015-11-25 16:05:49 -0800663#ifdef PDF_ENABLE_XFA
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700664 if (!IsWidgetAppearanceValid(CPDF_Annot::Normal))
665 ResetAppearance(TRUE);
666 if (!bNotify)
667 Synchronize(TRUE);
Tom Sepez40e9ff32015-11-30 12:39:54 -0800668#endif // PDF_ENABLE_XFA
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700669}
670
671void CPDFSDK_Widget::SetValue(const CFX_WideString& sValue, FX_BOOL bNotify) {
672 CPDF_FormField* pFormField = GetFormField();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700673 pFormField->SetValue(sValue, bNotify);
Tom Sepez51da0932015-11-25 16:05:49 -0800674#ifdef PDF_ENABLE_XFA
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700675 if (!bNotify)
676 Synchronize(TRUE);
Tom Sepez40e9ff32015-11-30 12:39:54 -0800677#endif // PDF_ENABLE_XFA
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700678}
679
680void CPDFSDK_Widget::SetDefaultValue(const CFX_WideString& sValue) {}
681void CPDFSDK_Widget::SetOptionSelection(int index,
682 FX_BOOL bSelected,
683 FX_BOOL bNotify) {
684 CPDF_FormField* pFormField = GetFormField();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700685 pFormField->SetItemSelection(index, bSelected, bNotify);
Tom Sepez51da0932015-11-25 16:05:49 -0800686#ifdef PDF_ENABLE_XFA
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700687 if (!bNotify)
688 Synchronize(TRUE);
Tom Sepez40e9ff32015-11-30 12:39:54 -0800689#endif // PDF_ENABLE_XFA
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700690}
691
692void CPDFSDK_Widget::ClearSelection(FX_BOOL bNotify) {
693 CPDF_FormField* pFormField = GetFormField();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700694 pFormField->ClearSelection(bNotify);
Tom Sepez51da0932015-11-25 16:05:49 -0800695#ifdef PDF_ENABLE_XFA
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700696 if (!bNotify)
697 Synchronize(TRUE);
Tom Sepez40e9ff32015-11-30 12:39:54 -0800698#endif // PDF_ENABLE_XFA
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700699}
700
701void CPDFSDK_Widget::SetTopVisibleIndex(int index) {}
702
703void CPDFSDK_Widget::SetAppModified() {
704 m_bAppModified = TRUE;
705}
706
707void CPDFSDK_Widget::ClearAppModified() {
708 m_bAppModified = FALSE;
709}
710
711FX_BOOL CPDFSDK_Widget::IsAppModified() const {
712 return m_bAppModified;
713}
714
Tom Sepez51da0932015-11-25 16:05:49 -0800715#ifdef PDF_ENABLE_XFA
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700716void CPDFSDK_Widget::ResetAppearance(FX_BOOL bValueChanged) {
717 switch (GetFieldType()) {
718 case FIELDTYPE_TEXTFIELD:
719 case FIELDTYPE_COMBOBOX: {
720 FX_BOOL bFormated = FALSE;
Lei Zhang99766722016-02-23 11:21:48 -0800721 CFX_WideString sValue = OnFormat(bFormated);
tsepezbd9748d2016-04-13 21:40:19 -0700722 ResetAppearance(bFormated ? sValue.c_str() : nullptr, TRUE);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700723 } break;
724 default:
Lei Zhang99766722016-02-23 11:21:48 -0800725 ResetAppearance(nullptr, FALSE);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700726 break;
727 }
728}
Tom Sepez40e9ff32015-11-30 12:39:54 -0800729#endif // PDF_ENABLE_XFA
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700730
731void CPDFSDK_Widget::ResetAppearance(const FX_WCHAR* sValue,
732 FX_BOOL bValueChanged) {
733 SetAppModified();
734
735 m_nAppAge++;
736 if (m_nAppAge > 999999)
737 m_nAppAge = 0;
738 if (bValueChanged)
739 m_nValueAge++;
740
741 int nFieldType = GetFieldType();
742
743 switch (nFieldType) {
744 case FIELDTYPE_PUSHBUTTON:
745 ResetAppearance_PushButton();
746 break;
747 case FIELDTYPE_CHECKBOX:
748 ResetAppearance_CheckBox();
749 break;
750 case FIELDTYPE_RADIOBUTTON:
751 ResetAppearance_RadioButton();
752 break;
753 case FIELDTYPE_COMBOBOX:
754 ResetAppearance_ComboBox(sValue);
755 break;
756 case FIELDTYPE_LISTBOX:
757 ResetAppearance_ListBox();
758 break;
759 case FIELDTYPE_TEXTFIELD:
760 ResetAppearance_TextField(sValue);
761 break;
762 }
763
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700764 m_pAnnot->ClearCachedAP();
765}
766
767CFX_WideString CPDFSDK_Widget::OnFormat(FX_BOOL& bFormated) {
768 CPDF_FormField* pFormField = GetFormField();
Lei Zhang96660d62015-12-14 18:27:25 -0800769 ASSERT(pFormField);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700770 return m_pInterForm->OnFormat(pFormField, bFormated);
771}
772
773void CPDFSDK_Widget::ResetFieldAppearance(FX_BOOL bValueChanged) {
774 CPDF_FormField* pFormField = GetFormField();
Lei Zhang96660d62015-12-14 18:27:25 -0800775 ASSERT(pFormField);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700776 m_pInterForm->ResetFieldAppearance(pFormField, NULL, bValueChanged);
777}
778
779void CPDFSDK_Widget::DrawAppearance(CFX_RenderDevice* pDevice,
Tom Sepez60d909e2015-12-10 15:34:55 -0800780 const CFX_Matrix* pUser2Device,
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700781 CPDF_Annot::AppearanceMode mode,
782 const CPDF_RenderOptions* pOptions) {
783 int nFieldType = GetFieldType();
784
785 if ((nFieldType == FIELDTYPE_CHECKBOX ||
786 nFieldType == FIELDTYPE_RADIOBUTTON) &&
787 mode == CPDF_Annot::Normal &&
788 !IsWidgetAppearanceValid(CPDF_Annot::Normal)) {
789 CFX_PathData pathData;
790
Tom Sepez281a9ea2016-02-26 14:24:28 -0800791 CFX_FloatRect rcAnnot = GetRect();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700792
793 pathData.AppendRect(rcAnnot.left, rcAnnot.bottom, rcAnnot.right,
794 rcAnnot.top);
795
796 CFX_GraphStateData gsd;
797 gsd.m_LineWidth = 0.0f;
798
799 pDevice->DrawPath(&pathData, pUser2Device, &gsd, 0, 0xFFAAAAAA,
800 FXFILL_ALTERNATE);
801 } else {
802 CPDFSDK_BAAnnot::DrawAppearance(pDevice, pUser2Device, mode, pOptions);
803 }
804}
805
806void CPDFSDK_Widget::UpdateField() {
807 CPDF_FormField* pFormField = GetFormField();
Lei Zhang96660d62015-12-14 18:27:25 -0800808 ASSERT(pFormField);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700809 m_pInterForm->UpdateField(pFormField);
810}
811
812void CPDFSDK_Widget::DrawShadow(CFX_RenderDevice* pDevice,
813 CPDFSDK_PageView* pPageView) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700814 int nFieldType = GetFieldType();
815 if (m_pInterForm->IsNeedHighLight(nFieldType)) {
Tom Sepez281a9ea2016-02-26 14:24:28 -0800816 CFX_FloatRect rc = GetRect();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700817 FX_COLORREF color = m_pInterForm->GetHighlightColor(nFieldType);
818 uint8_t alpha = m_pInterForm->GetHighlightAlpha();
819
820 CFX_FloatRect rcDevice;
821 ASSERT(m_pInterForm->GetDocument());
822 CPDFDoc_Environment* pEnv = m_pInterForm->GetDocument()->GetEnv();
823 if (!pEnv)
824 return;
Tom Sepez60d909e2015-12-10 15:34:55 -0800825 CFX_Matrix page2device;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700826 pPageView->GetCurrentMatrix(page2device);
827 page2device.Transform(((FX_FLOAT)rc.left), ((FX_FLOAT)rc.bottom),
828 rcDevice.left, rcDevice.bottom);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700829 page2device.Transform(((FX_FLOAT)rc.right), ((FX_FLOAT)rc.top),
830 rcDevice.right, rcDevice.top);
831
832 rcDevice.Normalize();
833
834 FX_ARGB argb = ArgbEncode((int)alpha, color);
835 FX_RECT rcDev((int)rcDevice.left, (int)rcDevice.top, (int)rcDevice.right,
836 (int)rcDevice.bottom);
837 pDevice->FillRect(&rcDev, argb);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700838 }
839}
840
841void CPDFSDK_Widget::ResetAppearance_PushButton() {
842 CPDF_FormControl* pControl = GetFormControl();
Tom Sepez281a9ea2016-02-26 14:24:28 -0800843 CFX_FloatRect rcWindow = GetRotatedRect();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700844 int32_t nLayout = 0;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700845 switch (pControl->GetTextPosition()) {
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700846 case TEXTPOS_ICON:
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700847 nLayout = PPBL_ICON;
848 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700849 case TEXTPOS_BELOW:
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700850 nLayout = PPBL_ICONTOPLABELBOTTOM;
851 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700852 case TEXTPOS_ABOVE:
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700853 nLayout = PPBL_LABELTOPICONBOTTOM;
854 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700855 case TEXTPOS_RIGHT:
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700856 nLayout = PPBL_ICONLEFTLABELRIGHT;
857 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700858 case TEXTPOS_LEFT:
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700859 nLayout = PPBL_LABELLEFTICONRIGHT;
860 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700861 case TEXTPOS_OVERLAID:
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700862 nLayout = PPBL_LABELOVERICON;
863 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700864 default:
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700865 nLayout = PPBL_LABEL;
866 break;
867 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700868
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700869 CPWL_Color crBackground, crBorder;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700870
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700871 int iColorType;
872 FX_FLOAT fc[4];
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700873
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700874 pControl->GetOriginalBackgroundColor(iColorType, fc);
875 if (iColorType > 0)
876 crBackground = CPWL_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700877
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700878 pControl->GetOriginalBorderColor(iColorType, fc);
879 if (iColorType > 0)
880 crBorder = CPWL_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700881
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700882 FX_FLOAT fBorderWidth = (FX_FLOAT)GetBorderWidth();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700883 CPWL_Dash dsBorder(3, 0, 0);
884 CPWL_Color crLeftTop, crRightBottom;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700885
dsinclair92cb5e52016-05-16 11:38:28 -0700886 BorderStyle nBorderStyle = GetBorderStyle();
887 switch (nBorderStyle) {
888 case BorderStyle::DASH:
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700889 dsBorder = CPWL_Dash(3, 3, 0);
890 break;
dsinclair92cb5e52016-05-16 11:38:28 -0700891 case BorderStyle::BEVELED:
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700892 fBorderWidth *= 2;
893 crLeftTop = CPWL_Color(COLORTYPE_GRAY, 1);
894 crRightBottom = CPWL_Utils::DevideColor(crBackground, 2);
895 break;
dsinclair92cb5e52016-05-16 11:38:28 -0700896 case BorderStyle::INSET:
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700897 fBorderWidth *= 2;
898 crLeftTop = CPWL_Color(COLORTYPE_GRAY, 0.5);
899 crRightBottom = CPWL_Color(COLORTYPE_GRAY, 0.75);
900 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700901 default:
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700902 break;
903 }
904
Tom Sepez281a9ea2016-02-26 14:24:28 -0800905 CFX_FloatRect rcClient = CPWL_Utils::DeflateRect(rcWindow, fBorderWidth);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700906
907 CPWL_Color crText(COLORTYPE_GRAY, 0);
908
909 FX_FLOAT fFontSize = 12.0f;
910 CFX_ByteString csNameTag;
911
912 CPDF_DefaultAppearance da = pControl->GetDefaultAppearance();
913 if (da.HasColor()) {
914 da.GetColor(iColorType, fc);
915 crText = CPWL_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
916 }
917
918 if (da.HasFont())
919 da.GetFont(csNameTag, fFontSize);
920
921 CFX_WideString csWCaption;
922 CFX_WideString csNormalCaption, csRolloverCaption, csDownCaption;
923
924 if (pControl->HasMKEntry("CA")) {
925 csNormalCaption = pControl->GetNormalCaption();
926 }
927 if (pControl->HasMKEntry("RC")) {
928 csRolloverCaption = pControl->GetRolloverCaption();
929 }
930 if (pControl->HasMKEntry("AC")) {
931 csDownCaption = pControl->GetDownCaption();
932 }
933
934 CPDF_Stream* pNormalIcon = NULL;
935 CPDF_Stream* pRolloverIcon = NULL;
936 CPDF_Stream* pDownIcon = NULL;
937
938 if (pControl->HasMKEntry("I")) {
939 pNormalIcon = pControl->GetNormalIcon();
940 }
941 if (pControl->HasMKEntry("RI")) {
942 pRolloverIcon = pControl->GetRolloverIcon();
943 }
944 if (pControl->HasMKEntry("IX")) {
945 pDownIcon = pControl->GetDownIcon();
946 }
947
948 if (pNormalIcon) {
949 if (CPDF_Dictionary* pImageDict = pNormalIcon->GetDict()) {
Wei Li9b761132016-01-29 15:44:20 -0800950 if (pImageDict->GetStringBy("Name").IsEmpty())
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700951 pImageDict->SetAtString("Name", "ImgA");
952 }
953 }
954
955 if (pRolloverIcon) {
956 if (CPDF_Dictionary* pImageDict = pRolloverIcon->GetDict()) {
Wei Li9b761132016-01-29 15:44:20 -0800957 if (pImageDict->GetStringBy("Name").IsEmpty())
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700958 pImageDict->SetAtString("Name", "ImgB");
959 }
960 }
961
962 if (pDownIcon) {
963 if (CPDF_Dictionary* pImageDict = pDownIcon->GetDict()) {
Wei Li9b761132016-01-29 15:44:20 -0800964 if (pImageDict->GetStringBy("Name").IsEmpty())
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700965 pImageDict->SetAtString("Name", "ImgC");
966 }
967 }
968
969 CPDF_IconFit iconFit = pControl->GetIconFit();
970
971 CPDFSDK_Document* pDoc = m_pInterForm->GetDocument();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700972 CPDFDoc_Environment* pEnv = pDoc->GetEnv();
973
Lei Zhangfcfa3b82015-12-24 21:07:28 -0800974 CBA_FontMap font_map(this, pEnv->GetSysHandler());
975 font_map.SetAPType("N");
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700976
977 CFX_ByteString csAP =
978 CPWL_Utils::GetRectFillAppStream(rcWindow, crBackground) +
979 CPWL_Utils::GetBorderAppStream(rcWindow, fBorderWidth, crBorder,
980 crLeftTop, crRightBottom, nBorderStyle,
981 dsBorder) +
982 CPWL_Utils::GetPushButtonAppStream(
Lei Zhangfcfa3b82015-12-24 21:07:28 -0800983 iconFit.GetFittingBounds() ? rcWindow : rcClient, &font_map,
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700984 pNormalIcon, iconFit, csNormalCaption, crText, fFontSize, nLayout);
985
986 WriteAppearance("N", GetRotatedRect(), GetMatrix(), csAP);
987 if (pNormalIcon)
988 AddImageToAppearance("N", pNormalIcon);
989
990 CPDF_FormControl::HighlightingMode eHLM = pControl->GetHighlightingMode();
991 if (eHLM == CPDF_FormControl::Push || eHLM == CPDF_FormControl::Toggle) {
992 if (csRolloverCaption.IsEmpty() && !pRolloverIcon) {
993 csRolloverCaption = csNormalCaption;
994 pRolloverIcon = pNormalIcon;
995 }
996
Lei Zhangfcfa3b82015-12-24 21:07:28 -0800997 font_map.SetAPType("R");
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700998
999 csAP = CPWL_Utils::GetRectFillAppStream(rcWindow, crBackground) +
1000 CPWL_Utils::GetBorderAppStream(rcWindow, fBorderWidth, crBorder,
1001 crLeftTop, crRightBottom,
1002 nBorderStyle, dsBorder) +
1003 CPWL_Utils::GetPushButtonAppStream(
Lei Zhangfcfa3b82015-12-24 21:07:28 -08001004 iconFit.GetFittingBounds() ? rcWindow : rcClient, &font_map,
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001005 pRolloverIcon, iconFit, csRolloverCaption, crText, fFontSize,
1006 nLayout);
1007
1008 WriteAppearance("R", GetRotatedRect(), GetMatrix(), csAP);
1009 if (pRolloverIcon)
1010 AddImageToAppearance("R", pRolloverIcon);
1011
1012 if (csDownCaption.IsEmpty() && !pDownIcon) {
1013 csDownCaption = csNormalCaption;
1014 pDownIcon = pNormalIcon;
1015 }
1016
1017 switch (nBorderStyle) {
dsinclair92cb5e52016-05-16 11:38:28 -07001018 case BorderStyle::BEVELED: {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001019 CPWL_Color crTemp = crLeftTop;
1020 crLeftTop = crRightBottom;
1021 crRightBottom = crTemp;
dsinclair92cb5e52016-05-16 11:38:28 -07001022 break;
1023 }
1024 case BorderStyle::INSET: {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001025 crLeftTop = CPWL_Color(COLORTYPE_GRAY, 0);
1026 crRightBottom = CPWL_Color(COLORTYPE_GRAY, 1);
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001027 break;
dsinclair92cb5e52016-05-16 11:38:28 -07001028 }
1029 default:
1030 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001031 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001032
Lei Zhangfcfa3b82015-12-24 21:07:28 -08001033 font_map.SetAPType("D");
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001034
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001035 csAP = CPWL_Utils::GetRectFillAppStream(
1036 rcWindow, CPWL_Utils::SubstractColor(crBackground, 0.25f)) +
1037 CPWL_Utils::GetBorderAppStream(rcWindow, fBorderWidth, crBorder,
1038 crLeftTop, crRightBottom,
1039 nBorderStyle, dsBorder) +
1040 CPWL_Utils::GetPushButtonAppStream(
Lei Zhangfcfa3b82015-12-24 21:07:28 -08001041 iconFit.GetFittingBounds() ? rcWindow : rcClient, &font_map,
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001042 pDownIcon, iconFit, csDownCaption, crText, fFontSize, nLayout);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001043
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001044 WriteAppearance("D", GetRotatedRect(), GetMatrix(), csAP);
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001045 if (pDownIcon)
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001046 AddImageToAppearance("D", pDownIcon);
1047 } else {
1048 RemoveAppearance("D");
1049 RemoveAppearance("R");
1050 }
1051}
1052
1053void CPDFSDK_Widget::ResetAppearance_CheckBox() {
1054 CPDF_FormControl* pControl = GetFormControl();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001055 CPWL_Color crBackground, crBorder, crText;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001056 int iColorType;
1057 FX_FLOAT fc[4];
1058
1059 pControl->GetOriginalBackgroundColor(iColorType, fc);
1060 if (iColorType > 0)
1061 crBackground = CPWL_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
1062
1063 pControl->GetOriginalBorderColor(iColorType, fc);
1064 if (iColorType > 0)
1065 crBorder = CPWL_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
1066
1067 FX_FLOAT fBorderWidth = (FX_FLOAT)GetBorderWidth();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001068 CPWL_Dash dsBorder(3, 0, 0);
1069 CPWL_Color crLeftTop, crRightBottom;
1070
dsinclair92cb5e52016-05-16 11:38:28 -07001071 BorderStyle nBorderStyle = GetBorderStyle();
1072 switch (nBorderStyle) {
1073 case BorderStyle::DASH:
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001074 dsBorder = CPWL_Dash(3, 3, 0);
1075 break;
dsinclair92cb5e52016-05-16 11:38:28 -07001076 case BorderStyle::BEVELED:
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001077 fBorderWidth *= 2;
1078 crLeftTop = CPWL_Color(COLORTYPE_GRAY, 1);
1079 crRightBottom = CPWL_Utils::DevideColor(crBackground, 2);
1080 break;
dsinclair92cb5e52016-05-16 11:38:28 -07001081 case BorderStyle::INSET:
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001082 fBorderWidth *= 2;
1083 crLeftTop = CPWL_Color(COLORTYPE_GRAY, 0.5);
1084 crRightBottom = CPWL_Color(COLORTYPE_GRAY, 0.75);
1085 break;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001086 default:
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001087 break;
1088 }
1089
Tom Sepez281a9ea2016-02-26 14:24:28 -08001090 CFX_FloatRect rcWindow = GetRotatedRect();
1091 CFX_FloatRect rcClient = CPWL_Utils::DeflateRect(rcWindow, fBorderWidth);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001092
1093 CPDF_DefaultAppearance da = pControl->GetDefaultAppearance();
1094 if (da.HasColor()) {
1095 da.GetColor(iColorType, fc);
1096 crText = CPWL_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
1097 }
1098
1099 int32_t nStyle = 0;
1100
1101 CFX_WideString csWCaption = pControl->GetNormalCaption();
1102 if (csWCaption.GetLength() > 0) {
1103 switch (csWCaption[0]) {
1104 case L'l':
1105 nStyle = PCS_CIRCLE;
1106 break;
1107 case L'8':
1108 nStyle = PCS_CROSS;
1109 break;
1110 case L'u':
1111 nStyle = PCS_DIAMOND;
1112 break;
1113 case L'n':
1114 nStyle = PCS_SQUARE;
1115 break;
1116 case L'H':
1117 nStyle = PCS_STAR;
1118 break;
1119 default: // L'4'
1120 nStyle = PCS_CHECK;
1121 break;
1122 }
1123 } else {
1124 nStyle = PCS_CHECK;
1125 }
1126
1127 CFX_ByteString csAP_N_ON =
1128 CPWL_Utils::GetRectFillAppStream(rcWindow, crBackground) +
1129 CPWL_Utils::GetBorderAppStream(rcWindow, fBorderWidth, crBorder,
1130 crLeftTop, crRightBottom, nBorderStyle,
1131 dsBorder);
1132
1133 CFX_ByteString csAP_N_OFF = csAP_N_ON;
1134
1135 switch (nBorderStyle) {
dsinclair92cb5e52016-05-16 11:38:28 -07001136 case BorderStyle::BEVELED: {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001137 CPWL_Color crTemp = crLeftTop;
1138 crLeftTop = crRightBottom;
1139 crRightBottom = crTemp;
dsinclair92cb5e52016-05-16 11:38:28 -07001140 break;
1141 }
1142 case BorderStyle::INSET: {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001143 crLeftTop = CPWL_Color(COLORTYPE_GRAY, 0);
1144 crRightBottom = CPWL_Color(COLORTYPE_GRAY, 1);
1145 break;
dsinclair92cb5e52016-05-16 11:38:28 -07001146 }
1147 default:
1148 break;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001149 }
1150
1151 CFX_ByteString csAP_D_ON =
1152 CPWL_Utils::GetRectFillAppStream(
1153 rcWindow, CPWL_Utils::SubstractColor(crBackground, 0.25f)) +
1154 CPWL_Utils::GetBorderAppStream(rcWindow, fBorderWidth, crBorder,
1155 crLeftTop, crRightBottom, nBorderStyle,
1156 dsBorder);
1157
1158 CFX_ByteString csAP_D_OFF = csAP_D_ON;
1159
1160 csAP_N_ON += CPWL_Utils::GetCheckBoxAppStream(rcClient, nStyle, crText);
1161 csAP_D_ON += CPWL_Utils::GetCheckBoxAppStream(rcClient, nStyle, crText);
1162
1163 WriteAppearance("N", GetRotatedRect(), GetMatrix(), csAP_N_ON,
1164 pControl->GetCheckedAPState());
1165 WriteAppearance("N", GetRotatedRect(), GetMatrix(), csAP_N_OFF, "Off");
1166
1167 WriteAppearance("D", GetRotatedRect(), GetMatrix(), csAP_D_ON,
1168 pControl->GetCheckedAPState());
1169 WriteAppearance("D", GetRotatedRect(), GetMatrix(), csAP_D_OFF, "Off");
1170
1171 CFX_ByteString csAS = GetAppState();
1172 if (csAS.IsEmpty())
1173 SetAppState("Off");
1174}
1175
1176void CPDFSDK_Widget::ResetAppearance_RadioButton() {
1177 CPDF_FormControl* pControl = GetFormControl();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001178 CPWL_Color crBackground, crBorder, crText;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001179 int iColorType;
1180 FX_FLOAT fc[4];
1181
1182 pControl->GetOriginalBackgroundColor(iColorType, fc);
1183 if (iColorType > 0)
1184 crBackground = CPWL_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
1185
1186 pControl->GetOriginalBorderColor(iColorType, fc);
1187 if (iColorType > 0)
1188 crBorder = CPWL_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
1189
1190 FX_FLOAT fBorderWidth = (FX_FLOAT)GetBorderWidth();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001191 CPWL_Dash dsBorder(3, 0, 0);
1192 CPWL_Color crLeftTop, crRightBottom;
1193
dsinclair92cb5e52016-05-16 11:38:28 -07001194 BorderStyle nBorderStyle = GetBorderStyle();
1195 switch (nBorderStyle) {
1196 case BorderStyle::DASH:
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001197 dsBorder = CPWL_Dash(3, 3, 0);
1198 break;
dsinclair92cb5e52016-05-16 11:38:28 -07001199 case BorderStyle::BEVELED:
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001200 fBorderWidth *= 2;
1201 crLeftTop = CPWL_Color(COLORTYPE_GRAY, 1);
1202 crRightBottom = CPWL_Utils::DevideColor(crBackground, 2);
1203 break;
dsinclair92cb5e52016-05-16 11:38:28 -07001204 case BorderStyle::INSET:
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001205 fBorderWidth *= 2;
1206 crLeftTop = CPWL_Color(COLORTYPE_GRAY, 0.5);
1207 crRightBottom = CPWL_Color(COLORTYPE_GRAY, 0.75);
1208 break;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001209 default:
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001210 break;
1211 }
1212
Tom Sepez281a9ea2016-02-26 14:24:28 -08001213 CFX_FloatRect rcWindow = GetRotatedRect();
1214 CFX_FloatRect rcClient = CPWL_Utils::DeflateRect(rcWindow, fBorderWidth);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001215
1216 CPDF_DefaultAppearance da = pControl->GetDefaultAppearance();
1217 if (da.HasColor()) {
1218 da.GetColor(iColorType, fc);
1219 crText = CPWL_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
1220 }
1221
1222 int32_t nStyle = 0;
1223
1224 CFX_WideString csWCaption = pControl->GetNormalCaption();
1225 if (csWCaption.GetLength() > 0) {
1226 switch (csWCaption[0]) {
1227 default: // L'l':
1228 nStyle = PCS_CIRCLE;
1229 break;
1230 case L'8':
1231 nStyle = PCS_CROSS;
1232 break;
1233 case L'u':
1234 nStyle = PCS_DIAMOND;
1235 break;
1236 case L'n':
1237 nStyle = PCS_SQUARE;
1238 break;
1239 case L'H':
1240 nStyle = PCS_STAR;
1241 break;
1242 case L'4':
1243 nStyle = PCS_CHECK;
1244 break;
1245 }
1246 } else {
1247 nStyle = PCS_CIRCLE;
1248 }
1249
1250 CFX_ByteString csAP_N_ON;
1251
Tom Sepez281a9ea2016-02-26 14:24:28 -08001252 CFX_FloatRect rcCenter =
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001253 CPWL_Utils::DeflateRect(CPWL_Utils::GetCenterSquare(rcWindow), 1.0f);
1254
1255 if (nStyle == PCS_CIRCLE) {
dsinclair92cb5e52016-05-16 11:38:28 -07001256 if (nBorderStyle == BorderStyle::BEVELED) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001257 crLeftTop = CPWL_Color(COLORTYPE_GRAY, 1);
1258 crRightBottom = CPWL_Utils::SubstractColor(crBackground, 0.25f);
dsinclair92cb5e52016-05-16 11:38:28 -07001259 } else if (nBorderStyle == BorderStyle::INSET) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001260 crLeftTop = CPWL_Color(COLORTYPE_GRAY, 0.5f);
1261 crRightBottom = CPWL_Color(COLORTYPE_GRAY, 0.75f);
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001262 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001263
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001264 csAP_N_ON = CPWL_Utils::GetCircleFillAppStream(rcCenter, crBackground) +
1265 CPWL_Utils::GetCircleBorderAppStream(
1266 rcCenter, fBorderWidth, crBorder, crLeftTop, crRightBottom,
1267 nBorderStyle, dsBorder);
1268 } else {
1269 csAP_N_ON = CPWL_Utils::GetRectFillAppStream(rcWindow, crBackground) +
1270 CPWL_Utils::GetBorderAppStream(rcWindow, fBorderWidth, crBorder,
1271 crLeftTop, crRightBottom,
1272 nBorderStyle, dsBorder);
1273 }
1274
1275 CFX_ByteString csAP_N_OFF = csAP_N_ON;
1276
1277 switch (nBorderStyle) {
dsinclair92cb5e52016-05-16 11:38:28 -07001278 case BorderStyle::BEVELED: {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001279 CPWL_Color crTemp = crLeftTop;
1280 crLeftTop = crRightBottom;
1281 crRightBottom = crTemp;
dsinclair92cb5e52016-05-16 11:38:28 -07001282 break;
1283 }
1284 case BorderStyle::INSET: {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001285 crLeftTop = CPWL_Color(COLORTYPE_GRAY, 0);
1286 crRightBottom = CPWL_Color(COLORTYPE_GRAY, 1);
1287 break;
dsinclair92cb5e52016-05-16 11:38:28 -07001288 }
1289 default:
1290 break;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001291 }
1292
1293 CFX_ByteString csAP_D_ON;
1294
1295 if (nStyle == PCS_CIRCLE) {
1296 CPWL_Color crBK = CPWL_Utils::SubstractColor(crBackground, 0.25f);
dsinclair92cb5e52016-05-16 11:38:28 -07001297 if (nBorderStyle == BorderStyle::BEVELED) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001298 crLeftTop = CPWL_Utils::SubstractColor(crBackground, 0.25f);
1299 crRightBottom = CPWL_Color(COLORTYPE_GRAY, 1);
1300 crBK = crBackground;
dsinclair92cb5e52016-05-16 11:38:28 -07001301 } else if (nBorderStyle == BorderStyle::INSET) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001302 crLeftTop = CPWL_Color(COLORTYPE_GRAY, 0);
1303 crRightBottom = CPWL_Color(COLORTYPE_GRAY, 1);
1304 }
1305
1306 csAP_D_ON = CPWL_Utils::GetCircleFillAppStream(rcCenter, crBK) +
1307 CPWL_Utils::GetCircleBorderAppStream(
1308 rcCenter, fBorderWidth, crBorder, crLeftTop, crRightBottom,
1309 nBorderStyle, dsBorder);
1310 } else {
1311 csAP_D_ON = CPWL_Utils::GetRectFillAppStream(
1312 rcWindow, CPWL_Utils::SubstractColor(crBackground, 0.25f)) +
1313 CPWL_Utils::GetBorderAppStream(rcWindow, fBorderWidth, crBorder,
1314 crLeftTop, crRightBottom,
1315 nBorderStyle, dsBorder);
1316 }
1317
1318 CFX_ByteString csAP_D_OFF = csAP_D_ON;
1319
1320 csAP_N_ON += CPWL_Utils::GetRadioButtonAppStream(rcClient, nStyle, crText);
1321 csAP_D_ON += CPWL_Utils::GetRadioButtonAppStream(rcClient, nStyle, crText);
1322
1323 WriteAppearance("N", GetRotatedRect(), GetMatrix(), csAP_N_ON,
1324 pControl->GetCheckedAPState());
1325 WriteAppearance("N", GetRotatedRect(), GetMatrix(), csAP_N_OFF, "Off");
1326
1327 WriteAppearance("D", GetRotatedRect(), GetMatrix(), csAP_D_ON,
1328 pControl->GetCheckedAPState());
1329 WriteAppearance("D", GetRotatedRect(), GetMatrix(), csAP_D_OFF, "Off");
1330
1331 CFX_ByteString csAS = GetAppState();
1332 if (csAS.IsEmpty())
1333 SetAppState("Off");
1334}
1335
1336void CPDFSDK_Widget::ResetAppearance_ComboBox(const FX_WCHAR* sValue) {
1337 CPDF_FormControl* pControl = GetFormControl();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001338 CPDF_FormField* pField = pControl->GetField();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001339 CFX_ByteTextBuf sBody, sLines;
1340
Tom Sepez281a9ea2016-02-26 14:24:28 -08001341 CFX_FloatRect rcClient = GetClientRect();
1342 CFX_FloatRect rcButton = rcClient;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001343 rcButton.left = rcButton.right - 13;
1344 rcButton.Normalize();
1345
thestig732f6a02016-05-12 10:41:56 -07001346 IFX_Edit* pEdit = IFX_Edit::NewEdit();
1347 pEdit->EnableRefresh(FALSE);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001348
thestig732f6a02016-05-12 10:41:56 -07001349 CPDFSDK_Document* pDoc = m_pInterForm->GetDocument();
1350 CPDFDoc_Environment* pEnv = pDoc->GetEnv();
1351 CBA_FontMap font_map(this, pEnv->GetSysHandler());
1352 pEdit->SetFontMap(&font_map);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001353
thestig732f6a02016-05-12 10:41:56 -07001354 CFX_FloatRect rcEdit = rcClient;
1355 rcEdit.right = rcButton.left;
1356 rcEdit.Normalize();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001357
thestig732f6a02016-05-12 10:41:56 -07001358 pEdit->SetPlateRect(rcEdit);
1359 pEdit->SetAlignmentV(1);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001360
thestig732f6a02016-05-12 10:41:56 -07001361 FX_FLOAT fFontSize = GetFontSize();
1362 if (IsFloatZero(fFontSize))
1363 pEdit->SetAutoFontSize(TRUE);
1364 else
1365 pEdit->SetFontSize(fFontSize);
1366
1367 pEdit->Initialize();
1368
1369 if (sValue) {
1370 pEdit->SetText(sValue);
1371 } else {
1372 int32_t nCurSel = pField->GetSelectedIndex(0);
1373
1374 if (nCurSel < 0)
1375 pEdit->SetText(pField->GetValue().c_str());
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001376 else
thestig732f6a02016-05-12 10:41:56 -07001377 pEdit->SetText(pField->GetOptionLabel(nCurSel).c_str());
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001378 }
1379
thestig732f6a02016-05-12 10:41:56 -07001380 CFX_FloatRect rcContent = pEdit->GetContentRect();
1381
1382 CFX_ByteString sEdit =
1383 CPWL_Utils::GetEditAppStream(pEdit, CFX_FloatPoint(0.0f, 0.0f));
1384 if (sEdit.GetLength() > 0) {
1385 sBody << "/Tx BMC\n"
1386 << "q\n";
1387 if (rcContent.Width() > rcEdit.Width() ||
1388 rcContent.Height() > rcEdit.Height()) {
1389 sBody << rcEdit.left << " " << rcEdit.bottom << " " << rcEdit.Width()
1390 << " " << rcEdit.Height() << " re\nW\nn\n";
1391 }
1392
1393 CPWL_Color crText = GetTextPWLColor();
1394 sBody << "BT\n"
1395 << CPWL_Utils::GetColorAppStream(crText) << sEdit << "ET\n"
1396 << "Q\nEMC\n";
1397 }
1398
1399 IFX_Edit::DelEdit(pEdit);
1400
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001401 sBody << CPWL_Utils::GetDropButtonAppStream(rcButton);
1402
1403 CFX_ByteString sAP = GetBackgroundAppStream() + GetBorderAppStream() +
tsepez8e4c5052016-04-14 13:42:44 -07001404 sLines.AsStringC() + sBody.AsStringC();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001405
1406 WriteAppearance("N", GetRotatedRect(), GetMatrix(), sAP);
1407}
1408
1409void CPDFSDK_Widget::ResetAppearance_ListBox() {
1410 CPDF_FormControl* pControl = GetFormControl();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001411 CPDF_FormField* pField = pControl->GetField();
Tom Sepez281a9ea2016-02-26 14:24:28 -08001412 CFX_FloatRect rcClient = GetClientRect();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001413 CFX_ByteTextBuf sBody, sLines;
1414
thestig732f6a02016-05-12 10:41:56 -07001415 IFX_Edit* pEdit = IFX_Edit::NewEdit();
1416 pEdit->EnableRefresh(FALSE);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001417
thestig732f6a02016-05-12 10:41:56 -07001418 CPDFSDK_Document* pDoc = m_pInterForm->GetDocument();
1419 CPDFDoc_Environment* pEnv = pDoc->GetEnv();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001420
thestig732f6a02016-05-12 10:41:56 -07001421 CBA_FontMap font_map(this, pEnv->GetSysHandler());
1422 pEdit->SetFontMap(&font_map);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001423
thestig732f6a02016-05-12 10:41:56 -07001424 pEdit->SetPlateRect(CFX_FloatRect(rcClient.left, 0.0f, rcClient.right, 0.0f));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001425
thestig732f6a02016-05-12 10:41:56 -07001426 FX_FLOAT fFontSize = GetFontSize();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001427
thestig594b20b2016-05-12 21:56:43 -07001428 pEdit->SetFontSize(IsFloatZero(fFontSize) ? 12.0f : fFontSize);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001429
thestig732f6a02016-05-12 10:41:56 -07001430 pEdit->Initialize();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001431
thestig732f6a02016-05-12 10:41:56 -07001432 CFX_ByteTextBuf sList;
1433 FX_FLOAT fy = rcClient.top;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001434
thestig732f6a02016-05-12 10:41:56 -07001435 int32_t nTop = pField->GetTopVisibleIndex();
1436 int32_t nCount = pField->CountOptions();
1437 int32_t nSelCount = pField->CountSelectedItems();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001438
thestig594b20b2016-05-12 21:56:43 -07001439 for (int32_t i = nTop; i < nCount; ++i) {
1440 bool bSelected = false;
1441 for (int32_t j = 0; j < nSelCount; ++j) {
thestig732f6a02016-05-12 10:41:56 -07001442 if (pField->GetSelectedIndex(j) == i) {
thestig594b20b2016-05-12 21:56:43 -07001443 bSelected = true;
thestig732f6a02016-05-12 10:41:56 -07001444 break;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001445 }
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001446 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001447
thestig732f6a02016-05-12 10:41:56 -07001448 pEdit->SetText(pField->GetOptionLabel(i).c_str());
1449
1450 CFX_FloatRect rcContent = pEdit->GetContentRect();
1451 FX_FLOAT fItemHeight = rcContent.Height();
1452
1453 if (bSelected) {
1454 CFX_FloatRect rcItem =
1455 CFX_FloatRect(rcClient.left, fy - fItemHeight, rcClient.right, fy);
1456 sList << "q\n"
1457 << CPWL_Utils::GetColorAppStream(
1458 CPWL_Color(COLORTYPE_RGB, 0, 51.0f / 255.0f,
1459 113.0f / 255.0f),
1460 TRUE)
1461 << rcItem.left << " " << rcItem.bottom << " " << rcItem.Width()
1462 << " " << rcItem.Height() << " re f\n"
1463 << "Q\n";
1464
1465 sList << "BT\n"
1466 << CPWL_Utils::GetColorAppStream(CPWL_Color(COLORTYPE_GRAY, 1),
1467 TRUE)
1468 << CPWL_Utils::GetEditAppStream(pEdit, CFX_FloatPoint(0.0f, fy))
1469 << "ET\n";
1470 } else {
1471 CPWL_Color crText = GetTextPWLColor();
1472 sList << "BT\n"
1473 << CPWL_Utils::GetColorAppStream(crText, TRUE)
1474 << CPWL_Utils::GetEditAppStream(pEdit, CFX_FloatPoint(0.0f, fy))
1475 << "ET\n";
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001476 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001477
thestig732f6a02016-05-12 10:41:56 -07001478 fy -= fItemHeight;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001479 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001480
thestig732f6a02016-05-12 10:41:56 -07001481 if (sList.GetSize() > 0) {
1482 sBody << "/Tx BMC\n"
1483 << "q\n"
1484 << rcClient.left << " " << rcClient.bottom << " " << rcClient.Width()
1485 << " " << rcClient.Height() << " re\nW\nn\n";
1486 sBody << sList << "Q\nEMC\n";
1487 }
1488
1489 IFX_Edit::DelEdit(pEdit);
1490
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001491 CFX_ByteString sAP = GetBackgroundAppStream() + GetBorderAppStream() +
tsepez8e4c5052016-04-14 13:42:44 -07001492 sLines.AsStringC() + sBody.AsStringC();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001493
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001494 WriteAppearance("N", GetRotatedRect(), GetMatrix(), sAP);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001495}
1496
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001497void CPDFSDK_Widget::ResetAppearance_TextField(const FX_WCHAR* sValue) {
1498 CPDF_FormControl* pControl = GetFormControl();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001499 CPDF_FormField* pField = pControl->GetField();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001500 CFX_ByteTextBuf sBody, sLines;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001501
thestig732f6a02016-05-12 10:41:56 -07001502 IFX_Edit* pEdit = IFX_Edit::NewEdit();
1503 pEdit->EnableRefresh(FALSE);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001504
thestig732f6a02016-05-12 10:41:56 -07001505 CPDFSDK_Document* pDoc = m_pInterForm->GetDocument();
1506 CPDFDoc_Environment* pEnv = pDoc->GetEnv();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001507
thestig732f6a02016-05-12 10:41:56 -07001508 CBA_FontMap font_map(this, pEnv->GetSysHandler());
1509 pEdit->SetFontMap(&font_map);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001510
thestig732f6a02016-05-12 10:41:56 -07001511 CFX_FloatRect rcClient = GetClientRect();
1512 pEdit->SetPlateRect(rcClient);
1513 pEdit->SetAlignmentH(pControl->GetControlAlignment());
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001514
thestig732f6a02016-05-12 10:41:56 -07001515 uint32_t dwFieldFlags = pField->GetFieldFlags();
1516 FX_BOOL bMultiLine = (dwFieldFlags >> 12) & 1;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001517
thestig732f6a02016-05-12 10:41:56 -07001518 if (bMultiLine) {
1519 pEdit->SetMultiLine(TRUE);
1520 pEdit->SetAutoReturn(TRUE);
1521 } else {
1522 pEdit->SetAlignmentV(1);
1523 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001524
thestig732f6a02016-05-12 10:41:56 -07001525 uint16_t subWord = 0;
1526 if ((dwFieldFlags >> 13) & 1) {
1527 subWord = '*';
1528 pEdit->SetPasswordChar(subWord);
1529 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001530
thestig732f6a02016-05-12 10:41:56 -07001531 int nMaxLen = pField->GetMaxLen();
1532 FX_BOOL bCharArray = (dwFieldFlags >> 24) & 1;
1533 FX_FLOAT fFontSize = GetFontSize();
Bo Xufdc00a72014-10-28 23:03:33 -07001534
Tom Sepez51da0932015-11-25 16:05:49 -08001535#ifdef PDF_ENABLE_XFA
thestig732f6a02016-05-12 10:41:56 -07001536 CFX_WideString sValueTmp;
1537 if (!sValue && GetMixXFAWidget()) {
1538 sValueTmp = GetValue(TRUE);
1539 sValue = sValueTmp.c_str();
1540 }
Tom Sepez40e9ff32015-11-30 12:39:54 -08001541#endif // PDF_ENABLE_XFA
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001542
thestig732f6a02016-05-12 10:41:56 -07001543 if (nMaxLen > 0) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001544 if (bCharArray) {
thestig732f6a02016-05-12 10:41:56 -07001545 pEdit->SetCharArray(nMaxLen);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001546
thestig732f6a02016-05-12 10:41:56 -07001547 if (IsFloatZero(fFontSize)) {
1548 fFontSize = CPWL_Edit::GetCharArrayAutoFontSize(font_map.GetPDFFont(0),
1549 rcClient, nMaxLen);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001550 }
thestig732f6a02016-05-12 10:41:56 -07001551 } else {
1552 if (sValue)
1553 nMaxLen = wcslen((const wchar_t*)sValue);
1554 pEdit->SetLimitChar(nMaxLen);
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001555 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001556 }
1557
thestig732f6a02016-05-12 10:41:56 -07001558 if (IsFloatZero(fFontSize))
1559 pEdit->SetAutoFontSize(TRUE);
1560 else
1561 pEdit->SetFontSize(fFontSize);
1562
1563 pEdit->Initialize();
1564
1565 if (sValue)
1566 pEdit->SetText(sValue);
1567 else
1568 pEdit->SetText(pField->GetValue().c_str());
1569
1570 CFX_FloatRect rcContent = pEdit->GetContentRect();
1571
1572 CFX_ByteString sEdit = CPWL_Utils::GetEditAppStream(
1573 pEdit, CFX_FloatPoint(0.0f, 0.0f), NULL, !bCharArray, subWord);
1574
1575 if (sEdit.GetLength() > 0) {
1576 sBody << "/Tx BMC\n"
1577 << "q\n";
1578 if (rcContent.Width() > rcClient.Width() ||
1579 rcContent.Height() > rcClient.Height()) {
1580 sBody << rcClient.left << " " << rcClient.bottom << " "
1581 << rcClient.Width() << " " << rcClient.Height() << " re\nW\nn\n";
1582 }
1583 CPWL_Color crText = GetTextPWLColor();
1584 sBody << "BT\n"
1585 << CPWL_Utils::GetColorAppStream(crText) << sEdit << "ET\n"
1586 << "Q\nEMC\n";
1587 }
1588
1589 if (bCharArray) {
1590 switch (GetBorderStyle()) {
dsinclair92cb5e52016-05-16 11:38:28 -07001591 case BorderStyle::SOLID: {
thestig732f6a02016-05-12 10:41:56 -07001592 CFX_ByteString sColor =
1593 CPWL_Utils::GetColorAppStream(GetBorderPWLColor(), FALSE);
1594 if (sColor.GetLength() > 0) {
1595 sLines << "q\n"
1596 << GetBorderWidth() << " w\n"
1597 << CPWL_Utils::GetColorAppStream(GetBorderPWLColor(), FALSE)
1598 << " 2 J 0 j\n";
1599
thestig594b20b2016-05-12 21:56:43 -07001600 for (int32_t i = 1; i < nMaxLen; ++i) {
thestig732f6a02016-05-12 10:41:56 -07001601 sLines << rcClient.left +
1602 ((rcClient.right - rcClient.left) / nMaxLen) * i
1603 << " " << rcClient.bottom << " m\n"
1604 << rcClient.left +
1605 ((rcClient.right - rcClient.left) / nMaxLen) * i
1606 << " " << rcClient.top << " l S\n";
1607 }
1608
1609 sLines << "Q\n";
1610 }
dsinclair92cb5e52016-05-16 11:38:28 -07001611 break;
1612 }
1613 case BorderStyle::DASH: {
thestig732f6a02016-05-12 10:41:56 -07001614 CFX_ByteString sColor =
1615 CPWL_Utils::GetColorAppStream(GetBorderPWLColor(), FALSE);
1616 if (sColor.GetLength() > 0) {
1617 CPWL_Dash dsBorder = CPWL_Dash(3, 3, 0);
1618
1619 sLines << "q\n"
1620 << GetBorderWidth() << " w\n"
1621 << CPWL_Utils::GetColorAppStream(GetBorderPWLColor(), FALSE)
1622 << "[" << dsBorder.nDash << " " << dsBorder.nGap << "] "
1623 << dsBorder.nPhase << " d\n";
1624
thestig594b20b2016-05-12 21:56:43 -07001625 for (int32_t i = 1; i < nMaxLen; ++i) {
thestig732f6a02016-05-12 10:41:56 -07001626 sLines << rcClient.left +
1627 ((rcClient.right - rcClient.left) / nMaxLen) * i
1628 << " " << rcClient.bottom << " m\n"
1629 << rcClient.left +
1630 ((rcClient.right - rcClient.left) / nMaxLen) * i
1631 << " " << rcClient.top << " l S\n";
1632 }
1633
1634 sLines << "Q\n";
1635 }
dsinclair92cb5e52016-05-16 11:38:28 -07001636 break;
1637 }
1638 default:
1639 break;
thestig732f6a02016-05-12 10:41:56 -07001640 }
1641 }
1642
1643 IFX_Edit::DelEdit(pEdit);
1644
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001645 CFX_ByteString sAP = GetBackgroundAppStream() + GetBorderAppStream() +
tsepez8e4c5052016-04-14 13:42:44 -07001646 sLines.AsStringC() + sBody.AsStringC();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001647 WriteAppearance("N", GetRotatedRect(), GetMatrix(), sAP);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001648}
1649
Tom Sepez281a9ea2016-02-26 14:24:28 -08001650CFX_FloatRect CPDFSDK_Widget::GetClientRect() const {
1651 CFX_FloatRect rcWindow = GetRotatedRect();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001652 FX_FLOAT fBorderWidth = (FX_FLOAT)GetBorderWidth();
1653 switch (GetBorderStyle()) {
dsinclair92cb5e52016-05-16 11:38:28 -07001654 case BorderStyle::BEVELED:
1655 case BorderStyle::INSET:
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001656 fBorderWidth *= 2.0f;
1657 break;
dsinclair92cb5e52016-05-16 11:38:28 -07001658 default:
1659 break;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001660 }
1661
1662 return CPWL_Utils::DeflateRect(rcWindow, fBorderWidth);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001663}
1664
Tom Sepez281a9ea2016-02-26 14:24:28 -08001665CFX_FloatRect CPDFSDK_Widget::GetRotatedRect() const {
1666 CFX_FloatRect rectAnnot = GetRect();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001667 FX_FLOAT fWidth = rectAnnot.right - rectAnnot.left;
1668 FX_FLOAT fHeight = rectAnnot.top - rectAnnot.bottom;
1669
1670 CPDF_FormControl* pControl = GetFormControl();
Tom Sepez281a9ea2016-02-26 14:24:28 -08001671 CFX_FloatRect rcPDFWindow;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001672 switch (abs(pControl->GetRotation() % 360)) {
1673 case 0:
1674 case 180:
1675 default:
Tom Sepez281a9ea2016-02-26 14:24:28 -08001676 rcPDFWindow = CFX_FloatRect(0, 0, fWidth, fHeight);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001677 break;
1678 case 90:
1679 case 270:
Tom Sepez281a9ea2016-02-26 14:24:28 -08001680 rcPDFWindow = CFX_FloatRect(0, 0, fHeight, fWidth);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001681 break;
1682 }
1683
1684 return rcPDFWindow;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001685}
1686
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001687CFX_ByteString CPDFSDK_Widget::GetBackgroundAppStream() const {
1688 CPWL_Color crBackground = GetFillPWLColor();
1689 if (crBackground.nColorType != COLORTYPE_TRANSPARENT) {
1690 return CPWL_Utils::GetRectFillAppStream(GetRotatedRect(), crBackground);
1691 }
1692 return "";
Bo Xufdc00a72014-10-28 23:03:33 -07001693}
1694
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001695CFX_ByteString CPDFSDK_Widget::GetBorderAppStream() const {
Tom Sepez281a9ea2016-02-26 14:24:28 -08001696 CFX_FloatRect rcWindow = GetRotatedRect();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001697 CPWL_Color crBorder = GetBorderPWLColor();
1698 CPWL_Color crBackground = GetFillPWLColor();
1699 CPWL_Color crLeftTop, crRightBottom;
1700
1701 FX_FLOAT fBorderWidth = (FX_FLOAT)GetBorderWidth();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001702 CPWL_Dash dsBorder(3, 0, 0);
1703
dsinclair92cb5e52016-05-16 11:38:28 -07001704 BorderStyle nBorderStyle = GetBorderStyle();
1705 switch (nBorderStyle) {
1706 case BorderStyle::DASH:
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001707 dsBorder = CPWL_Dash(3, 3, 0);
1708 break;
dsinclair92cb5e52016-05-16 11:38:28 -07001709 case BorderStyle::BEVELED:
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001710 fBorderWidth *= 2;
1711 crLeftTop = CPWL_Color(COLORTYPE_GRAY, 1);
1712 crRightBottom = CPWL_Utils::DevideColor(crBackground, 2);
1713 break;
dsinclair92cb5e52016-05-16 11:38:28 -07001714 case BorderStyle::INSET:
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001715 fBorderWidth *= 2;
1716 crLeftTop = CPWL_Color(COLORTYPE_GRAY, 0.5);
1717 crRightBottom = CPWL_Color(COLORTYPE_GRAY, 0.75);
1718 break;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001719 default:
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001720 break;
1721 }
1722
1723 return CPWL_Utils::GetBorderAppStream(rcWindow, fBorderWidth, crBorder,
1724 crLeftTop, crRightBottom, nBorderStyle,
1725 dsBorder);
Bo Xufdc00a72014-10-28 23:03:33 -07001726}
1727
Tom Sepez60d909e2015-12-10 15:34:55 -08001728CFX_Matrix CPDFSDK_Widget::GetMatrix() const {
1729 CFX_Matrix mt;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001730 CPDF_FormControl* pControl = GetFormControl();
Tom Sepez281a9ea2016-02-26 14:24:28 -08001731 CFX_FloatRect rcAnnot = GetRect();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001732 FX_FLOAT fWidth = rcAnnot.right - rcAnnot.left;
1733 FX_FLOAT fHeight = rcAnnot.top - rcAnnot.bottom;
1734
1735 switch (abs(pControl->GetRotation() % 360)) {
1736 case 0:
1737 default:
Tom Sepez60d909e2015-12-10 15:34:55 -08001738 mt = CFX_Matrix(1, 0, 0, 1, 0, 0);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001739 break;
1740 case 90:
Tom Sepez60d909e2015-12-10 15:34:55 -08001741 mt = CFX_Matrix(0, 1, -1, 0, fWidth, 0);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001742 break;
1743 case 180:
Tom Sepez60d909e2015-12-10 15:34:55 -08001744 mt = CFX_Matrix(-1, 0, 0, -1, fWidth, fHeight);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001745 break;
1746 case 270:
Tom Sepez60d909e2015-12-10 15:34:55 -08001747 mt = CFX_Matrix(0, -1, 1, 0, 0, fHeight);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001748 break;
1749 }
1750
1751 return mt;
Bo Xufdc00a72014-10-28 23:03:33 -07001752}
1753
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001754CPWL_Color CPDFSDK_Widget::GetTextPWLColor() const {
1755 CPWL_Color crText = CPWL_Color(COLORTYPE_GRAY, 0);
1756
1757 CPDF_FormControl* pFormCtrl = GetFormControl();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001758 CPDF_DefaultAppearance da = pFormCtrl->GetDefaultAppearance();
1759 if (da.HasColor()) {
1760 int32_t iColorType;
1761 FX_FLOAT fc[4];
1762 da.GetColor(iColorType, fc);
1763 crText = CPWL_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
1764 }
1765
1766 return crText;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001767}
1768
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001769CPWL_Color CPDFSDK_Widget::GetBorderPWLColor() const {
1770 CPWL_Color crBorder;
1771
1772 CPDF_FormControl* pFormCtrl = GetFormControl();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001773 int32_t iColorType;
1774 FX_FLOAT fc[4];
1775 pFormCtrl->GetOriginalBorderColor(iColorType, fc);
1776 if (iColorType > 0)
1777 crBorder = CPWL_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
1778
1779 return crBorder;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001780}
1781
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001782CPWL_Color CPDFSDK_Widget::GetFillPWLColor() const {
1783 CPWL_Color crFill;
1784
1785 CPDF_FormControl* pFormCtrl = GetFormControl();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001786 int32_t iColorType;
1787 FX_FLOAT fc[4];
1788 pFormCtrl->GetOriginalBackgroundColor(iColorType, fc);
1789 if (iColorType > 0)
1790 crFill = CPWL_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
1791
1792 return crFill;
Bo Xufdc00a72014-10-28 23:03:33 -07001793}
1794
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001795void CPDFSDK_Widget::AddImageToAppearance(const CFX_ByteString& sAPType,
1796 CPDF_Stream* pImage) {
Tom Sepez33420902015-10-13 15:00:10 -07001797 CPDF_Document* pDoc = m_pPageView->GetPDFDocument();
Lei Zhang96660d62015-12-14 18:27:25 -08001798 ASSERT(pDoc);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001799
Wei Li9b761132016-01-29 15:44:20 -08001800 CPDF_Dictionary* pAPDict = m_pAnnot->GetAnnotDict()->GetDictBy("AP");
tsepez7b1ccf92016-04-14 11:04:57 -07001801 CPDF_Stream* pStream = pAPDict->GetStreamBy(sAPType);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001802 CPDF_Dictionary* pStreamDict = pStream->GetDict();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001803 CFX_ByteString sImageAlias = "IMG";
1804
1805 if (CPDF_Dictionary* pImageDict = pImage->GetDict()) {
Wei Li9b761132016-01-29 15:44:20 -08001806 sImageAlias = pImageDict->GetStringBy("Name");
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001807 if (sImageAlias.IsEmpty())
1808 sImageAlias = "IMG";
1809 }
1810
Wei Li9b761132016-01-29 15:44:20 -08001811 CPDF_Dictionary* pStreamResList = pStreamDict->GetDictBy("Resources");
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001812 if (!pStreamResList) {
Tom Sepezae51c812015-08-05 12:34:06 -07001813 pStreamResList = new CPDF_Dictionary();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001814 pStreamDict->SetAt("Resources", pStreamResList);
1815 }
1816
1817 if (pStreamResList) {
Tom Sepezae51c812015-08-05 12:34:06 -07001818 CPDF_Dictionary* pXObject = new CPDF_Dictionary;
tsepez7b1ccf92016-04-14 11:04:57 -07001819 pXObject->SetAtReference(sImageAlias, pDoc, pImage);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001820 pStreamResList->SetAt("XObject", pXObject);
1821 }
Bo Xufdc00a72014-10-28 23:03:33 -07001822}
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001823
1824void CPDFSDK_Widget::RemoveAppearance(const CFX_ByteString& sAPType) {
tsepez7b1ccf92016-04-14 11:04:57 -07001825 if (CPDF_Dictionary* pAPDict = m_pAnnot->GetAnnotDict()->GetDictBy("AP"))
1826 pAPDict->RemoveAt(sAPType);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001827}
1828
1829FX_BOOL CPDFSDK_Widget::OnAAction(CPDF_AAction::AActionType type,
1830 PDFSDK_FieldAction& data,
1831 CPDFSDK_PageView* pPageView) {
1832 CPDFSDK_Document* pDocument = pPageView->GetSDKDocument();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001833 CPDFDoc_Environment* pEnv = pDocument->GetEnv();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001834
Tom Sepez40e9ff32015-11-30 12:39:54 -08001835#ifdef PDF_ENABLE_XFA
Tom Sepez540c4362015-11-24 13:33:57 -08001836 CPDFXFA_Document* pDoc = pDocument->GetXFADocument();
dsinclairdf4bc592016-03-31 20:34:43 -07001837 if (CXFA_FFWidget* hWidget = GetMixXFAWidget()) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001838 XFA_EVENTTYPE eEventType = GetXFAEventType(type, data.bWillCommit);
1839
1840 if (eEventType != XFA_EVENT_Unknown) {
dsinclairdf4bc592016-03-31 20:34:43 -07001841 if (CXFA_FFWidgetHandler* pXFAWidgetHandler = GetXFAWidgetHandler()) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001842 CXFA_EventParam param;
1843 param.m_eType = eEventType;
1844 param.m_wsChange = data.sChange;
1845 param.m_iCommitKey = data.nCommitKey;
1846 param.m_bShift = data.bShift;
1847 param.m_iSelStart = data.nSelStart;
1848 param.m_iSelEnd = data.nSelEnd;
1849 param.m_wsFullText = data.sValue;
1850 param.m_bKeyDown = data.bKeyDown;
1851 param.m_bModifier = data.bModifier;
1852 param.m_wsNewText = data.sValue;
1853 if (data.nSelEnd > data.nSelStart)
1854 param.m_wsNewText.Delete(data.nSelStart,
1855 data.nSelEnd - data.nSelStart);
1856 for (int i = data.sChange.GetLength() - 1; i >= 0; i--)
1857 param.m_wsNewText.Insert(data.nSelStart, data.sChange[i]);
1858 param.m_wsPrevText = data.sValue;
1859
dsinclair221caf62016-04-04 12:08:40 -07001860 CXFA_WidgetAcc* pAcc = hWidget->GetDataAcc();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001861 param.m_pTarget = pAcc;
1862 int32_t nRet = pXFAWidgetHandler->ProcessEvent(pAcc, &param);
1863
dsinclairdf4bc592016-03-31 20:34:43 -07001864 if (CXFA_FFDocView* pDocView = pDoc->GetXFADocView()) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001865 pDocView->UpdateDocView();
1866 }
1867
Wei Lie98ac2e2016-03-18 15:43:04 -07001868 if (nRet == XFA_EVENTERROR_Success)
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001869 return TRUE;
1870 }
1871 }
1872 }
Tom Sepez40e9ff32015-11-30 12:39:54 -08001873#endif // PDF_ENABLE_XFA
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001874
1875 CPDF_Action action = GetAAction(type);
Wei Li0fc6b252016-03-01 16:29:41 -08001876 if (action.GetDict() && action.GetType() != CPDF_Action::Unknown) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001877 CPDFSDK_ActionHandler* pActionHandler = pEnv->GetActionHander();
1878 return pActionHandler->DoAction_Field(action, type, pDocument,
1879 GetFormField(), data);
1880 }
1881 return FALSE;
1882}
1883
1884CPDF_Action CPDFSDK_Widget::GetAAction(CPDF_AAction::AActionType eAAT) {
1885 switch (eAAT) {
1886 case CPDF_AAction::CursorEnter:
1887 case CPDF_AAction::CursorExit:
1888 case CPDF_AAction::ButtonDown:
1889 case CPDF_AAction::ButtonUp:
1890 case CPDF_AAction::GetFocus:
1891 case CPDF_AAction::LoseFocus:
1892 case CPDF_AAction::PageOpen:
1893 case CPDF_AAction::PageClose:
1894 case CPDF_AAction::PageVisible:
1895 case CPDF_AAction::PageInvisible:
1896 return CPDFSDK_BAAnnot::GetAAction(eAAT);
1897
1898 case CPDF_AAction::KeyStroke:
1899 case CPDF_AAction::Format:
1900 case CPDF_AAction::Validate:
1901 case CPDF_AAction::Calculate: {
1902 CPDF_FormField* pField = GetFormField();
Wei Li0fc6b252016-03-01 16:29:41 -08001903 if (pField->GetAdditionalAction().GetDict())
1904 return pField->GetAdditionalAction().GetAction(eAAT);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001905 return CPDFSDK_BAAnnot::GetAAction(eAAT);
1906 }
1907 default:
1908 break;
1909 }
1910
1911 return CPDF_Action();
1912}
1913
1914CFX_WideString CPDFSDK_Widget::GetAlternateName() const {
1915 CPDF_FormField* pFormField = GetFormField();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001916 return pFormField->GetAlternateName();
1917}
1918
1919int32_t CPDFSDK_Widget::GetAppearanceAge() const {
1920 return m_nAppAge;
1921}
1922
1923int32_t CPDFSDK_Widget::GetValueAge() const {
1924 return m_nValueAge;
1925}
1926
1927FX_BOOL CPDFSDK_Widget::HitTest(FX_FLOAT pageX, FX_FLOAT pageY) {
1928 CPDF_Annot* pAnnot = GetPDFAnnot();
1929 CFX_FloatRect annotRect;
1930 pAnnot->GetRect(annotRect);
1931 if (annotRect.Contains(pageX, pageY)) {
1932 if (!IsVisible())
1933 return FALSE;
1934
1935 int nFieldFlags = GetFieldFlags();
1936 if ((nFieldFlags & FIELDFLAG_READONLY) == FIELDFLAG_READONLY)
1937 return FALSE;
1938
1939 return TRUE;
1940 }
1941 return FALSE;
1942}
1943
Tom Sepez51da0932015-11-25 16:05:49 -08001944#ifdef PDF_ENABLE_XFA
dsinclairdf4bc592016-03-31 20:34:43 -07001945CPDFSDK_XFAWidget::CPDFSDK_XFAWidget(CXFA_FFWidget* pAnnot,
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001946 CPDFSDK_PageView* pPageView,
1947 CPDFSDK_InterForm* pInterForm)
Dan Sinclairf766ad22016-03-14 13:51:24 -04001948 : CPDFSDK_Annot(pPageView),
1949 m_pInterForm(pInterForm),
1950 m_hXFAWidget(pAnnot) {}
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001951
1952FX_BOOL CPDFSDK_XFAWidget::IsXFAField() {
1953 return TRUE;
1954}
1955
1956CFX_ByteString CPDFSDK_XFAWidget::GetType() const {
1957 return FSDK_XFAWIDGET_TYPENAME;
1958}
1959
Tom Sepez3343d142015-11-02 09:54:54 -08001960CFX_FloatRect CPDFSDK_XFAWidget::GetRect() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001961 CFX_RectF rcBBox;
dsinclair221caf62016-04-04 12:08:40 -07001962 GetXFAWidget()->GetRect(rcBBox);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001963 return CFX_FloatRect(rcBBox.left, rcBBox.top, rcBBox.left + rcBBox.width,
1964 rcBBox.top + rcBBox.height);
1965}
Tom Sepez40e9ff32015-11-30 12:39:54 -08001966#endif // PDF_ENABLE_XFA
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001967
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001968CPDFSDK_InterForm::CPDFSDK_InterForm(CPDFSDK_Document* pDocument)
1969 : m_pDocument(pDocument),
1970 m_pInterForm(NULL),
Tom Sepez51da0932015-11-25 16:05:49 -08001971#ifdef PDF_ENABLE_XFA
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001972 m_bXfaCalculate(TRUE),
1973 m_bXfaValidationsEnabled(TRUE),
Tom Sepez40e9ff32015-11-30 12:39:54 -08001974#endif // PDF_ENABLE_XFA
1975 m_bCalculate(TRUE),
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001976 m_bBusy(FALSE) {
Tom Sepez50d12ad2015-11-24 09:50:51 -08001977 m_pInterForm = new CPDF_InterForm(m_pDocument->GetPDFDocument(), FALSE);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001978 m_pInterForm->SetFormNotify(this);
1979
Tom Sepezae7a9172015-11-23 09:22:46 -08001980 for (int i = 0; i < kNumFieldTypes; ++i)
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001981 m_bNeedHightlight[i] = FALSE;
1982 m_iHighlightAlpha = 0;
1983}
1984
1985CPDFSDK_InterForm::~CPDFSDK_InterForm() {
1986 delete m_pInterForm;
1987 m_pInterForm = nullptr;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001988 m_Map.clear();
Tom Sepez51da0932015-11-25 16:05:49 -08001989#ifdef PDF_ENABLE_XFA
tsepez16a20332016-04-22 14:00:47 -07001990 m_XFAMap.clear();
Tom Sepez40e9ff32015-11-30 12:39:54 -08001991#endif // PDF_ENABLE_XFA
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001992}
1993
1994FX_BOOL CPDFSDK_InterForm::HighlightWidgets() {
1995 return FALSE;
1996}
1997
1998CPDFSDK_Widget* CPDFSDK_InterForm::GetSibling(CPDFSDK_Widget* pWidget,
1999 FX_BOOL bNext) const {
Lei Zhangaa8bf7e2015-12-24 19:13:32 -08002000 std::unique_ptr<CBA_AnnotIterator> pIterator(
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002001 new CBA_AnnotIterator(pWidget->GetPageView(), "Widget", ""));
2002
2003 if (bNext) {
2004 return (CPDFSDK_Widget*)pIterator->GetNextAnnot(pWidget);
2005 }
2006 return (CPDFSDK_Widget*)pIterator->GetPrevAnnot(pWidget);
2007}
2008
2009CPDFSDK_Widget* CPDFSDK_InterForm::GetWidget(CPDF_FormControl* pControl) const {
2010 if (!pControl || !m_pInterForm)
2011 return nullptr;
2012
2013 CPDFSDK_Widget* pWidget = nullptr;
2014 const auto it = m_Map.find(pControl);
2015 if (it != m_Map.end())
2016 pWidget = it->second;
2017
2018 if (pWidget)
2019 return pWidget;
2020
2021 CPDF_Dictionary* pControlDict = pControl->GetWidget();
Tom Sepez50d12ad2015-11-24 09:50:51 -08002022 CPDF_Document* pDocument = m_pDocument->GetPDFDocument();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002023 CPDFSDK_PageView* pPage = nullptr;
2024
Wei Li9b761132016-01-29 15:44:20 -08002025 if (CPDF_Dictionary* pPageDict = pControlDict->GetDictBy("P")) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002026 int nPageIndex = pDocument->GetPageIndex(pPageDict->GetObjNum());
2027 if (nPageIndex >= 0) {
2028 pPage = m_pDocument->GetPageView(nPageIndex);
2029 }
2030 }
2031
2032 if (!pPage) {
2033 int nPageIndex = GetPageIndexByAnnotDict(pDocument, pControlDict);
2034 if (nPageIndex >= 0) {
2035 pPage = m_pDocument->GetPageView(nPageIndex);
2036 }
2037 }
2038
2039 if (!pPage)
2040 return nullptr;
2041 return (CPDFSDK_Widget*)pPage->GetAnnotByDict(pControlDict);
2042}
2043
Lei Zhangd88a3642015-11-10 09:38:57 -08002044void CPDFSDK_InterForm::GetWidgets(
2045 const CFX_WideString& sFieldName,
2046 std::vector<CPDFSDK_Widget*>* widgets) const {
2047 for (int i = 0, sz = m_pInterForm->CountFields(sFieldName); i < sz; ++i) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002048 CPDF_FormField* pFormField = m_pInterForm->GetField(i, sFieldName);
Lei Zhangd88a3642015-11-10 09:38:57 -08002049 ASSERT(pFormField);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002050 GetWidgets(pFormField, widgets);
2051 }
2052}
2053
Lei Zhangd88a3642015-11-10 09:38:57 -08002054void CPDFSDK_InterForm::GetWidgets(
2055 CPDF_FormField* pField,
2056 std::vector<CPDFSDK_Widget*>* widgets) const {
2057 for (int i = 0, sz = pField->CountControls(); i < sz; ++i) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002058 CPDF_FormControl* pFormCtrl = pField->GetControl(i);
Lei Zhangd88a3642015-11-10 09:38:57 -08002059 ASSERT(pFormCtrl);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002060 CPDFSDK_Widget* pWidget = GetWidget(pFormCtrl);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002061 if (pWidget)
Lei Zhangd88a3642015-11-10 09:38:57 -08002062 widgets->push_back(pWidget);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002063 }
2064}
2065
2066int CPDFSDK_InterForm::GetPageIndexByAnnotDict(
2067 CPDF_Document* pDocument,
2068 CPDF_Dictionary* pAnnotDict) const {
Lei Zhang96660d62015-12-14 18:27:25 -08002069 ASSERT(pAnnotDict);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002070
2071 for (int i = 0, sz = pDocument->GetPageCount(); i < sz; i++) {
2072 if (CPDF_Dictionary* pPageDict = pDocument->GetPage(i)) {
Wei Li9b761132016-01-29 15:44:20 -08002073 if (CPDF_Array* pAnnots = pPageDict->GetArrayBy("Annots")) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002074 for (int j = 0, jsz = pAnnots->GetCount(); j < jsz; j++) {
tsepezbd567552016-03-29 14:51:50 -07002075 CPDF_Object* pDict = pAnnots->GetDirectObjectAt(j);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002076 if (pAnnotDict == pDict) {
2077 return i;
2078 }
2079 }
2080 }
2081 }
2082 }
2083
2084 return -1;
2085}
2086
2087void CPDFSDK_InterForm::AddMap(CPDF_FormControl* pControl,
2088 CPDFSDK_Widget* pWidget) {
2089 m_Map[pControl] = pWidget;
2090}
2091
2092void CPDFSDK_InterForm::RemoveMap(CPDF_FormControl* pControl) {
2093 m_Map.erase(pControl);
2094}
2095
Tom Sepez40e9ff32015-11-30 12:39:54 -08002096void CPDFSDK_InterForm::EnableCalculate(FX_BOOL bEnabled) {
2097 m_bCalculate = bEnabled;
2098}
2099
2100FX_BOOL CPDFSDK_InterForm::IsCalculateEnabled() const {
2101 return m_bCalculate;
2102}
2103
Tom Sepez51da0932015-11-25 16:05:49 -08002104#ifdef PDF_ENABLE_XFA
dsinclairdf4bc592016-03-31 20:34:43 -07002105void CPDFSDK_InterForm::AddXFAMap(CXFA_FFWidget* hWidget,
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002106 CPDFSDK_XFAWidget* pWidget) {
dsinclair43854a52016-04-27 12:26:00 -07002107 ASSERT(hWidget);
tsepez16a20332016-04-22 14:00:47 -07002108 m_XFAMap[hWidget] = pWidget;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002109}
2110
dsinclairdf4bc592016-03-31 20:34:43 -07002111void CPDFSDK_InterForm::RemoveXFAMap(CXFA_FFWidget* hWidget) {
dsinclair43854a52016-04-27 12:26:00 -07002112 ASSERT(hWidget);
tsepez16a20332016-04-22 14:00:47 -07002113 m_XFAMap.erase(hWidget);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002114}
2115
dsinclairdf4bc592016-03-31 20:34:43 -07002116CPDFSDK_XFAWidget* CPDFSDK_InterForm::GetXFAWidget(CXFA_FFWidget* hWidget) {
dsinclair43854a52016-04-27 12:26:00 -07002117 ASSERT(hWidget);
tsepez16a20332016-04-22 14:00:47 -07002118 auto it = m_XFAMap.find(hWidget);
2119 return it != m_XFAMap.end() ? it->second : nullptr;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002120}
2121
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002122void CPDFSDK_InterForm::XfaEnableCalculate(FX_BOOL bEnabled) {
2123 m_bXfaCalculate = bEnabled;
2124}
2125FX_BOOL CPDFSDK_InterForm::IsXfaCalculateEnabled() const {
2126 return m_bXfaCalculate;
2127}
2128
2129FX_BOOL CPDFSDK_InterForm::IsXfaValidationsEnabled() {
2130 return m_bXfaValidationsEnabled;
2131}
2132void CPDFSDK_InterForm::XfaSetValidationsEnabled(FX_BOOL bEnabled) {
2133 m_bXfaValidationsEnabled = bEnabled;
Bo Xufdc00a72014-10-28 23:03:33 -07002134}
Tom Sepez40e9ff32015-11-30 12:39:54 -08002135#endif // PDF_ENABLE_XFA
Bo Xufdc00a72014-10-28 23:03:33 -07002136
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002137void CPDFSDK_InterForm::OnCalculate(CPDF_FormField* pFormField) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002138 CPDFDoc_Environment* pEnv = m_pDocument->GetEnv();
2139 ASSERT(pEnv);
2140 if (!pEnv->IsJSInitiated())
2141 return;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07002142
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002143 if (m_bBusy)
2144 return;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07002145
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002146 m_bBusy = TRUE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07002147
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002148 if (IsCalculateEnabled()) {
Tom Sepezba038bc2015-10-08 12:03:00 -07002149 IJS_Runtime* pRuntime = m_pDocument->GetJsRuntime();
Tom Sepez2f2ffec2015-07-23 14:42:09 -07002150 pRuntime->SetReaderDocument(m_pDocument);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07002151
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002152 int nSize = m_pInterForm->CountFieldsInCalculationOrder();
2153 for (int i = 0; i < nSize; i++) {
2154 if (CPDF_FormField* pField =
2155 m_pInterForm->GetFieldInCalculationOrder(i)) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002156 int nType = pField->GetFieldType();
2157 if (nType == FIELDTYPE_COMBOBOX || nType == FIELDTYPE_TEXTFIELD) {
2158 CPDF_AAction aAction = pField->GetAdditionalAction();
Wei Li0fc6b252016-03-01 16:29:41 -08002159 if (aAction.GetDict() &&
2160 aAction.ActionExist(CPDF_AAction::Calculate)) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002161 CPDF_Action action = aAction.GetAction(CPDF_AAction::Calculate);
Wei Li0fc6b252016-03-01 16:29:41 -08002162 if (action.GetDict()) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002163 CFX_WideString csJS = action.GetJavaScript();
2164 if (!csJS.IsEmpty()) {
Tom Sepezba038bc2015-10-08 12:03:00 -07002165 IJS_Context* pContext = pRuntime->NewContext();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002166 CFX_WideString sOldValue = pField->GetValue();
2167 CFX_WideString sValue = sOldValue;
2168 FX_BOOL bRC = TRUE;
2169 pContext->OnField_Calculate(pFormField, pField, sValue, bRC);
Lei Zhanga6d9f0e2015-06-13 00:48:38 -07002170
Tom Sepez2f2ffec2015-07-23 14:42:09 -07002171 CFX_WideString sInfo;
Tom Sepez33420902015-10-13 15:00:10 -07002172 FX_BOOL bRet = pContext->RunScript(csJS, &sInfo);
Tom Sepez2f2ffec2015-07-23 14:42:09 -07002173 pRuntime->ReleaseContext(pContext);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07002174
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002175 if (bRet) {
2176 if (bRC) {
2177 if (sValue.Compare(sOldValue) != 0)
2178 pField->SetValue(sValue, TRUE);
2179 }
Tom Sepez2f2ffec2015-07-23 14:42:09 -07002180 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002181 }
Tom Sepez2f2ffec2015-07-23 14:42:09 -07002182 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002183 }
Tom Sepez2f2ffec2015-07-23 14:42:09 -07002184 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002185 }
Tom Sepez2f2ffec2015-07-23 14:42:09 -07002186 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002187 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07002188
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002189 m_bBusy = FALSE;
2190}
2191
2192CFX_WideString CPDFSDK_InterForm::OnFormat(CPDF_FormField* pFormField,
2193 FX_BOOL& bFormated) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002194 CFX_WideString sValue = pFormField->GetValue();
2195 CPDFDoc_Environment* pEnv = m_pDocument->GetEnv();
2196 ASSERT(pEnv);
2197 if (!pEnv->IsJSInitiated()) {
2198 bFormated = FALSE;
Tom Sepez2f2ffec2015-07-23 14:42:09 -07002199 return sValue;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002200 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07002201
Tom Sepezba038bc2015-10-08 12:03:00 -07002202 IJS_Runtime* pRuntime = m_pDocument->GetJsRuntime();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002203 pRuntime->SetReaderDocument(m_pDocument);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07002204
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002205 if (pFormField->GetFieldType() == FIELDTYPE_COMBOBOX) {
2206 if (pFormField->CountSelectedItems() > 0) {
2207 int index = pFormField->GetSelectedIndex(0);
2208 if (index >= 0)
2209 sValue = pFormField->GetOptionLabel(index);
Tom Sepez2f2ffec2015-07-23 14:42:09 -07002210 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002211 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07002212
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002213 bFormated = FALSE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07002214
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002215 CPDF_AAction aAction = pFormField->GetAdditionalAction();
Wei Li0fc6b252016-03-01 16:29:41 -08002216 if (aAction.GetDict() && aAction.ActionExist(CPDF_AAction::Format)) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002217 CPDF_Action action = aAction.GetAction(CPDF_AAction::Format);
Wei Li0fc6b252016-03-01 16:29:41 -08002218 if (action.GetDict()) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002219 CFX_WideString script = action.GetJavaScript();
2220 if (!script.IsEmpty()) {
2221 CFX_WideString Value = sValue;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07002222
Tom Sepezba038bc2015-10-08 12:03:00 -07002223 IJS_Context* pContext = pRuntime->NewContext();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002224 pContext->OnField_Format(pFormField, Value, TRUE);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07002225
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002226 CFX_WideString sInfo;
Tom Sepez33420902015-10-13 15:00:10 -07002227 FX_BOOL bRet = pContext->RunScript(script, &sInfo);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002228 pRuntime->ReleaseContext(pContext);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07002229
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002230 if (bRet) {
2231 sValue = Value;
2232 bFormated = TRUE;
Tom Sepez2f2ffec2015-07-23 14:42:09 -07002233 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002234 }
Tom Sepez2f2ffec2015-07-23 14:42:09 -07002235 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002236 }
2237
2238 return sValue;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07002239}
2240
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002241void CPDFSDK_InterForm::ResetFieldAppearance(CPDF_FormField* pFormField,
2242 const FX_WCHAR* sValue,
2243 FX_BOOL bValueChanged) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002244 for (int i = 0, sz = pFormField->CountControls(); i < sz; i++) {
2245 CPDF_FormControl* pFormCtrl = pFormField->GetControl(i);
Lei Zhang96660d62015-12-14 18:27:25 -08002246 ASSERT(pFormCtrl);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002247 if (CPDFSDK_Widget* pWidget = GetWidget(pFormCtrl))
2248 pWidget->ResetAppearance(sValue, bValueChanged);
2249 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07002250}
2251
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002252void CPDFSDK_InterForm::UpdateField(CPDF_FormField* pFormField) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002253 for (int i = 0, sz = pFormField->CountControls(); i < sz; i++) {
2254 CPDF_FormControl* pFormCtrl = pFormField->GetControl(i);
Lei Zhang96660d62015-12-14 18:27:25 -08002255 ASSERT(pFormCtrl);
Lei Zhanga6d9f0e2015-06-13 00:48:38 -07002256
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002257 if (CPDFSDK_Widget* pWidget = GetWidget(pFormCtrl)) {
2258 CPDFDoc_Environment* pEnv = m_pDocument->GetEnv();
2259 CFFL_IFormFiller* pIFormFiller = pEnv->GetIFormFiller();
Tom Sepez540c4362015-11-24 13:33:57 -08002260 UnderlyingPageType* pPage = pWidget->GetUnderlyingPage();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002261 CPDFSDK_PageView* pPageView = m_pDocument->GetPageView(pPage, FALSE);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002262 FX_RECT rcBBox = pIFormFiller->GetViewBBox(pPageView, pWidget);
Lei Zhanga6d9f0e2015-06-13 00:48:38 -07002263
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002264 pEnv->FFI_Invalidate(pPage, rcBBox.left, rcBBox.top, rcBBox.right,
2265 rcBBox.bottom);
Tom Sepez2f2ffec2015-07-23 14:42:09 -07002266 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002267 }
2268}
2269
Tom Sepezd6262c12016-02-03 14:47:06 -08002270FX_BOOL CPDFSDK_InterForm::OnKeyStrokeCommit(CPDF_FormField* pFormField,
2271 const CFX_WideString& csValue) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002272 CPDF_AAction aAction = pFormField->GetAdditionalAction();
Wei Li0fc6b252016-03-01 16:29:41 -08002273 if (!aAction.GetDict() || !aAction.ActionExist(CPDF_AAction::KeyStroke))
Tom Sepezd6262c12016-02-03 14:47:06 -08002274 return TRUE;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002275
Tom Sepezd6262c12016-02-03 14:47:06 -08002276 CPDF_Action action = aAction.GetAction(CPDF_AAction::KeyStroke);
Wei Li0fc6b252016-03-01 16:29:41 -08002277 if (!action.GetDict())
Tom Sepezd6262c12016-02-03 14:47:06 -08002278 return TRUE;
2279
2280 CPDFDoc_Environment* pEnv = m_pDocument->GetEnv();
2281 CPDFSDK_ActionHandler* pActionHandler = pEnv->GetActionHander();
2282 PDFSDK_FieldAction fa;
2283 fa.bModifier = pEnv->FFI_IsCTRLKeyDown(0);
2284 fa.bShift = pEnv->FFI_IsSHIFTKeyDown(0);
2285 fa.sValue = csValue;
2286 pActionHandler->DoAction_FieldJavaScript(action, CPDF_AAction::KeyStroke,
2287 m_pDocument, pFormField, fa);
2288 return fa.bRC;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002289}
2290
Tom Sepezd6262c12016-02-03 14:47:06 -08002291FX_BOOL CPDFSDK_InterForm::OnValidate(CPDF_FormField* pFormField,
2292 const CFX_WideString& csValue) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002293 CPDF_AAction aAction = pFormField->GetAdditionalAction();
Wei Li0fc6b252016-03-01 16:29:41 -08002294 if (!aAction.GetDict() || !aAction.ActionExist(CPDF_AAction::Validate))
Tom Sepezd6262c12016-02-03 14:47:06 -08002295 return TRUE;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002296
Tom Sepezd6262c12016-02-03 14:47:06 -08002297 CPDF_Action action = aAction.GetAction(CPDF_AAction::Validate);
Wei Li0fc6b252016-03-01 16:29:41 -08002298 if (!action.GetDict())
Tom Sepezd6262c12016-02-03 14:47:06 -08002299 return TRUE;
2300
2301 CPDFDoc_Environment* pEnv = m_pDocument->GetEnv();
2302 CPDFSDK_ActionHandler* pActionHandler = pEnv->GetActionHander();
2303 PDFSDK_FieldAction fa;
2304 fa.bModifier = pEnv->FFI_IsCTRLKeyDown(0);
2305 fa.bShift = pEnv->FFI_IsSHIFTKeyDown(0);
2306 fa.sValue = csValue;
2307 pActionHandler->DoAction_FieldJavaScript(action, CPDF_AAction::Validate,
2308 m_pDocument, pFormField, fa);
2309 return fa.bRC;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07002310}
2311
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002312FX_BOOL CPDFSDK_InterForm::DoAction_Hide(const CPDF_Action& action) {
Wei Li0fc6b252016-03-01 16:29:41 -08002313 ASSERT(action.GetDict());
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07002314
Wei Li0fc6b252016-03-01 16:29:41 -08002315 CPDF_ActionFields af(&action);
Lei Zhangd88a3642015-11-10 09:38:57 -08002316 std::vector<CPDF_Object*> fieldObjects = af.GetAllFields();
2317 std::vector<CPDF_FormField*> fields = GetFieldFromObjects(fieldObjects);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002318
2319 FX_BOOL bHide = action.GetHideStatus();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002320 FX_BOOL bChanged = FALSE;
2321
Lei Zhangd88a3642015-11-10 09:38:57 -08002322 for (CPDF_FormField* pField : fields) {
2323 for (int i = 0, sz = pField->CountControls(); i < sz; ++i) {
2324 CPDF_FormControl* pControl = pField->GetControl(i);
2325 ASSERT(pControl);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002326
2327 if (CPDFSDK_Widget* pWidget = GetWidget(pControl)) {
tsepezc3255f52016-03-25 14:52:27 -07002328 uint32_t nFlags = pWidget->GetFlags();
Lei Zhangd88a3642015-11-10 09:38:57 -08002329 nFlags &= ~ANNOTFLAG_INVISIBLE;
2330 nFlags &= ~ANNOTFLAG_NOVIEW;
2331 if (bHide)
2332 nFlags |= ANNOTFLAG_HIDDEN;
2333 else
2334 nFlags &= ~ANNOTFLAG_HIDDEN;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002335 pWidget->SetFlags(nFlags);
Lei Zhangd88a3642015-11-10 09:38:57 -08002336 pWidget->GetPageView()->UpdateView(pWidget);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002337 bChanged = TRUE;
2338 }
2339 }
2340 }
2341
2342 return bChanged;
2343}
2344
2345FX_BOOL CPDFSDK_InterForm::DoAction_SubmitForm(const CPDF_Action& action) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002346 CFX_WideString sDestination = action.GetFilePath();
2347 if (sDestination.IsEmpty())
2348 return FALSE;
2349
2350 CPDF_Dictionary* pActionDict = action.GetDict();
2351 if (pActionDict->KeyExist("Fields")) {
Wei Li0fc6b252016-03-01 16:29:41 -08002352 CPDF_ActionFields af(&action);
tsepezc3255f52016-03-25 14:52:27 -07002353 uint32_t dwFlags = action.GetFlags();
Lei Zhangd88a3642015-11-10 09:38:57 -08002354 std::vector<CPDF_Object*> fieldObjects = af.GetAllFields();
2355 std::vector<CPDF_FormField*> fields = GetFieldFromObjects(fieldObjects);
2356 if (!fields.empty()) {
2357 bool bIncludeOrExclude = !(dwFlags & 0x01);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002358 if (m_pInterForm->CheckRequiredFields(&fields, bIncludeOrExclude))
Tom Sepez2f2ffec2015-07-23 14:42:09 -07002359 return FALSE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07002360
Wei Li97da9762016-03-11 17:00:48 -08002361 return SubmitFields(sDestination, fields, bIncludeOrExclude, false);
Tom Sepez2f2ffec2015-07-23 14:42:09 -07002362 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002363 }
Lei Zhangd88a3642015-11-10 09:38:57 -08002364 if (m_pInterForm->CheckRequiredFields(nullptr, true))
Tom Sepez2f2ffec2015-07-23 14:42:09 -07002365 return FALSE;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002366
2367 return SubmitForm(sDestination, FALSE);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07002368}
2369
Lei Zhangd88a3642015-11-10 09:38:57 -08002370FX_BOOL CPDFSDK_InterForm::SubmitFields(
2371 const CFX_WideString& csDestination,
2372 const std::vector<CPDF_FormField*>& fields,
Wei Li97da9762016-03-11 17:00:48 -08002373 bool bIncludeOrExclude,
2374 bool bUrlEncoded) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002375 CPDFDoc_Environment* pEnv = m_pDocument->GetEnv();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002376
2377 CFX_ByteTextBuf textBuf;
2378 ExportFieldsToFDFTextBuf(fields, bIncludeOrExclude, textBuf);
2379
2380 uint8_t* pBuffer = textBuf.GetBuffer();
2381 FX_STRSIZE nBufSize = textBuf.GetLength();
2382
Lei Zhangd88a3642015-11-10 09:38:57 -08002383 if (bUrlEncoded && !FDFToURLEncodedData(pBuffer, nBufSize))
2384 return FALSE;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002385
2386 pEnv->JS_docSubmitForm(pBuffer, nBufSize, csDestination.c_str());
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002387 return TRUE;
2388}
2389
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002390FX_BOOL CPDFSDK_InterForm::FDFToURLEncodedData(CFX_WideString csFDFFile,
2391 CFX_WideString csTxtFile) {
2392 return TRUE;
2393}
2394
2395FX_BOOL CPDFSDK_InterForm::FDFToURLEncodedData(uint8_t*& pBuf,
2396 FX_STRSIZE& nBufSize) {
2397 CFDF_Document* pFDF = CFDF_Document::ParseMemory(pBuf, nBufSize);
2398 if (pFDF) {
Wei Li9b761132016-01-29 15:44:20 -08002399 CPDF_Dictionary* pMainDict = pFDF->GetRoot()->GetDictBy("FDF");
Lei Zhang997de612015-11-04 18:17:53 -08002400 if (!pMainDict)
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002401 return FALSE;
2402
2403 // Get fields
Wei Li9b761132016-01-29 15:44:20 -08002404 CPDF_Array* pFields = pMainDict->GetArrayBy("Fields");
Lei Zhang997de612015-11-04 18:17:53 -08002405 if (!pFields)
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002406 return FALSE;
2407
2408 CFX_ByteTextBuf fdfEncodedData;
tsepezc3255f52016-03-25 14:52:27 -07002409 for (uint32_t i = 0; i < pFields->GetCount(); i++) {
Wei Li9b761132016-01-29 15:44:20 -08002410 CPDF_Dictionary* pField = pFields->GetDictAt(i);
Lei Zhang997de612015-11-04 18:17:53 -08002411 if (!pField)
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002412 continue;
2413 CFX_WideString name;
Wei Li9b761132016-01-29 15:44:20 -08002414 name = pField->GetUnicodeTextBy("T");
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002415 CFX_ByteString name_b = CFX_ByteString::FromUnicode(name);
Wei Li9b761132016-01-29 15:44:20 -08002416 CFX_ByteString csBValue = pField->GetStringBy("V");
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002417 CFX_WideString csWValue = PDF_DecodeText(csBValue);
2418 CFX_ByteString csValue_b = CFX_ByteString::FromUnicode(csWValue);
2419
Tom Sepez052a8d92016-02-19 14:41:46 -08002420 fdfEncodedData << name_b.GetBuffer(name_b.GetLength());
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002421 name_b.ReleaseBuffer();
Tom Sepez052a8d92016-02-19 14:41:46 -08002422 fdfEncodedData << "=";
2423 fdfEncodedData << csValue_b.GetBuffer(csValue_b.GetLength());
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002424 csValue_b.ReleaseBuffer();
2425 if (i != pFields->GetCount() - 1)
Tom Sepez052a8d92016-02-19 14:41:46 -08002426 fdfEncodedData << "&";
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002427 }
2428
2429 nBufSize = fdfEncodedData.GetLength();
2430 pBuf = FX_Alloc(uint8_t, nBufSize);
2431 FXSYS_memcpy(pBuf, fdfEncodedData.GetBuffer(), nBufSize);
2432 }
2433 return TRUE;
2434}
2435
Lei Zhangd88a3642015-11-10 09:38:57 -08002436FX_BOOL CPDFSDK_InterForm::ExportFieldsToFDFTextBuf(
2437 const std::vector<CPDF_FormField*>& fields,
Wei Li97da9762016-03-11 17:00:48 -08002438 bool bIncludeOrExclude,
Lei Zhangd88a3642015-11-10 09:38:57 -08002439 CFX_ByteTextBuf& textBuf) {
Lei Zhangaa8bf7e2015-12-24 19:13:32 -08002440 std::unique_ptr<CFDF_Document> pFDF(m_pInterForm->ExportToFDF(
tsepez4c3debb2016-04-08 12:20:38 -07002441 m_pDocument->GetPath().AsStringC(), fields, bIncludeOrExclude));
Lei Zhangd88a3642015-11-10 09:38:57 -08002442 return pFDF ? pFDF->WriteBuf(textBuf) : FALSE;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002443}
2444
Tom Sepez51da0932015-11-25 16:05:49 -08002445#ifdef PDF_ENABLE_XFA
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002446void CPDFSDK_InterForm::SynchronizeField(CPDF_FormField* pFormField,
2447 FX_BOOL bSynchronizeElse) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002448 for (int i = 0, sz = pFormField->CountControls(); i < sz; i++) {
2449 CPDF_FormControl* pFormCtrl = pFormField->GetControl(i);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002450 if (CPDFSDK_Widget* pWidget = GetWidget(pFormCtrl)) {
2451 pWidget->Synchronize(bSynchronizeElse);
Tom Sepez2f2ffec2015-07-23 14:42:09 -07002452 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002453 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07002454}
Tom Sepez40e9ff32015-11-30 12:39:54 -08002455#endif // PDF_ENABLE_XFA
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07002456
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002457CFX_WideString CPDFSDK_InterForm::GetTemporaryFileName(
2458 const CFX_WideString& sFileExt) {
2459 CFX_WideString sFileName;
2460 return L"";
2461}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07002462
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002463FX_BOOL CPDFSDK_InterForm::SubmitForm(const CFX_WideString& sDestination,
2464 FX_BOOL bUrlEncoded) {
2465 if (sDestination.IsEmpty())
2466 return FALSE;
2467
Lei Zhang96660d62015-12-14 18:27:25 -08002468 if (!m_pDocument || !m_pInterForm)
2469 return FALSE;
2470
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002471 CPDFDoc_Environment* pEnv = m_pDocument->GetEnv();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002472 CFX_WideString wsPDFFilePath = m_pDocument->GetPath();
tsepez4c3debb2016-04-08 12:20:38 -07002473 CFDF_Document* pFDFDoc = m_pInterForm->ExportToFDF(wsPDFFilePath.AsStringC());
Lei Zhang997de612015-11-04 18:17:53 -08002474 if (!pFDFDoc)
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002475 return FALSE;
2476
2477 CFX_ByteTextBuf FdfBuffer;
2478 FX_BOOL bRet = pFDFDoc->WriteBuf(FdfBuffer);
2479 delete pFDFDoc;
2480 if (!bRet)
2481 return FALSE;
2482
2483 uint8_t* pBuffer = FdfBuffer.GetBuffer();
2484 FX_STRSIZE nBufSize = FdfBuffer.GetLength();
2485
2486 if (bUrlEncoded) {
2487 if (!FDFToURLEncodedData(pBuffer, nBufSize))
2488 return FALSE;
2489 }
2490
2491 pEnv->JS_docSubmitForm(pBuffer, nBufSize, sDestination.c_str());
2492
Lei Zhangda180e92015-08-14 22:22:13 -07002493 if (bUrlEncoded) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002494 FX_Free(pBuffer);
2495 pBuffer = NULL;
2496 }
2497
2498 return TRUE;
2499}
2500
2501FX_BOOL CPDFSDK_InterForm::ExportFormToFDFTextBuf(CFX_ByteTextBuf& textBuf) {
tsepezfc58ad12016-04-05 12:22:15 -07002502 CFDF_Document* pFDF =
tsepez4c3debb2016-04-08 12:20:38 -07002503 m_pInterForm->ExportToFDF(m_pDocument->GetPath().AsStringC());
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002504 if (!pFDF)
2505 return FALSE;
2506
2507 FX_BOOL bRet = pFDF->WriteBuf(textBuf);
2508 delete pFDF;
2509
2510 return bRet;
2511}
2512
2513FX_BOOL CPDFSDK_InterForm::DoAction_ResetForm(const CPDF_Action& action) {
Wei Li0fc6b252016-03-01 16:29:41 -08002514 ASSERT(action.GetDict());
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002515
2516 CPDF_Dictionary* pActionDict = action.GetDict();
Lei Zhangd88a3642015-11-10 09:38:57 -08002517 if (!pActionDict->KeyExist("Fields"))
2518 return m_pInterForm->ResetForm(true);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002519
Wei Li0fc6b252016-03-01 16:29:41 -08002520 CPDF_ActionFields af(&action);
tsepezc3255f52016-03-25 14:52:27 -07002521 uint32_t dwFlags = action.GetFlags();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002522
Lei Zhangd88a3642015-11-10 09:38:57 -08002523 std::vector<CPDF_Object*> fieldObjects = af.GetAllFields();
2524 std::vector<CPDF_FormField*> fields = GetFieldFromObjects(fieldObjects);
2525 return m_pInterForm->ResetForm(fields, !(dwFlags & 0x01), true);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002526}
2527
2528FX_BOOL CPDFSDK_InterForm::DoAction_ImportData(const CPDF_Action& action) {
2529 return FALSE;
2530}
2531
Lei Zhangd88a3642015-11-10 09:38:57 -08002532std::vector<CPDF_FormField*> CPDFSDK_InterForm::GetFieldFromObjects(
2533 const std::vector<CPDF_Object*>& objects) const {
2534 std::vector<CPDF_FormField*> fields;
2535 for (CPDF_Object* pObject : objects) {
2536 if (pObject && pObject->IsString()) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002537 CFX_WideString csName = pObject->GetUnicodeText();
2538 CPDF_FormField* pField = m_pInterForm->GetField(0, csName);
Dan Sinclaird43ebdd2015-10-27 15:37:54 -04002539 if (pField)
Lei Zhangd88a3642015-11-10 09:38:57 -08002540 fields.push_back(pField);
Tom Sepez2f2ffec2015-07-23 14:42:09 -07002541 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002542 }
Lei Zhangd88a3642015-11-10 09:38:57 -08002543 return fields;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07002544}
2545
Tom Sepezd6262c12016-02-03 14:47:06 -08002546int CPDFSDK_InterForm::BeforeValueChange(CPDF_FormField* pField,
2547 const CFX_WideString& csValue) {
2548 int nType = pField->GetFieldType();
2549 if (nType != FIELDTYPE_COMBOBOX && nType != FIELDTYPE_TEXTFIELD)
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002550 return 0;
2551
Tom Sepezd6262c12016-02-03 14:47:06 -08002552 if (!OnKeyStrokeCommit(pField, csValue))
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002553 return -1;
2554
Tom Sepezd6262c12016-02-03 14:47:06 -08002555 if (!OnValidate(pField, csValue))
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002556 return -1;
2557
2558 return 1;
2559}
2560
Tom Sepezd6262c12016-02-03 14:47:06 -08002561void CPDFSDK_InterForm::AfterValueChange(CPDF_FormField* pField) {
2562#ifdef PDF_ENABLE_XFA
2563 SynchronizeField(pField, FALSE);
2564#endif // PDF_ENABLE_XFA
2565 int nType = pField->GetFieldType();
2566 if (nType == FIELDTYPE_COMBOBOX || nType == FIELDTYPE_TEXTFIELD) {
2567 OnCalculate(pField);
2568 FX_BOOL bFormated = FALSE;
2569 CFX_WideString sValue = OnFormat(pField, bFormated);
2570 ResetFieldAppearance(pField, bFormated ? sValue.c_str() : nullptr, TRUE);
2571 UpdateField(pField);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002572 }
Tom Sepezd6262c12016-02-03 14:47:06 -08002573}
2574
2575int CPDFSDK_InterForm::BeforeSelectionChange(CPDF_FormField* pField,
2576 const CFX_WideString& csValue) {
2577 if (pField->GetFieldType() != FIELDTYPE_LISTBOX)
2578 return 0;
2579
2580 if (!OnKeyStrokeCommit(pField, csValue))
2581 return -1;
2582
2583 if (!OnValidate(pField, csValue))
2584 return -1;
2585
2586 return 1;
2587}
2588
2589void CPDFSDK_InterForm::AfterSelectionChange(CPDF_FormField* pField) {
2590 if (pField->GetFieldType() == FIELDTYPE_LISTBOX) {
2591 OnCalculate(pField);
2592 ResetFieldAppearance(pField, NULL, TRUE);
2593 UpdateField(pField);
2594 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002595}
2596
Tom Sepezed5d7aa2016-02-02 16:02:03 -08002597void CPDFSDK_InterForm::AfterCheckedStatusChange(CPDF_FormField* pField) {
2598 int nType = pField->GetFieldType();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002599 if (nType == FIELDTYPE_CHECKBOX || nType == FIELDTYPE_RADIOBUTTON) {
Tom Sepezed5d7aa2016-02-02 16:02:03 -08002600 OnCalculate(pField);
2601 UpdateField(pField);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002602 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002603}
2604
Tom Sepezd6262c12016-02-03 14:47:06 -08002605int CPDFSDK_InterForm::BeforeFormReset(CPDF_InterForm* pForm) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002606 return 0;
2607}
2608
Tom Sepezd6262c12016-02-03 14:47:06 -08002609void CPDFSDK_InterForm::AfterFormReset(CPDF_InterForm* pForm) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002610 OnCalculate(nullptr);
Tom Sepezd6262c12016-02-03 14:47:06 -08002611}
2612
2613int CPDFSDK_InterForm::BeforeFormImportData(CPDF_InterForm* pForm) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002614 return 0;
2615}
2616
Tom Sepezd6262c12016-02-03 14:47:06 -08002617void CPDFSDK_InterForm::AfterFormImportData(CPDF_InterForm* pForm) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002618 OnCalculate(nullptr);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002619}
2620
2621FX_BOOL CPDFSDK_InterForm::IsNeedHighLight(int nFieldType) {
Tom Sepezae7a9172015-11-23 09:22:46 -08002622 if (nFieldType < 1 || nFieldType > kNumFieldTypes)
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002623 return FALSE;
2624 return m_bNeedHightlight[nFieldType - 1];
2625}
2626
2627void CPDFSDK_InterForm::RemoveAllHighLight() {
Tom Sepezae7a9172015-11-23 09:22:46 -08002628 for (int i = 0; i < kNumFieldTypes; ++i)
2629 m_bNeedHightlight[i] = FALSE;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002630}
Tom Sepezae7a9172015-11-23 09:22:46 -08002631
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002632void CPDFSDK_InterForm::SetHighlightColor(FX_COLORREF clr, int nFieldType) {
Tom Sepezae7a9172015-11-23 09:22:46 -08002633 if (nFieldType < 0 || nFieldType > kNumFieldTypes)
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002634 return;
2635 switch (nFieldType) {
2636 case 0: {
Tom Sepezae7a9172015-11-23 09:22:46 -08002637 for (int i = 0; i < kNumFieldTypes; ++i) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002638 m_aHighlightColor[i] = clr;
2639 m_bNeedHightlight[i] = TRUE;
2640 }
2641 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -07002642 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002643 default: {
2644 m_aHighlightColor[nFieldType - 1] = clr;
2645 m_bNeedHightlight[nFieldType - 1] = TRUE;
2646 break;
2647 }
2648 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07002649}
2650
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002651FX_COLORREF CPDFSDK_InterForm::GetHighlightColor(int nFieldType) {
Tom Sepezae7a9172015-11-23 09:22:46 -08002652 if (nFieldType < 0 || nFieldType > kNumFieldTypes)
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002653 return FXSYS_RGB(255, 255, 255);
2654 if (nFieldType == 0)
2655 return m_aHighlightColor[0];
2656 return m_aHighlightColor[nFieldType - 1];
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07002657}
2658
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002659CBA_AnnotIterator::CBA_AnnotIterator(CPDFSDK_PageView* pPageView,
2660 const CFX_ByteString& sType,
2661 const CFX_ByteString& sSubType)
Tom Sepezb9cc7a02016-02-01 13:42:30 -08002662 : m_eTabOrder(STRUCTURE),
2663 m_pPageView(pPageView),
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002664 m_sType(sType),
Tom Sepezb9cc7a02016-02-01 13:42:30 -08002665 m_sSubType(sSubType) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002666 CPDF_Page* pPDFPage = m_pPageView->GetPDFPage();
Wei Li9b761132016-01-29 15:44:20 -08002667 CFX_ByteString sTabs = pPDFPage->m_pFormDict->GetStringBy("Tabs");
Tom Sepezb9cc7a02016-02-01 13:42:30 -08002668 if (sTabs == "R")
2669 m_eTabOrder = ROW;
2670 else if (sTabs == "C")
2671 m_eTabOrder = COLUMN;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07002672
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002673 GenerateResults();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07002674}
2675
Dan Sinclairf766ad22016-03-14 13:51:24 -04002676CBA_AnnotIterator::~CBA_AnnotIterator() {}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07002677
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002678CPDFSDK_Annot* CBA_AnnotIterator::GetFirstAnnot() {
Tom Sepezb9cc7a02016-02-01 13:42:30 -08002679 return m_Annots.empty() ? nullptr : m_Annots.front();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07002680}
2681
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002682CPDFSDK_Annot* CBA_AnnotIterator::GetLastAnnot() {
Tom Sepezb9cc7a02016-02-01 13:42:30 -08002683 return m_Annots.empty() ? nullptr : m_Annots.back();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07002684}
2685
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002686CPDFSDK_Annot* CBA_AnnotIterator::GetNextAnnot(CPDFSDK_Annot* pAnnot) {
Tom Sepezb9cc7a02016-02-01 13:42:30 -08002687 auto iter = std::find(m_Annots.begin(), m_Annots.end(), pAnnot);
2688 if (iter == m_Annots.end())
2689 return nullptr;
2690 ++iter;
2691 if (iter == m_Annots.end())
2692 iter = m_Annots.begin();
2693 return *iter;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07002694}
2695
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002696CPDFSDK_Annot* CBA_AnnotIterator::GetPrevAnnot(CPDFSDK_Annot* pAnnot) {
Tom Sepezb9cc7a02016-02-01 13:42:30 -08002697 auto iter = std::find(m_Annots.begin(), m_Annots.end(), pAnnot);
2698 if (iter == m_Annots.end())
2699 return nullptr;
2700 if (iter == m_Annots.begin())
2701 iter = m_Annots.end();
2702 return *(--iter);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07002703}
2704
Tom Sepezb9cc7a02016-02-01 13:42:30 -08002705// static
2706bool CBA_AnnotIterator::CompareByLeftAscending(const CPDFSDK_Annot* p1,
2707 const CPDFSDK_Annot* p2) {
2708 return GetAnnotRect(p1).left < GetAnnotRect(p2).left;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07002709}
2710
Tom Sepezb9cc7a02016-02-01 13:42:30 -08002711// static
2712bool CBA_AnnotIterator::CompareByTopDescending(const CPDFSDK_Annot* p1,
2713 const CPDFSDK_Annot* p2) {
2714 return GetAnnotRect(p1).top > GetAnnotRect(p2).top;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07002715}
2716
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002717void CBA_AnnotIterator::GenerateResults() {
Tom Sepezb9cc7a02016-02-01 13:42:30 -08002718 switch (m_eTabOrder) {
2719 case STRUCTURE: {
Lei Zhangbf60b292015-10-26 12:14:35 -07002720 for (size_t i = 0; i < m_pPageView->CountAnnots(); ++i) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002721 CPDFSDK_Annot* pAnnot = m_pPageView->GetAnnot(i);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002722 if (pAnnot->GetType() == m_sType && pAnnot->GetSubType() == m_sSubType)
Tom Sepezb9cc7a02016-02-01 13:42:30 -08002723 m_Annots.push_back(pAnnot);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002724 }
Tom Sepezb9cc7a02016-02-01 13:42:30 -08002725 } break;
2726 case ROW: {
2727 std::vector<CPDFSDK_Annot*> sa;
Lei Zhang50218532015-10-30 14:03:43 -07002728 for (size_t i = 0; i < m_pPageView->CountAnnots(); ++i) {
2729 CPDFSDK_Annot* pAnnot = m_pPageView->GetAnnot(i);
2730 if (pAnnot->GetType() == m_sType && pAnnot->GetSubType() == m_sSubType)
Tom Sepezb9cc7a02016-02-01 13:42:30 -08002731 sa.push_back(pAnnot);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002732 }
2733
Tom Sepezb9cc7a02016-02-01 13:42:30 -08002734 std::sort(sa.begin(), sa.end(), CompareByLeftAscending);
2735 while (!sa.empty()) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002736 int nLeftTopIndex = -1;
Lei Zhang50218532015-10-30 14:03:43 -07002737 FX_FLOAT fTop = 0.0f;
Tom Sepezb9cc7a02016-02-01 13:42:30 -08002738 for (int i = sa.size() - 1; i >= 0; i--) {
Tom Sepez281a9ea2016-02-26 14:24:28 -08002739 CFX_FloatRect rcAnnot = GetAnnotRect(sa[i]);
Lei Zhang50218532015-10-30 14:03:43 -07002740 if (rcAnnot.top > fTop) {
2741 nLeftTopIndex = i;
2742 fTop = rcAnnot.top;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002743 }
Tom Sepez2f2ffec2015-07-23 14:42:09 -07002744 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002745 if (nLeftTopIndex >= 0) {
Tom Sepezb9cc7a02016-02-01 13:42:30 -08002746 CPDFSDK_Annot* pLeftTopAnnot = sa[nLeftTopIndex];
Tom Sepez281a9ea2016-02-26 14:24:28 -08002747 CFX_FloatRect rcLeftTop = GetAnnotRect(pLeftTopAnnot);
Tom Sepezb9cc7a02016-02-01 13:42:30 -08002748 m_Annots.push_back(pLeftTopAnnot);
2749 sa.erase(sa.begin() + nLeftTopIndex);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002750
Tom Sepezb9cc7a02016-02-01 13:42:30 -08002751 std::vector<int> aSelect;
Wei Li89409932016-03-28 10:33:33 -07002752 for (size_t i = 0; i < sa.size(); ++i) {
Tom Sepez281a9ea2016-02-26 14:24:28 -08002753 CFX_FloatRect rcAnnot = GetAnnotRect(sa[i]);
Lei Zhang50218532015-10-30 14:03:43 -07002754 FX_FLOAT fCenterY = (rcAnnot.top + rcAnnot.bottom) / 2.0f;
2755 if (fCenterY > rcLeftTop.bottom && fCenterY < rcLeftTop.top)
Tom Sepezb9cc7a02016-02-01 13:42:30 -08002756 aSelect.push_back(i);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002757 }
Wei Li89409932016-03-28 10:33:33 -07002758 for (size_t i = 0; i < aSelect.size(); ++i)
Tom Sepezb9cc7a02016-02-01 13:42:30 -08002759 m_Annots.push_back(sa[aSelect[i]]);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002760
Tom Sepezb9cc7a02016-02-01 13:42:30 -08002761 for (int i = aSelect.size() - 1; i >= 0; --i)
2762 sa.erase(sa.begin() + aSelect[i]);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002763 }
2764 }
Tom Sepezb9cc7a02016-02-01 13:42:30 -08002765 } break;
2766 case COLUMN: {
2767 std::vector<CPDFSDK_Annot*> sa;
Lei Zhang50218532015-10-30 14:03:43 -07002768 for (size_t i = 0; i < m_pPageView->CountAnnots(); ++i) {
2769 CPDFSDK_Annot* pAnnot = m_pPageView->GetAnnot(i);
2770 if (pAnnot->GetType() == m_sType && pAnnot->GetSubType() == m_sSubType)
Tom Sepezb9cc7a02016-02-01 13:42:30 -08002771 sa.push_back(pAnnot);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002772 }
2773
Tom Sepezb9cc7a02016-02-01 13:42:30 -08002774 std::sort(sa.begin(), sa.end(), CompareByTopDescending);
2775 while (!sa.empty()) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002776 int nLeftTopIndex = -1;
Lei Zhang50218532015-10-30 14:03:43 -07002777 FX_FLOAT fLeft = -1.0f;
Tom Sepezb9cc7a02016-02-01 13:42:30 -08002778 for (int i = sa.size() - 1; i >= 0; --i) {
Tom Sepez281a9ea2016-02-26 14:24:28 -08002779 CFX_FloatRect rcAnnot = GetAnnotRect(sa[i]);
Lei Zhang50218532015-10-30 14:03:43 -07002780 if (fLeft < 0) {
2781 nLeftTopIndex = 0;
2782 fLeft = rcAnnot.left;
2783 } else if (rcAnnot.left < fLeft) {
2784 nLeftTopIndex = i;
2785 fLeft = rcAnnot.left;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002786 }
Tom Sepez2f2ffec2015-07-23 14:42:09 -07002787 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002788
2789 if (nLeftTopIndex >= 0) {
Tom Sepezb9cc7a02016-02-01 13:42:30 -08002790 CPDFSDK_Annot* pLeftTopAnnot = sa[nLeftTopIndex];
Tom Sepez281a9ea2016-02-26 14:24:28 -08002791 CFX_FloatRect rcLeftTop = GetAnnotRect(pLeftTopAnnot);
Tom Sepezb9cc7a02016-02-01 13:42:30 -08002792 m_Annots.push_back(pLeftTopAnnot);
2793 sa.erase(sa.begin() + nLeftTopIndex);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002794
Tom Sepezb9cc7a02016-02-01 13:42:30 -08002795 std::vector<int> aSelect;
Wei Li89409932016-03-28 10:33:33 -07002796 for (size_t i = 0; i < sa.size(); ++i) {
Tom Sepez281a9ea2016-02-26 14:24:28 -08002797 CFX_FloatRect rcAnnot = GetAnnotRect(sa[i]);
Lei Zhang50218532015-10-30 14:03:43 -07002798 FX_FLOAT fCenterX = (rcAnnot.left + rcAnnot.right) / 2.0f;
2799 if (fCenterX > rcLeftTop.left && fCenterX < rcLeftTop.right)
Tom Sepezb9cc7a02016-02-01 13:42:30 -08002800 aSelect.push_back(i);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002801 }
Wei Li89409932016-03-28 10:33:33 -07002802 for (size_t i = 0; i < aSelect.size(); ++i)
Tom Sepezb9cc7a02016-02-01 13:42:30 -08002803 m_Annots.push_back(sa[aSelect[i]]);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002804
Tom Sepezb9cc7a02016-02-01 13:42:30 -08002805 for (int i = aSelect.size() - 1; i >= 0; --i)
2806 sa.erase(sa.begin() + aSelect[i]);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002807 }
2808 }
Lei Zhang50218532015-10-30 14:03:43 -07002809 break;
2810 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002811 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07002812}
2813
Tom Sepez281a9ea2016-02-26 14:24:28 -08002814CFX_FloatRect CBA_AnnotIterator::GetAnnotRect(const CPDFSDK_Annot* pAnnot) {
2815 CFX_FloatRect rcAnnot;
Lei Zhang50218532015-10-30 14:03:43 -07002816 pAnnot->GetPDFAnnot()->GetRect(rcAnnot);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002817 return rcAnnot;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07002818}