blob: 38dd1f2d9f34f050d81e28bd1751f2b55ea268a4 [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>
Lei Zhangaa8bf7e2015-12-24 19:13:32 -080010#include <memory>
Dan Sinclair3ebd1212016-03-09 09:59:23 -050011#include <vector>
Lei Zhangaa8bf7e2015-12-24 19:13:32 -080012
Dan Sinclair455a4192016-03-16 09:48:56 -040013#include "core/fpdfapi/fpdf_page/include/cpdf_page.h"
Dan Sinclairaa403d32016-03-15 14:57:22 -040014#include "core/fpdfapi/fpdf_parser/include/cfdf_document.h"
15#include "core/fpdfapi/fpdf_parser/include/cpdf_array.h"
16#include "core/fpdfapi/fpdf_parser/include/cpdf_document.h"
Lei Zhangbde53d22015-11-12 22:21:30 -080017#include "fpdfsdk/include/formfiller/FFL_FormFiller.h"
18#include "fpdfsdk/include/fsdk_actionhandler.h"
19#include "fpdfsdk/include/fsdk_baseannot.h"
Lei Zhangbde53d22015-11-12 22:21:30 -080020#include "fpdfsdk/include/fsdk_define.h"
21#include "fpdfsdk/include/fsdk_mgr.h"
22#include "fpdfsdk/include/javascript/IJavaScript.h"
Lei Zhangc2fb35f2016-01-05 16:46:58 -080023#include "fpdfsdk/include/pdfwindow/PWL_Utils.h"
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070024
Tom Sepez40e9ff32015-11-30 12:39:54 -080025#ifdef PDF_ENABLE_XFA
Lei Zhang875b9c92016-01-08 13:51:10 -080026#include "fpdfsdk/include/fpdfxfa/fpdfxfa_doc.h"
27#include "fpdfsdk/include/fpdfxfa/fpdfxfa_util.h"
Tom Sepez40e9ff32015-11-30 12:39:54 -080028#endif // PDF_ENABLE_XFA
29
Nico Weber9d8ec5a2015-08-04 13:00:21 -070030#define IsFloatZero(f) ((f) < 0.01 && (f) > -0.01)
31#define IsFloatBigger(fa, fb) ((fa) > (fb) && !IsFloatZero((fa) - (fb)))
32#define IsFloatSmaller(fa, fb) ((fa) < (fb) && !IsFloatZero((fa) - (fb)))
33#define IsFloatEqual(fa, fb) IsFloatZero((fa) - (fb))
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070034
Nico Weber9d8ec5a2015-08-04 13:00:21 -070035CPDFSDK_Widget::CPDFSDK_Widget(CPDF_Annot* pAnnot,
36 CPDFSDK_PageView* pPageView,
37 CPDFSDK_InterForm* pInterForm)
38 : CPDFSDK_BAAnnot(pAnnot, pPageView),
39 m_pInterForm(pInterForm),
40 m_nAppAge(0),
Tom Sepez40e9ff32015-11-30 12:39:54 -080041 m_nValueAge(0)
42#ifdef PDF_ENABLE_XFA
43 ,
Nico Weber9d8ec5a2015-08-04 13:00:21 -070044 m_hMixXFAWidget(NULL),
Tom Sepez40e9ff32015-11-30 12:39:54 -080045 m_pWidgetHandler(NULL)
46#endif // PDF_ENABLE_XFA
47{
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070048}
49
Nico Weber9d8ec5a2015-08-04 13:00:21 -070050CPDFSDK_Widget::~CPDFSDK_Widget() {}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070051
Tom Sepez51da0932015-11-25 16:05:49 -080052#ifdef PDF_ENABLE_XFA
Tom Sepezbf59a072015-10-21 14:07:23 -070053IXFA_Widget* CPDFSDK_Widget::GetMixXFAWidget() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070054 CPDFSDK_Document* pSDKDoc = m_pPageView->GetSDKDocument();
Tom Sepez50d12ad2015-11-24 09:50:51 -080055 CPDFXFA_Document* pDoc = pSDKDoc->GetXFADocument();
Nico Weber9d8ec5a2015-08-04 13:00:21 -070056 if (pDoc->GetDocType() == DOCTYPE_STATIC_XFA) {
57 if (!m_hMixXFAWidget) {
58 if (IXFA_DocView* pDocView = pDoc->GetXFADocView()) {
59 CFX_WideString sName;
Lei Zhang99766722016-02-23 11:21:48 -080060 if (GetFieldType() == FIELDTYPE_RADIOBUTTON) {
61 sName = GetAnnotName();
Nico Weber9d8ec5a2015-08-04 13:00:21 -070062 if (sName.IsEmpty())
63 sName = GetName();
Dan Sinclair738b08c2016-03-01 14:45:20 -050064 } else {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070065 sName = GetName();
Dan Sinclair738b08c2016-03-01 14:45:20 -050066 }
Bo Xufdc00a72014-10-28 23:03:33 -070067
Nico Weber9d8ec5a2015-08-04 13:00:21 -070068 if (!sName.IsEmpty())
69 m_hMixXFAWidget = pDocView->GetWidgetByName(sName);
70 }
Tom Sepez2f2ffec2015-07-23 14:42:09 -070071 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -070072 return m_hMixXFAWidget;
73 }
Lei Zhanga6d9f0e2015-06-13 00:48:38 -070074
Nico Weber9d8ec5a2015-08-04 13:00:21 -070075 return NULL;
76}
77
78IXFA_Widget* CPDFSDK_Widget::GetGroupMixXFAWidget() {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070079 CPDFSDK_Document* pSDKDoc = m_pPageView->GetSDKDocument();
Tom Sepez50d12ad2015-11-24 09:50:51 -080080 CPDFXFA_Document* pDoc = pSDKDoc->GetXFADocument();
Nico Weber9d8ec5a2015-08-04 13:00:21 -070081 if (pDoc->GetDocType() == DOCTYPE_STATIC_XFA) {
82 if (IXFA_DocView* pDocView = pDoc->GetXFADocView()) {
83 CFX_WideString sName = GetName();
Nico Weber9d8ec5a2015-08-04 13:00:21 -070084 if (!sName.IsEmpty())
85 return pDocView->GetWidgetByName(sName);
86 }
87 }
88
Tom Sepez50d12ad2015-11-24 09:50:51 -080089 return nullptr;
Nico Weber9d8ec5a2015-08-04 13:00:21 -070090}
91
Tom Sepezbf59a072015-10-21 14:07:23 -070092IXFA_WidgetHandler* CPDFSDK_Widget::GetXFAWidgetHandler() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070093 CPDFSDK_Document* pSDKDoc = m_pPageView->GetSDKDocument();
Tom Sepez50d12ad2015-11-24 09:50:51 -080094 CPDFXFA_Document* pDoc = pSDKDoc->GetXFADocument();
Nico Weber9d8ec5a2015-08-04 13:00:21 -070095 if (pDoc->GetDocType() == DOCTYPE_STATIC_XFA) {
96 if (!m_pWidgetHandler) {
97 if (IXFA_DocView* pDocView = pDoc->GetXFADocView()) {
98 m_pWidgetHandler = pDocView->GetWidgetHandler();
99 }
100 }
101 return m_pWidgetHandler;
102 }
103
104 return NULL;
105}
106
107static XFA_EVENTTYPE GetXFAEventType(PDFSDK_XFAAActionType eXFAAAT) {
108 XFA_EVENTTYPE eEventType = XFA_EVENT_Unknown;
109
110 switch (eXFAAAT) {
111 case PDFSDK_XFA_Click:
112 eEventType = XFA_EVENT_Click;
113 break;
114 case PDFSDK_XFA_Full:
115 eEventType = XFA_EVENT_Full;
116 break;
117 case PDFSDK_XFA_PreOpen:
118 eEventType = XFA_EVENT_PreOpen;
119 break;
120 case PDFSDK_XFA_PostOpen:
121 eEventType = XFA_EVENT_PostOpen;
122 break;
123 }
124
125 return eEventType;
126}
127
128static XFA_EVENTTYPE GetXFAEventType(CPDF_AAction::AActionType eAAT,
129 FX_BOOL bWillCommit) {
130 XFA_EVENTTYPE eEventType = XFA_EVENT_Unknown;
131
132 switch (eAAT) {
133 case CPDF_AAction::CursorEnter:
134 eEventType = XFA_EVENT_MouseEnter;
135 break;
136 case CPDF_AAction::CursorExit:
137 eEventType = XFA_EVENT_MouseExit;
138 break;
139 case CPDF_AAction::ButtonDown:
140 eEventType = XFA_EVENT_MouseDown;
141 break;
142 case CPDF_AAction::ButtonUp:
143 eEventType = XFA_EVENT_MouseUp;
144 break;
145 case CPDF_AAction::GetFocus:
146 eEventType = XFA_EVENT_Enter;
147 break;
148 case CPDF_AAction::LoseFocus:
149 eEventType = XFA_EVENT_Exit;
150 break;
151 case CPDF_AAction::PageOpen:
152 break;
153 case CPDF_AAction::PageClose:
154 break;
155 case CPDF_AAction::PageVisible:
156 break;
157 case CPDF_AAction::PageInvisible:
158 break;
159 case CPDF_AAction::KeyStroke:
160 if (!bWillCommit) {
161 eEventType = XFA_EVENT_Change;
162 }
163 break;
164 case CPDF_AAction::Validate:
165 eEventType = XFA_EVENT_Validate;
166 break;
167 case CPDF_AAction::OpenPage:
168 case CPDF_AAction::ClosePage:
169 case CPDF_AAction::Format:
170 case CPDF_AAction::Calculate:
171 case CPDF_AAction::CloseDocument:
172 case CPDF_AAction::SaveDocument:
173 case CPDF_AAction::DocumentSaved:
174 case CPDF_AAction::PrintDocument:
175 case CPDF_AAction::DocumentPrinted:
176 break;
177 }
178
179 return eEventType;
180}
181
182FX_BOOL CPDFSDK_Widget::HasXFAAAction(PDFSDK_XFAAActionType eXFAAAT) {
Lei Zhang99766722016-02-23 11:21:48 -0800183 if (IXFA_Widget* hWidget = GetMixXFAWidget()) {
184 if (IXFA_WidgetHandler* pXFAWidgetHandler = GetXFAWidgetHandler()) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700185 XFA_EVENTTYPE eEventType = GetXFAEventType(eXFAAAT);
186
187 if ((eEventType == XFA_EVENT_Click || eEventType == XFA_EVENT_Change) &&
188 GetFieldType() == FIELDTYPE_RADIOBUTTON) {
189 if (IXFA_Widget* hGroupWidget = GetGroupMixXFAWidget()) {
190 CXFA_WidgetAcc* pAcc = pXFAWidgetHandler->GetDataAcc(hGroupWidget);
191 if (pXFAWidgetHandler->HasEvent(pAcc, eEventType))
192 return TRUE;
193 }
194 }
195
196 {
197 CXFA_WidgetAcc* pAcc = pXFAWidgetHandler->GetDataAcc(hWidget);
198 return pXFAWidgetHandler->HasEvent(pAcc, eEventType);
199 }
200 }
201 }
202
203 return FALSE;
204}
205
206FX_BOOL CPDFSDK_Widget::OnXFAAAction(PDFSDK_XFAAActionType eXFAAAT,
207 PDFSDK_FieldAction& data,
208 CPDFSDK_PageView* pPageView) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700209 CPDFSDK_Document* pSDKDoc = m_pPageView->GetSDKDocument();
Tom Sepez50d12ad2015-11-24 09:50:51 -0800210 CPDFXFA_Document* pDoc = pSDKDoc->GetXFADocument();
211 if (IXFA_Widget* hWidget = GetMixXFAWidget()) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700212 XFA_EVENTTYPE eEventType = GetXFAEventType(eXFAAAT);
213
214 if (eEventType != XFA_EVENT_Unknown) {
Lei Zhang99766722016-02-23 11:21:48 -0800215 if (IXFA_WidgetHandler* pXFAWidgetHandler = GetXFAWidgetHandler()) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700216 CXFA_EventParam param;
217 param.m_eType = eEventType;
218 param.m_wsChange = data.sChange;
219 param.m_iCommitKey = data.nCommitKey;
220 param.m_bShift = data.bShift;
221 param.m_iSelStart = data.nSelStart;
222 param.m_iSelEnd = data.nSelEnd;
223 param.m_wsFullText = data.sValue;
224 param.m_bKeyDown = data.bKeyDown;
225 param.m_bModifier = data.bModifier;
226 param.m_wsNewText = data.sValue;
227 if (data.nSelEnd > data.nSelStart)
228 param.m_wsNewText.Delete(data.nSelStart,
229 data.nSelEnd - data.nSelStart);
230 for (int i = 0; i < data.sChange.GetLength(); i++)
231 param.m_wsNewText.Insert(data.nSelStart, data.sChange[i]);
232 param.m_wsPrevText = data.sValue;
233
234 if ((eEventType == XFA_EVENT_Click || eEventType == XFA_EVENT_Change) &&
235 GetFieldType() == FIELDTYPE_RADIOBUTTON) {
236 if (IXFA_Widget* hGroupWidget = GetGroupMixXFAWidget()) {
237 CXFA_WidgetAcc* pAcc = pXFAWidgetHandler->GetDataAcc(hGroupWidget);
238 param.m_pTarget = pAcc;
239 pXFAWidgetHandler->ProcessEvent(pAcc, &param);
240 }
241
242 {
243 CXFA_WidgetAcc* pAcc = pXFAWidgetHandler->GetDataAcc(hWidget);
244 param.m_pTarget = pAcc;
245 int32_t nRet = pXFAWidgetHandler->ProcessEvent(pAcc, &param);
Wei Lie98ac2e2016-03-18 15:43:04 -0700246 return nRet == XFA_EVENTERROR_Success;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700247 }
248 } else {
249 CXFA_WidgetAcc* pAcc = pXFAWidgetHandler->GetDataAcc(hWidget);
250 param.m_pTarget = pAcc;
251 int32_t nRet = pXFAWidgetHandler->ProcessEvent(pAcc, &param);
Wei Lie98ac2e2016-03-18 15:43:04 -0700252 return nRet == XFA_EVENTERROR_Success;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700253 }
254
255 if (IXFA_DocView* pDocView = pDoc->GetXFADocView()) {
256 pDocView->UpdateDocView();
257 }
258 }
259 }
260 }
261
262 return FALSE;
263}
264
265void CPDFSDK_Widget::Synchronize(FX_BOOL bSynchronizeElse) {
Lei Zhang99766722016-02-23 11:21:48 -0800266 if (IXFA_Widget* hWidget = GetMixXFAWidget()) {
267 if (IXFA_WidgetHandler* pXFAWidgetHandler = GetXFAWidgetHandler()) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700268 CPDF_FormField* pFormField = GetFormField();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700269 if (CXFA_WidgetAcc* pWidgetAcc = pXFAWidgetHandler->GetDataAcc(hWidget)) {
270 switch (GetFieldType()) {
271 case FIELDTYPE_CHECKBOX:
272 case FIELDTYPE_RADIOBUTTON: {
273 CPDF_FormControl* pFormCtrl = GetFormControl();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700274 XFA_CHECKSTATE eCheckState =
275 pFormCtrl->IsChecked() ? XFA_CHECKSTATE_On : XFA_CHECKSTATE_Off;
276 pWidgetAcc->SetCheckState(eCheckState);
277 } break;
278 case FIELDTYPE_TEXTFIELD:
279 pWidgetAcc->SetValue(pFormField->GetValue(), XFA_VALUEPICTURE_Edit);
280 break;
281 case FIELDTYPE_LISTBOX: {
282 pWidgetAcc->ClearAllSelections();
283
284 for (int i = 0, sz = pFormField->CountSelectedItems(); i < sz;
285 i++) {
286 int nIndex = pFormField->GetSelectedIndex(i);
287 if (nIndex > -1 && nIndex < pWidgetAcc->CountChoiceListItems())
288 pWidgetAcc->SetItemState(nIndex, TRUE, FALSE);
289 }
290 } break;
291 case FIELDTYPE_COMBOBOX: {
292 pWidgetAcc->ClearAllSelections();
293
294 for (int i = 0, sz = pFormField->CountSelectedItems(); i < sz;
295 i++) {
296 int nIndex = pFormField->GetSelectedIndex(i);
297 if (nIndex > -1 && nIndex < pWidgetAcc->CountChoiceListItems())
298 pWidgetAcc->SetItemState(nIndex, TRUE, FALSE);
299 }
300 }
301
302 pWidgetAcc->SetValue(pFormField->GetValue(), XFA_VALUEPICTURE_Edit);
303 break;
304 }
305
306 if (bSynchronizeElse)
307 pWidgetAcc->ProcessValueChanged();
308 }
309 }
310 }
311}
312
313void CPDFSDK_Widget::SynchronizeXFAValue() {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700314 CPDFSDK_Document* pSDKDoc = m_pPageView->GetSDKDocument();
Tom Sepez50d12ad2015-11-24 09:50:51 -0800315 CPDFXFA_Document* pDoc = pSDKDoc->GetXFADocument();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700316 IXFA_DocView* pXFADocView = pDoc->GetXFADocView();
317 if (!pXFADocView)
318 return;
319
Tom Sepezbf59a072015-10-21 14:07:23 -0700320 if (IXFA_Widget* hWidget = GetMixXFAWidget()) {
321 if (GetXFAWidgetHandler()) {
322 CPDFSDK_Widget::SynchronizeXFAValue(pXFADocView, hWidget, GetFormField(),
323 GetFormControl());
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700324 }
325 }
326}
327
328void CPDFSDK_Widget::SynchronizeXFAItems() {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700329 CPDFSDK_Document* pSDKDoc = m_pPageView->GetSDKDocument();
Tom Sepez50d12ad2015-11-24 09:50:51 -0800330 CPDFXFA_Document* pDoc = pSDKDoc->GetXFADocument();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700331 IXFA_DocView* pXFADocView = pDoc->GetXFADocView();
332 if (!pXFADocView)
333 return;
334
Tom Sepezbf59a072015-10-21 14:07:23 -0700335 if (IXFA_Widget* hWidget = GetMixXFAWidget()) {
336 if (GetXFAWidgetHandler())
337 SynchronizeXFAItems(pXFADocView, hWidget, GetFormField(), nullptr);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700338 }
339}
340
341void CPDFSDK_Widget::SynchronizeXFAValue(IXFA_DocView* pXFADocView,
342 IXFA_Widget* hWidget,
343 CPDF_FormField* pFormField,
344 CPDF_FormControl* pFormControl) {
Lei Zhang5eca3052016-02-22 20:32:21 -0800345 ASSERT(hWidget);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700346
347 if (IXFA_WidgetHandler* pXFAWidgetHandler = pXFADocView->GetWidgetHandler()) {
Lei Zhang5eca3052016-02-22 20:32:21 -0800348 ASSERT(pFormControl);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700349
350 switch (pFormField->GetFieldType()) {
351 case FIELDTYPE_CHECKBOX: {
352 if (CXFA_WidgetAcc* pWidgetAcc =
353 pXFAWidgetHandler->GetDataAcc(hWidget)) {
Wei Lie4076482016-03-15 10:58:40 -0700354 pFormField->CheckControl(
355 pFormField->GetControlIndex(pFormControl),
356 pWidgetAcc->GetCheckState() == XFA_CHECKSTATE_On, true);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700357 }
358 } break;
359 case FIELDTYPE_RADIOBUTTON: {
Wei Lie4076482016-03-15 10:58:40 -0700360 // TODO(weili): Check whether we need to handle checkbox and radio
361 // button differently, otherwise, merge these two cases.
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700362 if (CXFA_WidgetAcc* pWidgetAcc =
363 pXFAWidgetHandler->GetDataAcc(hWidget)) {
Wei Lie4076482016-03-15 10:58:40 -0700364 pFormField->CheckControl(
365 pFormField->GetControlIndex(pFormControl),
366 pWidgetAcc->GetCheckState() == XFA_CHECKSTATE_On, true);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700367 }
368 } break;
369 case FIELDTYPE_TEXTFIELD: {
370 if (CXFA_WidgetAcc* pWidgetAcc =
371 pXFAWidgetHandler->GetDataAcc(hWidget)) {
372 CFX_WideString sValue;
373 pWidgetAcc->GetValue(sValue, XFA_VALUEPICTURE_Display);
374 pFormField->SetValue(sValue, TRUE);
375 }
376 } break;
377 case FIELDTYPE_LISTBOX: {
378 pFormField->ClearSelection(FALSE);
379
380 if (CXFA_WidgetAcc* pWidgetAcc =
381 pXFAWidgetHandler->GetDataAcc(hWidget)) {
382 for (int i = 0, sz = pWidgetAcc->CountSelectedItems(); i < sz; i++) {
383 int nIndex = pWidgetAcc->GetSelectedItem(i);
384
385 if (nIndex > -1 && nIndex < pFormField->CountOptions()) {
386 pFormField->SetItemSelection(nIndex, TRUE, TRUE);
387 }
388 }
389 }
390 } break;
391 case FIELDTYPE_COMBOBOX: {
392 pFormField->ClearSelection(FALSE);
393
394 if (CXFA_WidgetAcc* pWidgetAcc =
395 pXFAWidgetHandler->GetDataAcc(hWidget)) {
396 for (int i = 0, sz = pWidgetAcc->CountSelectedItems(); i < sz; i++) {
397 int nIndex = pWidgetAcc->GetSelectedItem(i);
398
399 if (nIndex > -1 && nIndex < pFormField->CountOptions()) {
400 pFormField->SetItemSelection(nIndex, TRUE, TRUE);
401 }
402 }
403
404 CFX_WideString sValue;
405 pWidgetAcc->GetValue(sValue, XFA_VALUEPICTURE_Display);
406 pFormField->SetValue(sValue, TRUE);
407 }
408 } break;
409 }
410 }
411}
412
413void CPDFSDK_Widget::SynchronizeXFAItems(IXFA_DocView* pXFADocView,
414 IXFA_Widget* hWidget,
415 CPDF_FormField* pFormField,
416 CPDF_FormControl* pFormControl) {
Lei Zhang5eca3052016-02-22 20:32:21 -0800417 ASSERT(hWidget);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700418
419 if (IXFA_WidgetHandler* pXFAWidgetHandler = pXFADocView->GetWidgetHandler()) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700420 switch (pFormField->GetFieldType()) {
421 case FIELDTYPE_LISTBOX: {
422 pFormField->ClearSelection(FALSE);
423 pFormField->ClearOptions(TRUE);
424
425 if (CXFA_WidgetAcc* pWidgetAcc =
426 pXFAWidgetHandler->GetDataAcc(hWidget)) {
427 for (int i = 0, sz = pWidgetAcc->CountChoiceListItems(); i < sz;
428 i++) {
429 CFX_WideString swText;
430 pWidgetAcc->GetChoiceListItem(swText, i);
431
432 pFormField->InsertOption(swText, i, TRUE);
433 }
434 }
435 } break;
436 case FIELDTYPE_COMBOBOX: {
437 pFormField->ClearSelection(FALSE);
438 pFormField->ClearOptions(FALSE);
439
440 if (CXFA_WidgetAcc* pWidgetAcc =
441 pXFAWidgetHandler->GetDataAcc(hWidget)) {
442 for (int i = 0, sz = pWidgetAcc->CountChoiceListItems(); i < sz;
443 i++) {
444 CFX_WideString swText;
445 pWidgetAcc->GetChoiceListItem(swText, i);
446
447 pFormField->InsertOption(swText, i, FALSE);
448 }
449 }
450
451 pFormField->SetValue(L"", TRUE);
452 } break;
453 }
454 }
455}
Tom Sepez40e9ff32015-11-30 12:39:54 -0800456#endif // PDF_ENABLE_XFA
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700457
458FX_BOOL CPDFSDK_Widget::IsWidgetAppearanceValid(
459 CPDF_Annot::AppearanceMode mode) {
Wei Li9b761132016-01-29 15:44:20 -0800460 CPDF_Dictionary* pAP = m_pAnnot->GetAnnotDict()->GetDictBy("AP");
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700461 if (!pAP)
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700462 return FALSE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700463
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700464 // Choose the right sub-ap
465 const FX_CHAR* ap_entry = "N";
466 if (mode == CPDF_Annot::Down)
467 ap_entry = "D";
468 else if (mode == CPDF_Annot::Rollover)
469 ap_entry = "R";
470 if (!pAP->KeyExist(ap_entry))
471 ap_entry = "N";
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700472
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700473 // Get the AP stream or subdirectory
474 CPDF_Object* psub = pAP->GetElementValue(ap_entry);
475 if (!psub)
476 return FALSE;
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700477
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700478 int nFieldType = GetFieldType();
479 switch (nFieldType) {
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700480 case FIELDTYPE_PUSHBUTTON:
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700481 case FIELDTYPE_COMBOBOX:
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700482 case FIELDTYPE_LISTBOX:
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700483 case FIELDTYPE_TEXTFIELD:
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700484 case FIELDTYPE_SIGNATURE:
Dan Sinclairaa435ba2015-10-22 16:45:48 -0400485 return psub->IsStream();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700486 case FIELDTYPE_CHECKBOX:
487 case FIELDTYPE_RADIOBUTTON:
Dan Sinclairf1251c12015-10-20 16:24:45 -0400488 if (CPDF_Dictionary* pSubDict = psub->AsDictionary()) {
Wei Li9b761132016-01-29 15:44:20 -0800489 return pSubDict->GetStreamBy(GetAppState()) != NULL;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700490 }
491 return FALSE;
492 }
493 return TRUE;
494}
495
496int CPDFSDK_Widget::GetFieldType() const {
Lei Zhang96660d62015-12-14 18:27:25 -0800497 return GetFormField()->GetFieldType();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700498}
499
500FX_BOOL CPDFSDK_Widget::IsAppearanceValid() {
Tom Sepez51da0932015-11-25 16:05:49 -0800501#ifdef PDF_ENABLE_XFA
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700502 CPDFSDK_Document* pSDKDoc = m_pPageView->GetSDKDocument();
Tom Sepez50d12ad2015-11-24 09:50:51 -0800503 CPDFXFA_Document* pDoc = pSDKDoc->GetXFADocument();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700504 int nDocType = pDoc->GetDocType();
Tom Sepez540c4362015-11-24 13:33:57 -0800505 if (nDocType != DOCTYPE_PDF && nDocType != DOCTYPE_STATIC_XFA)
506 return TRUE;
Tom Sepez40e9ff32015-11-30 12:39:54 -0800507#endif // PDF_ENABLE_XFA
Tom Sepez540c4362015-11-24 13:33:57 -0800508 return CPDFSDK_BAAnnot::IsAppearanceValid();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700509}
510
511int CPDFSDK_Widget::GetFieldFlags() const {
512 CPDF_InterForm* pPDFInterForm = m_pInterForm->GetInterForm();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700513 CPDF_FormControl* pFormControl =
514 pPDFInterForm->GetControlByDict(m_pAnnot->GetAnnotDict());
515 CPDF_FormField* pFormField = pFormControl->GetField();
516 return pFormField->GetFieldFlags();
517}
518
519CFX_ByteString CPDFSDK_Widget::GetSubType() const {
520 int nType = GetFieldType();
521
522 if (nType == FIELDTYPE_SIGNATURE)
523 return BFFT_SIGNATURE;
524 return CPDFSDK_Annot::GetSubType();
525}
526
527CPDF_FormField* CPDFSDK_Widget::GetFormField() const {
Lei Zhang1b700c32015-10-30 23:55:35 -0700528 return GetFormControl()->GetField();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700529}
530
531CPDF_FormControl* CPDFSDK_Widget::GetFormControl() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700532 CPDF_InterForm* pPDFInterForm = m_pInterForm->GetInterForm();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700533 return pPDFInterForm->GetControlByDict(GetAnnotDict());
534}
535
Lei Zhang1b700c32015-10-30 23:55:35 -0700536CPDF_FormControl* CPDFSDK_Widget::GetFormControl(
537 CPDF_InterForm* pInterForm,
538 const CPDF_Dictionary* pAnnotDict) {
Lei Zhang96660d62015-12-14 18:27:25 -0800539 ASSERT(pAnnotDict);
Lei Zhang1b700c32015-10-30 23:55:35 -0700540 return pInterForm->GetControlByDict(pAnnotDict);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700541}
542
543int CPDFSDK_Widget::GetRotate() const {
544 CPDF_FormControl* pCtrl = GetFormControl();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700545 return pCtrl->GetRotation() % 360;
546}
547
Tom Sepez51da0932015-11-25 16:05:49 -0800548#ifdef PDF_ENABLE_XFA
Tom Sepezbf59a072015-10-21 14:07:23 -0700549CFX_WideString CPDFSDK_Widget::GetName() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700550 CPDF_FormField* pFormField = GetFormField();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700551 return pFormField->GetFullName();
552}
Tom Sepez40e9ff32015-11-30 12:39:54 -0800553#endif // PDF_ENABLE_XFA
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700554
555FX_BOOL CPDFSDK_Widget::GetFillColor(FX_COLORREF& color) const {
556 CPDF_FormControl* pFormCtrl = GetFormControl();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700557 int iColorType = 0;
558 color = FX_ARGBTOCOLORREF(pFormCtrl->GetBackgroundColor(iColorType));
559
560 return iColorType != COLORTYPE_TRANSPARENT;
561}
562
563FX_BOOL CPDFSDK_Widget::GetBorderColor(FX_COLORREF& color) const {
564 CPDF_FormControl* pFormCtrl = GetFormControl();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700565 int iColorType = 0;
566 color = FX_ARGBTOCOLORREF(pFormCtrl->GetBorderColor(iColorType));
567
568 return iColorType != COLORTYPE_TRANSPARENT;
569}
570
571FX_BOOL CPDFSDK_Widget::GetTextColor(FX_COLORREF& color) const {
572 CPDF_FormControl* pFormCtrl = GetFormControl();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700573 CPDF_DefaultAppearance da = pFormCtrl->GetDefaultAppearance();
574 if (da.HasColor()) {
575 FX_ARGB argb;
576 int iColorType = COLORTYPE_TRANSPARENT;
577 da.GetColor(argb, iColorType);
578 color = FX_ARGBTOCOLORREF(argb);
579
580 return iColorType != COLORTYPE_TRANSPARENT;
581 }
582
583 return FALSE;
584}
585
586FX_FLOAT CPDFSDK_Widget::GetFontSize() const {
587 CPDF_FormControl* pFormCtrl = GetFormControl();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700588 CPDF_DefaultAppearance pDa = pFormCtrl->GetDefaultAppearance();
589 CFX_ByteString csFont = "";
590 FX_FLOAT fFontSize = 0.0f;
591 pDa.GetFont(csFont, fFontSize);
592
593 return fFontSize;
594}
595
Tom Sepezbf59a072015-10-21 14:07:23 -0700596int CPDFSDK_Widget::GetSelectedIndex(int nIndex) const {
Tom Sepeza8a39e22015-10-12 15:47:07 -0700597#ifdef PDF_ENABLE_XFA
Lei Zhang99766722016-02-23 11:21:48 -0800598 if (IXFA_Widget* hWidget = GetMixXFAWidget()) {
599 if (IXFA_WidgetHandler* pXFAWidgetHandler = GetXFAWidgetHandler()) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700600 if (CXFA_WidgetAcc* pWidgetAcc = pXFAWidgetHandler->GetDataAcc(hWidget)) {
601 if (nIndex < pWidgetAcc->CountSelectedItems())
602 return pWidgetAcc->GetSelectedItem(nIndex);
603 }
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700604 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700605 }
Tom Sepeza8a39e22015-10-12 15:47:07 -0700606#endif // PDF_ENABLE_XFA
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700607 CPDF_FormField* pFormField = GetFormField();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700608 return pFormField->GetSelectedIndex(nIndex);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700609}
610
Tom Sepeza8a39e22015-10-12 15:47:07 -0700611#ifdef PDF_ENABLE_XFA
Tom Sepez40e9ff32015-11-30 12:39:54 -0800612CFX_WideString CPDFSDK_Widget::GetValue(FX_BOOL bDisplay) const {
Lei Zhang99766722016-02-23 11:21:48 -0800613 if (IXFA_Widget* hWidget = GetMixXFAWidget()) {
614 if (IXFA_WidgetHandler* pXFAWidgetHandler = GetXFAWidgetHandler()) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700615 if (CXFA_WidgetAcc* pWidgetAcc = pXFAWidgetHandler->GetDataAcc(hWidget)) {
616 CFX_WideString sValue;
617 pWidgetAcc->GetValue(sValue, bDisplay ? XFA_VALUEPICTURE_Display
618 : XFA_VALUEPICTURE_Edit);
619 return sValue;
620 }
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700621 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700622 }
Tom Sepez40e9ff32015-11-30 12:39:54 -0800623#else
624CFX_WideString CPDFSDK_Widget::GetValue() const {
Tom Sepeza8a39e22015-10-12 15:47:07 -0700625#endif // PDF_ENABLE_XFA
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700626 CPDF_FormField* pFormField = GetFormField();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700627 return pFormField->GetValue();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700628}
629
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700630CFX_WideString CPDFSDK_Widget::GetDefaultValue() const {
631 CPDF_FormField* pFormField = GetFormField();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700632 return pFormField->GetDefaultValue();
633}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700634
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700635CFX_WideString CPDFSDK_Widget::GetOptionLabel(int nIndex) const {
636 CPDF_FormField* pFormField = GetFormField();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700637 return pFormField->GetOptionLabel(nIndex);
638}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700639
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700640int CPDFSDK_Widget::CountOptions() const {
641 CPDF_FormField* pFormField = GetFormField();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700642 return pFormField->CountOptions();
643}
644
Tom Sepezbf59a072015-10-21 14:07:23 -0700645FX_BOOL CPDFSDK_Widget::IsOptionSelected(int nIndex) const {
Tom Sepeza8a39e22015-10-12 15:47:07 -0700646#ifdef PDF_ENABLE_XFA
Lei Zhang99766722016-02-23 11:21:48 -0800647 if (IXFA_Widget* hWidget = GetMixXFAWidget()) {
648 if (IXFA_WidgetHandler* pXFAWidgetHandler = GetXFAWidgetHandler()) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700649 if (CXFA_WidgetAcc* pWidgetAcc = pXFAWidgetHandler->GetDataAcc(hWidget)) {
650 if (nIndex > -1 && nIndex < pWidgetAcc->CountChoiceListItems())
651 return pWidgetAcc->GetItemState(nIndex);
652
653 return FALSE;
654 }
655 }
656 }
Tom Sepeza8a39e22015-10-12 15:47:07 -0700657#endif // PDF_ENABLE_XFA
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700658 CPDF_FormField* pFormField = GetFormField();
659 return pFormField->IsItemSelected(nIndex);
660}
661
662int CPDFSDK_Widget::GetTopVisibleIndex() const {
663 CPDF_FormField* pFormField = GetFormField();
664 return pFormField->GetTopVisibleIndex();
665}
666
Wei Li97da9762016-03-11 17:00:48 -0800667bool CPDFSDK_Widget::IsChecked() const {
Tom Sepeza8a39e22015-10-12 15:47:07 -0700668#ifdef PDF_ENABLE_XFA
Lei Zhang99766722016-02-23 11:21:48 -0800669 if (IXFA_WidgetHandler* pXFAWidgetHandler = GetXFAWidgetHandler()) {
670 if (IXFA_Widget* hWidget = GetMixXFAWidget()) {
Tom Sepez007e6c02016-02-26 14:31:56 -0800671 if (CXFA_WidgetAcc* pWidgetAcc = pXFAWidgetHandler->GetDataAcc(hWidget))
672 return pWidgetAcc->GetCheckState() == XFA_CHECKSTATE_On;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700673 }
674 }
Tom Sepeza8a39e22015-10-12 15:47:07 -0700675#endif // PDF_ENABLE_XFA
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700676 CPDF_FormControl* pFormCtrl = GetFormControl();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700677 return pFormCtrl->IsChecked();
678}
679
680int CPDFSDK_Widget::GetAlignment() const {
681 CPDF_FormControl* pFormCtrl = GetFormControl();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700682 return pFormCtrl->GetControlAlignment();
683}
684
685int CPDFSDK_Widget::GetMaxLen() const {
686 CPDF_FormField* pFormField = GetFormField();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700687 return pFormField->GetMaxLen();
688}
689
Wei Li97da9762016-03-11 17:00:48 -0800690void CPDFSDK_Widget::SetCheck(bool bChecked, bool bNotify) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700691 CPDF_FormControl* pFormCtrl = GetFormControl();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700692 CPDF_FormField* pFormField = pFormCtrl->GetField();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700693 pFormField->CheckControl(pFormField->GetControlIndex(pFormCtrl), bChecked,
694 bNotify);
Tom Sepez51da0932015-11-25 16:05:49 -0800695#ifdef PDF_ENABLE_XFA
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700696 if (!IsWidgetAppearanceValid(CPDF_Annot::Normal))
697 ResetAppearance(TRUE);
698 if (!bNotify)
699 Synchronize(TRUE);
Tom Sepez40e9ff32015-11-30 12:39:54 -0800700#endif // PDF_ENABLE_XFA
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700701}
702
703void CPDFSDK_Widget::SetValue(const CFX_WideString& sValue, FX_BOOL bNotify) {
704 CPDF_FormField* pFormField = GetFormField();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700705 pFormField->SetValue(sValue, bNotify);
Tom Sepez51da0932015-11-25 16:05:49 -0800706#ifdef PDF_ENABLE_XFA
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700707 if (!bNotify)
708 Synchronize(TRUE);
Tom Sepez40e9ff32015-11-30 12:39:54 -0800709#endif // PDF_ENABLE_XFA
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700710}
711
712void CPDFSDK_Widget::SetDefaultValue(const CFX_WideString& sValue) {}
713void CPDFSDK_Widget::SetOptionSelection(int index,
714 FX_BOOL bSelected,
715 FX_BOOL bNotify) {
716 CPDF_FormField* pFormField = GetFormField();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700717 pFormField->SetItemSelection(index, bSelected, bNotify);
Tom Sepez51da0932015-11-25 16:05:49 -0800718#ifdef PDF_ENABLE_XFA
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700719 if (!bNotify)
720 Synchronize(TRUE);
Tom Sepez40e9ff32015-11-30 12:39:54 -0800721#endif // PDF_ENABLE_XFA
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700722}
723
724void CPDFSDK_Widget::ClearSelection(FX_BOOL bNotify) {
725 CPDF_FormField* pFormField = GetFormField();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700726 pFormField->ClearSelection(bNotify);
Tom Sepez51da0932015-11-25 16:05:49 -0800727#ifdef PDF_ENABLE_XFA
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700728 if (!bNotify)
729 Synchronize(TRUE);
Tom Sepez40e9ff32015-11-30 12:39:54 -0800730#endif // PDF_ENABLE_XFA
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700731}
732
733void CPDFSDK_Widget::SetTopVisibleIndex(int index) {}
734
735void CPDFSDK_Widget::SetAppModified() {
736 m_bAppModified = TRUE;
737}
738
739void CPDFSDK_Widget::ClearAppModified() {
740 m_bAppModified = FALSE;
741}
742
743FX_BOOL CPDFSDK_Widget::IsAppModified() const {
744 return m_bAppModified;
745}
746
Tom Sepez51da0932015-11-25 16:05:49 -0800747#ifdef PDF_ENABLE_XFA
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700748void CPDFSDK_Widget::ResetAppearance(FX_BOOL bValueChanged) {
749 switch (GetFieldType()) {
750 case FIELDTYPE_TEXTFIELD:
751 case FIELDTYPE_COMBOBOX: {
752 FX_BOOL bFormated = FALSE;
Lei Zhang99766722016-02-23 11:21:48 -0800753 CFX_WideString sValue = OnFormat(bFormated);
754 ResetAppearance(bFormated ? sValue : nullptr, TRUE);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700755 } break;
756 default:
Lei Zhang99766722016-02-23 11:21:48 -0800757 ResetAppearance(nullptr, FALSE);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700758 break;
759 }
760}
Tom Sepez40e9ff32015-11-30 12:39:54 -0800761#endif // PDF_ENABLE_XFA
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700762
763void CPDFSDK_Widget::ResetAppearance(const FX_WCHAR* sValue,
764 FX_BOOL bValueChanged) {
765 SetAppModified();
766
767 m_nAppAge++;
768 if (m_nAppAge > 999999)
769 m_nAppAge = 0;
770 if (bValueChanged)
771 m_nValueAge++;
772
773 int nFieldType = GetFieldType();
774
775 switch (nFieldType) {
776 case FIELDTYPE_PUSHBUTTON:
777 ResetAppearance_PushButton();
778 break;
779 case FIELDTYPE_CHECKBOX:
780 ResetAppearance_CheckBox();
781 break;
782 case FIELDTYPE_RADIOBUTTON:
783 ResetAppearance_RadioButton();
784 break;
785 case FIELDTYPE_COMBOBOX:
786 ResetAppearance_ComboBox(sValue);
787 break;
788 case FIELDTYPE_LISTBOX:
789 ResetAppearance_ListBox();
790 break;
791 case FIELDTYPE_TEXTFIELD:
792 ResetAppearance_TextField(sValue);
793 break;
794 }
795
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700796 m_pAnnot->ClearCachedAP();
797}
798
799CFX_WideString CPDFSDK_Widget::OnFormat(FX_BOOL& bFormated) {
800 CPDF_FormField* pFormField = GetFormField();
Lei Zhang96660d62015-12-14 18:27:25 -0800801 ASSERT(pFormField);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700802 return m_pInterForm->OnFormat(pFormField, bFormated);
803}
804
805void CPDFSDK_Widget::ResetFieldAppearance(FX_BOOL bValueChanged) {
806 CPDF_FormField* pFormField = GetFormField();
Lei Zhang96660d62015-12-14 18:27:25 -0800807 ASSERT(pFormField);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700808 m_pInterForm->ResetFieldAppearance(pFormField, NULL, bValueChanged);
809}
810
811void CPDFSDK_Widget::DrawAppearance(CFX_RenderDevice* pDevice,
Tom Sepez60d909e2015-12-10 15:34:55 -0800812 const CFX_Matrix* pUser2Device,
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700813 CPDF_Annot::AppearanceMode mode,
814 const CPDF_RenderOptions* pOptions) {
815 int nFieldType = GetFieldType();
816
817 if ((nFieldType == FIELDTYPE_CHECKBOX ||
818 nFieldType == FIELDTYPE_RADIOBUTTON) &&
819 mode == CPDF_Annot::Normal &&
820 !IsWidgetAppearanceValid(CPDF_Annot::Normal)) {
821 CFX_PathData pathData;
822
Tom Sepez281a9ea2016-02-26 14:24:28 -0800823 CFX_FloatRect rcAnnot = GetRect();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700824
825 pathData.AppendRect(rcAnnot.left, rcAnnot.bottom, rcAnnot.right,
826 rcAnnot.top);
827
828 CFX_GraphStateData gsd;
829 gsd.m_LineWidth = 0.0f;
830
831 pDevice->DrawPath(&pathData, pUser2Device, &gsd, 0, 0xFFAAAAAA,
832 FXFILL_ALTERNATE);
833 } else {
834 CPDFSDK_BAAnnot::DrawAppearance(pDevice, pUser2Device, mode, pOptions);
835 }
836}
837
838void CPDFSDK_Widget::UpdateField() {
839 CPDF_FormField* pFormField = GetFormField();
Lei Zhang96660d62015-12-14 18:27:25 -0800840 ASSERT(pFormField);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700841 m_pInterForm->UpdateField(pFormField);
842}
843
844void CPDFSDK_Widget::DrawShadow(CFX_RenderDevice* pDevice,
845 CPDFSDK_PageView* pPageView) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700846 int nFieldType = GetFieldType();
847 if (m_pInterForm->IsNeedHighLight(nFieldType)) {
Tom Sepez281a9ea2016-02-26 14:24:28 -0800848 CFX_FloatRect rc = GetRect();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700849 FX_COLORREF color = m_pInterForm->GetHighlightColor(nFieldType);
850 uint8_t alpha = m_pInterForm->GetHighlightAlpha();
851
852 CFX_FloatRect rcDevice;
853 ASSERT(m_pInterForm->GetDocument());
854 CPDFDoc_Environment* pEnv = m_pInterForm->GetDocument()->GetEnv();
855 if (!pEnv)
856 return;
Tom Sepez60d909e2015-12-10 15:34:55 -0800857 CFX_Matrix page2device;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700858 pPageView->GetCurrentMatrix(page2device);
859 page2device.Transform(((FX_FLOAT)rc.left), ((FX_FLOAT)rc.bottom),
860 rcDevice.left, rcDevice.bottom);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700861 page2device.Transform(((FX_FLOAT)rc.right), ((FX_FLOAT)rc.top),
862 rcDevice.right, rcDevice.top);
863
864 rcDevice.Normalize();
865
866 FX_ARGB argb = ArgbEncode((int)alpha, color);
867 FX_RECT rcDev((int)rcDevice.left, (int)rcDevice.top, (int)rcDevice.right,
868 (int)rcDevice.bottom);
869 pDevice->FillRect(&rcDev, argb);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700870 }
871}
872
873void CPDFSDK_Widget::ResetAppearance_PushButton() {
874 CPDF_FormControl* pControl = GetFormControl();
Tom Sepez281a9ea2016-02-26 14:24:28 -0800875 CFX_FloatRect rcWindow = GetRotatedRect();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700876 int32_t nLayout = 0;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700877 switch (pControl->GetTextPosition()) {
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700878 case TEXTPOS_ICON:
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700879 nLayout = PPBL_ICON;
880 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700881 case TEXTPOS_BELOW:
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700882 nLayout = PPBL_ICONTOPLABELBOTTOM;
883 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700884 case TEXTPOS_ABOVE:
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700885 nLayout = PPBL_LABELTOPICONBOTTOM;
886 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700887 case TEXTPOS_RIGHT:
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700888 nLayout = PPBL_ICONLEFTLABELRIGHT;
889 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700890 case TEXTPOS_LEFT:
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700891 nLayout = PPBL_LABELLEFTICONRIGHT;
892 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700893 case TEXTPOS_OVERLAID:
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700894 nLayout = PPBL_LABELOVERICON;
895 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700896 default:
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700897 nLayout = PPBL_LABEL;
898 break;
899 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700900
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700901 CPWL_Color crBackground, crBorder;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700902
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700903 int iColorType;
904 FX_FLOAT fc[4];
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700905
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700906 pControl->GetOriginalBackgroundColor(iColorType, fc);
907 if (iColorType > 0)
908 crBackground = CPWL_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700909
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700910 pControl->GetOriginalBorderColor(iColorType, fc);
911 if (iColorType > 0)
912 crBorder = CPWL_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700913
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700914 FX_FLOAT fBorderWidth = (FX_FLOAT)GetBorderWidth();
915 int32_t nBorderStyle = 0;
916 CPWL_Dash dsBorder(3, 0, 0);
917 CPWL_Color crLeftTop, crRightBottom;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700918
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700919 switch (GetBorderStyle()) {
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700920 case BBS_DASH:
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700921 nBorderStyle = PBS_DASH;
922 dsBorder = CPWL_Dash(3, 3, 0);
923 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700924 case BBS_BEVELED:
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700925 nBorderStyle = PBS_BEVELED;
926 fBorderWidth *= 2;
927 crLeftTop = CPWL_Color(COLORTYPE_GRAY, 1);
928 crRightBottom = CPWL_Utils::DevideColor(crBackground, 2);
929 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700930 case BBS_INSET:
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700931 nBorderStyle = PBS_INSET;
932 fBorderWidth *= 2;
933 crLeftTop = CPWL_Color(COLORTYPE_GRAY, 0.5);
934 crRightBottom = CPWL_Color(COLORTYPE_GRAY, 0.75);
935 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700936 case BBS_UNDERLINE:
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700937 nBorderStyle = PBS_UNDERLINED;
938 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700939 default:
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700940 nBorderStyle = PBS_SOLID;
941 break;
942 }
943
Tom Sepez281a9ea2016-02-26 14:24:28 -0800944 CFX_FloatRect rcClient = CPWL_Utils::DeflateRect(rcWindow, fBorderWidth);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700945
946 CPWL_Color crText(COLORTYPE_GRAY, 0);
947
948 FX_FLOAT fFontSize = 12.0f;
949 CFX_ByteString csNameTag;
950
951 CPDF_DefaultAppearance da = pControl->GetDefaultAppearance();
952 if (da.HasColor()) {
953 da.GetColor(iColorType, fc);
954 crText = CPWL_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
955 }
956
957 if (da.HasFont())
958 da.GetFont(csNameTag, fFontSize);
959
960 CFX_WideString csWCaption;
961 CFX_WideString csNormalCaption, csRolloverCaption, csDownCaption;
962
963 if (pControl->HasMKEntry("CA")) {
964 csNormalCaption = pControl->GetNormalCaption();
965 }
966 if (pControl->HasMKEntry("RC")) {
967 csRolloverCaption = pControl->GetRolloverCaption();
968 }
969 if (pControl->HasMKEntry("AC")) {
970 csDownCaption = pControl->GetDownCaption();
971 }
972
973 CPDF_Stream* pNormalIcon = NULL;
974 CPDF_Stream* pRolloverIcon = NULL;
975 CPDF_Stream* pDownIcon = NULL;
976
977 if (pControl->HasMKEntry("I")) {
978 pNormalIcon = pControl->GetNormalIcon();
979 }
980 if (pControl->HasMKEntry("RI")) {
981 pRolloverIcon = pControl->GetRolloverIcon();
982 }
983 if (pControl->HasMKEntry("IX")) {
984 pDownIcon = pControl->GetDownIcon();
985 }
986
987 if (pNormalIcon) {
988 if (CPDF_Dictionary* pImageDict = pNormalIcon->GetDict()) {
Wei Li9b761132016-01-29 15:44:20 -0800989 if (pImageDict->GetStringBy("Name").IsEmpty())
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700990 pImageDict->SetAtString("Name", "ImgA");
991 }
992 }
993
994 if (pRolloverIcon) {
995 if (CPDF_Dictionary* pImageDict = pRolloverIcon->GetDict()) {
Wei Li9b761132016-01-29 15:44:20 -0800996 if (pImageDict->GetStringBy("Name").IsEmpty())
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700997 pImageDict->SetAtString("Name", "ImgB");
998 }
999 }
1000
1001 if (pDownIcon) {
1002 if (CPDF_Dictionary* pImageDict = pDownIcon->GetDict()) {
Wei Li9b761132016-01-29 15:44:20 -08001003 if (pImageDict->GetStringBy("Name").IsEmpty())
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001004 pImageDict->SetAtString("Name", "ImgC");
1005 }
1006 }
1007
1008 CPDF_IconFit iconFit = pControl->GetIconFit();
1009
1010 CPDFSDK_Document* pDoc = m_pInterForm->GetDocument();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001011 CPDFDoc_Environment* pEnv = pDoc->GetEnv();
1012
Lei Zhangfcfa3b82015-12-24 21:07:28 -08001013 CBA_FontMap font_map(this, pEnv->GetSysHandler());
1014 font_map.SetAPType("N");
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001015
1016 CFX_ByteString csAP =
1017 CPWL_Utils::GetRectFillAppStream(rcWindow, crBackground) +
1018 CPWL_Utils::GetBorderAppStream(rcWindow, fBorderWidth, crBorder,
1019 crLeftTop, crRightBottom, nBorderStyle,
1020 dsBorder) +
1021 CPWL_Utils::GetPushButtonAppStream(
Lei Zhangfcfa3b82015-12-24 21:07:28 -08001022 iconFit.GetFittingBounds() ? rcWindow : rcClient, &font_map,
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001023 pNormalIcon, iconFit, csNormalCaption, crText, fFontSize, nLayout);
1024
1025 WriteAppearance("N", GetRotatedRect(), GetMatrix(), csAP);
1026 if (pNormalIcon)
1027 AddImageToAppearance("N", pNormalIcon);
1028
1029 CPDF_FormControl::HighlightingMode eHLM = pControl->GetHighlightingMode();
1030 if (eHLM == CPDF_FormControl::Push || eHLM == CPDF_FormControl::Toggle) {
1031 if (csRolloverCaption.IsEmpty() && !pRolloverIcon) {
1032 csRolloverCaption = csNormalCaption;
1033 pRolloverIcon = pNormalIcon;
1034 }
1035
Lei Zhangfcfa3b82015-12-24 21:07:28 -08001036 font_map.SetAPType("R");
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001037
1038 csAP = CPWL_Utils::GetRectFillAppStream(rcWindow, crBackground) +
1039 CPWL_Utils::GetBorderAppStream(rcWindow, fBorderWidth, crBorder,
1040 crLeftTop, crRightBottom,
1041 nBorderStyle, dsBorder) +
1042 CPWL_Utils::GetPushButtonAppStream(
Lei Zhangfcfa3b82015-12-24 21:07:28 -08001043 iconFit.GetFittingBounds() ? rcWindow : rcClient, &font_map,
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001044 pRolloverIcon, iconFit, csRolloverCaption, crText, fFontSize,
1045 nLayout);
1046
1047 WriteAppearance("R", GetRotatedRect(), GetMatrix(), csAP);
1048 if (pRolloverIcon)
1049 AddImageToAppearance("R", pRolloverIcon);
1050
1051 if (csDownCaption.IsEmpty() && !pDownIcon) {
1052 csDownCaption = csNormalCaption;
1053 pDownIcon = pNormalIcon;
1054 }
1055
1056 switch (nBorderStyle) {
1057 case PBS_BEVELED: {
1058 CPWL_Color crTemp = crLeftTop;
1059 crLeftTop = crRightBottom;
1060 crRightBottom = crTemp;
1061 } break;
1062 case PBS_INSET:
1063 crLeftTop = CPWL_Color(COLORTYPE_GRAY, 0);
1064 crRightBottom = CPWL_Color(COLORTYPE_GRAY, 1);
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001065 break;
1066 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001067
Lei Zhangfcfa3b82015-12-24 21:07:28 -08001068 font_map.SetAPType("D");
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001069
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001070 csAP = CPWL_Utils::GetRectFillAppStream(
1071 rcWindow, CPWL_Utils::SubstractColor(crBackground, 0.25f)) +
1072 CPWL_Utils::GetBorderAppStream(rcWindow, fBorderWidth, crBorder,
1073 crLeftTop, crRightBottom,
1074 nBorderStyle, dsBorder) +
1075 CPWL_Utils::GetPushButtonAppStream(
Lei Zhangfcfa3b82015-12-24 21:07:28 -08001076 iconFit.GetFittingBounds() ? rcWindow : rcClient, &font_map,
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001077 pDownIcon, iconFit, csDownCaption, crText, fFontSize, nLayout);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001078
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001079 WriteAppearance("D", GetRotatedRect(), GetMatrix(), csAP);
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001080 if (pDownIcon)
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001081 AddImageToAppearance("D", pDownIcon);
1082 } else {
1083 RemoveAppearance("D");
1084 RemoveAppearance("R");
1085 }
1086}
1087
1088void CPDFSDK_Widget::ResetAppearance_CheckBox() {
1089 CPDF_FormControl* pControl = GetFormControl();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001090 CPWL_Color crBackground, crBorder, crText;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001091 int iColorType;
1092 FX_FLOAT fc[4];
1093
1094 pControl->GetOriginalBackgroundColor(iColorType, fc);
1095 if (iColorType > 0)
1096 crBackground = CPWL_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
1097
1098 pControl->GetOriginalBorderColor(iColorType, fc);
1099 if (iColorType > 0)
1100 crBorder = CPWL_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
1101
1102 FX_FLOAT fBorderWidth = (FX_FLOAT)GetBorderWidth();
1103 int32_t nBorderStyle = 0;
1104 CPWL_Dash dsBorder(3, 0, 0);
1105 CPWL_Color crLeftTop, crRightBottom;
1106
1107 switch (GetBorderStyle()) {
1108 case BBS_DASH:
1109 nBorderStyle = PBS_DASH;
1110 dsBorder = CPWL_Dash(3, 3, 0);
1111 break;
1112 case BBS_BEVELED:
1113 nBorderStyle = PBS_BEVELED;
1114 fBorderWidth *= 2;
1115 crLeftTop = CPWL_Color(COLORTYPE_GRAY, 1);
1116 crRightBottom = CPWL_Utils::DevideColor(crBackground, 2);
1117 break;
1118 case BBS_INSET:
1119 nBorderStyle = PBS_INSET;
1120 fBorderWidth *= 2;
1121 crLeftTop = CPWL_Color(COLORTYPE_GRAY, 0.5);
1122 crRightBottom = CPWL_Color(COLORTYPE_GRAY, 0.75);
1123 break;
1124 case BBS_UNDERLINE:
1125 nBorderStyle = PBS_UNDERLINED;
1126 break;
1127 default:
1128 nBorderStyle = PBS_SOLID;
1129 break;
1130 }
1131
Tom Sepez281a9ea2016-02-26 14:24:28 -08001132 CFX_FloatRect rcWindow = GetRotatedRect();
1133 CFX_FloatRect rcClient = CPWL_Utils::DeflateRect(rcWindow, fBorderWidth);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001134
1135 CPDF_DefaultAppearance da = pControl->GetDefaultAppearance();
1136 if (da.HasColor()) {
1137 da.GetColor(iColorType, fc);
1138 crText = CPWL_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
1139 }
1140
1141 int32_t nStyle = 0;
1142
1143 CFX_WideString csWCaption = pControl->GetNormalCaption();
1144 if (csWCaption.GetLength() > 0) {
1145 switch (csWCaption[0]) {
1146 case L'l':
1147 nStyle = PCS_CIRCLE;
1148 break;
1149 case L'8':
1150 nStyle = PCS_CROSS;
1151 break;
1152 case L'u':
1153 nStyle = PCS_DIAMOND;
1154 break;
1155 case L'n':
1156 nStyle = PCS_SQUARE;
1157 break;
1158 case L'H':
1159 nStyle = PCS_STAR;
1160 break;
1161 default: // L'4'
1162 nStyle = PCS_CHECK;
1163 break;
1164 }
1165 } else {
1166 nStyle = PCS_CHECK;
1167 }
1168
1169 CFX_ByteString csAP_N_ON =
1170 CPWL_Utils::GetRectFillAppStream(rcWindow, crBackground) +
1171 CPWL_Utils::GetBorderAppStream(rcWindow, fBorderWidth, crBorder,
1172 crLeftTop, crRightBottom, nBorderStyle,
1173 dsBorder);
1174
1175 CFX_ByteString csAP_N_OFF = csAP_N_ON;
1176
1177 switch (nBorderStyle) {
1178 case PBS_BEVELED: {
1179 CPWL_Color crTemp = crLeftTop;
1180 crLeftTop = crRightBottom;
1181 crRightBottom = crTemp;
1182 } break;
1183 case PBS_INSET:
1184 crLeftTop = CPWL_Color(COLORTYPE_GRAY, 0);
1185 crRightBottom = CPWL_Color(COLORTYPE_GRAY, 1);
1186 break;
1187 }
1188
1189 CFX_ByteString csAP_D_ON =
1190 CPWL_Utils::GetRectFillAppStream(
1191 rcWindow, CPWL_Utils::SubstractColor(crBackground, 0.25f)) +
1192 CPWL_Utils::GetBorderAppStream(rcWindow, fBorderWidth, crBorder,
1193 crLeftTop, crRightBottom, nBorderStyle,
1194 dsBorder);
1195
1196 CFX_ByteString csAP_D_OFF = csAP_D_ON;
1197
1198 csAP_N_ON += CPWL_Utils::GetCheckBoxAppStream(rcClient, nStyle, crText);
1199 csAP_D_ON += CPWL_Utils::GetCheckBoxAppStream(rcClient, nStyle, crText);
1200
1201 WriteAppearance("N", GetRotatedRect(), GetMatrix(), csAP_N_ON,
1202 pControl->GetCheckedAPState());
1203 WriteAppearance("N", GetRotatedRect(), GetMatrix(), csAP_N_OFF, "Off");
1204
1205 WriteAppearance("D", GetRotatedRect(), GetMatrix(), csAP_D_ON,
1206 pControl->GetCheckedAPState());
1207 WriteAppearance("D", GetRotatedRect(), GetMatrix(), csAP_D_OFF, "Off");
1208
1209 CFX_ByteString csAS = GetAppState();
1210 if (csAS.IsEmpty())
1211 SetAppState("Off");
1212}
1213
1214void CPDFSDK_Widget::ResetAppearance_RadioButton() {
1215 CPDF_FormControl* pControl = GetFormControl();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001216 CPWL_Color crBackground, crBorder, crText;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001217 int iColorType;
1218 FX_FLOAT fc[4];
1219
1220 pControl->GetOriginalBackgroundColor(iColorType, fc);
1221 if (iColorType > 0)
1222 crBackground = CPWL_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
1223
1224 pControl->GetOriginalBorderColor(iColorType, fc);
1225 if (iColorType > 0)
1226 crBorder = CPWL_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
1227
1228 FX_FLOAT fBorderWidth = (FX_FLOAT)GetBorderWidth();
1229 int32_t nBorderStyle = 0;
1230 CPWL_Dash dsBorder(3, 0, 0);
1231 CPWL_Color crLeftTop, crRightBottom;
1232
1233 switch (GetBorderStyle()) {
1234 case BBS_DASH:
1235 nBorderStyle = PBS_DASH;
1236 dsBorder = CPWL_Dash(3, 3, 0);
1237 break;
1238 case BBS_BEVELED:
1239 nBorderStyle = PBS_BEVELED;
1240 fBorderWidth *= 2;
1241 crLeftTop = CPWL_Color(COLORTYPE_GRAY, 1);
1242 crRightBottom = CPWL_Utils::DevideColor(crBackground, 2);
1243 break;
1244 case BBS_INSET:
1245 nBorderStyle = PBS_INSET;
1246 fBorderWidth *= 2;
1247 crLeftTop = CPWL_Color(COLORTYPE_GRAY, 0.5);
1248 crRightBottom = CPWL_Color(COLORTYPE_GRAY, 0.75);
1249 break;
1250 case BBS_UNDERLINE:
1251 nBorderStyle = PBS_UNDERLINED;
1252 break;
1253 default:
1254 nBorderStyle = PBS_SOLID;
1255 break;
1256 }
1257
Tom Sepez281a9ea2016-02-26 14:24:28 -08001258 CFX_FloatRect rcWindow = GetRotatedRect();
1259 CFX_FloatRect rcClient = CPWL_Utils::DeflateRect(rcWindow, fBorderWidth);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001260
1261 CPDF_DefaultAppearance da = pControl->GetDefaultAppearance();
1262 if (da.HasColor()) {
1263 da.GetColor(iColorType, fc);
1264 crText = CPWL_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
1265 }
1266
1267 int32_t nStyle = 0;
1268
1269 CFX_WideString csWCaption = pControl->GetNormalCaption();
1270 if (csWCaption.GetLength() > 0) {
1271 switch (csWCaption[0]) {
1272 default: // L'l':
1273 nStyle = PCS_CIRCLE;
1274 break;
1275 case L'8':
1276 nStyle = PCS_CROSS;
1277 break;
1278 case L'u':
1279 nStyle = PCS_DIAMOND;
1280 break;
1281 case L'n':
1282 nStyle = PCS_SQUARE;
1283 break;
1284 case L'H':
1285 nStyle = PCS_STAR;
1286 break;
1287 case L'4':
1288 nStyle = PCS_CHECK;
1289 break;
1290 }
1291 } else {
1292 nStyle = PCS_CIRCLE;
1293 }
1294
1295 CFX_ByteString csAP_N_ON;
1296
Tom Sepez281a9ea2016-02-26 14:24:28 -08001297 CFX_FloatRect rcCenter =
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001298 CPWL_Utils::DeflateRect(CPWL_Utils::GetCenterSquare(rcWindow), 1.0f);
1299
1300 if (nStyle == PCS_CIRCLE) {
1301 if (nBorderStyle == PBS_BEVELED) {
1302 crLeftTop = CPWL_Color(COLORTYPE_GRAY, 1);
1303 crRightBottom = CPWL_Utils::SubstractColor(crBackground, 0.25f);
1304 } else if (nBorderStyle == PBS_INSET) {
1305 crLeftTop = CPWL_Color(COLORTYPE_GRAY, 0.5f);
1306 crRightBottom = CPWL_Color(COLORTYPE_GRAY, 0.75f);
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001307 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001308
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001309 csAP_N_ON = CPWL_Utils::GetCircleFillAppStream(rcCenter, crBackground) +
1310 CPWL_Utils::GetCircleBorderAppStream(
1311 rcCenter, fBorderWidth, crBorder, crLeftTop, crRightBottom,
1312 nBorderStyle, dsBorder);
1313 } else {
1314 csAP_N_ON = CPWL_Utils::GetRectFillAppStream(rcWindow, crBackground) +
1315 CPWL_Utils::GetBorderAppStream(rcWindow, fBorderWidth, crBorder,
1316 crLeftTop, crRightBottom,
1317 nBorderStyle, dsBorder);
1318 }
1319
1320 CFX_ByteString csAP_N_OFF = csAP_N_ON;
1321
1322 switch (nBorderStyle) {
1323 case PBS_BEVELED: {
1324 CPWL_Color crTemp = crLeftTop;
1325 crLeftTop = crRightBottom;
1326 crRightBottom = crTemp;
1327 } break;
1328 case PBS_INSET:
1329 crLeftTop = CPWL_Color(COLORTYPE_GRAY, 0);
1330 crRightBottom = CPWL_Color(COLORTYPE_GRAY, 1);
1331 break;
1332 }
1333
1334 CFX_ByteString csAP_D_ON;
1335
1336 if (nStyle == PCS_CIRCLE) {
1337 CPWL_Color crBK = CPWL_Utils::SubstractColor(crBackground, 0.25f);
1338 if (nBorderStyle == PBS_BEVELED) {
1339 crLeftTop = CPWL_Utils::SubstractColor(crBackground, 0.25f);
1340 crRightBottom = CPWL_Color(COLORTYPE_GRAY, 1);
1341 crBK = crBackground;
1342 } else if (nBorderStyle == PBS_INSET) {
1343 crLeftTop = CPWL_Color(COLORTYPE_GRAY, 0);
1344 crRightBottom = CPWL_Color(COLORTYPE_GRAY, 1);
1345 }
1346
1347 csAP_D_ON = CPWL_Utils::GetCircleFillAppStream(rcCenter, crBK) +
1348 CPWL_Utils::GetCircleBorderAppStream(
1349 rcCenter, fBorderWidth, crBorder, crLeftTop, crRightBottom,
1350 nBorderStyle, dsBorder);
1351 } else {
1352 csAP_D_ON = CPWL_Utils::GetRectFillAppStream(
1353 rcWindow, CPWL_Utils::SubstractColor(crBackground, 0.25f)) +
1354 CPWL_Utils::GetBorderAppStream(rcWindow, fBorderWidth, crBorder,
1355 crLeftTop, crRightBottom,
1356 nBorderStyle, dsBorder);
1357 }
1358
1359 CFX_ByteString csAP_D_OFF = csAP_D_ON;
1360
1361 csAP_N_ON += CPWL_Utils::GetRadioButtonAppStream(rcClient, nStyle, crText);
1362 csAP_D_ON += CPWL_Utils::GetRadioButtonAppStream(rcClient, nStyle, crText);
1363
1364 WriteAppearance("N", GetRotatedRect(), GetMatrix(), csAP_N_ON,
1365 pControl->GetCheckedAPState());
1366 WriteAppearance("N", GetRotatedRect(), GetMatrix(), csAP_N_OFF, "Off");
1367
1368 WriteAppearance("D", GetRotatedRect(), GetMatrix(), csAP_D_ON,
1369 pControl->GetCheckedAPState());
1370 WriteAppearance("D", GetRotatedRect(), GetMatrix(), csAP_D_OFF, "Off");
1371
1372 CFX_ByteString csAS = GetAppState();
1373 if (csAS.IsEmpty())
1374 SetAppState("Off");
1375}
1376
1377void CPDFSDK_Widget::ResetAppearance_ComboBox(const FX_WCHAR* sValue) {
1378 CPDF_FormControl* pControl = GetFormControl();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001379 CPDF_FormField* pField = pControl->GetField();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001380 CFX_ByteTextBuf sBody, sLines;
1381
Tom Sepez281a9ea2016-02-26 14:24:28 -08001382 CFX_FloatRect rcClient = GetClientRect();
1383 CFX_FloatRect rcButton = rcClient;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001384 rcButton.left = rcButton.right - 13;
1385 rcButton.Normalize();
1386
1387 if (IFX_Edit* pEdit = IFX_Edit::NewEdit()) {
1388 pEdit->EnableRefresh(FALSE);
1389
1390 CPDFSDK_Document* pDoc = m_pInterForm->GetDocument();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001391 CPDFDoc_Environment* pEnv = pDoc->GetEnv();
Lei Zhangfcfa3b82015-12-24 21:07:28 -08001392 CBA_FontMap font_map(this, pEnv->GetSysHandler());
1393 pEdit->SetFontMap(&font_map);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001394
Tom Sepez281a9ea2016-02-26 14:24:28 -08001395 CFX_FloatRect rcEdit = rcClient;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001396 rcEdit.right = rcButton.left;
1397 rcEdit.Normalize();
1398
1399 pEdit->SetPlateRect(rcEdit);
1400 pEdit->SetAlignmentV(1);
1401
1402 FX_FLOAT fFontSize = GetFontSize();
1403 if (IsFloatZero(fFontSize))
1404 pEdit->SetAutoFontSize(TRUE);
1405 else
1406 pEdit->SetFontSize(fFontSize);
1407
1408 pEdit->Initialize();
1409
Lei Zhangd88a3642015-11-10 09:38:57 -08001410 if (sValue) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001411 pEdit->SetText(sValue);
Lei Zhangd88a3642015-11-10 09:38:57 -08001412 } else {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001413 int32_t nCurSel = pField->GetSelectedIndex(0);
1414
1415 if (nCurSel < 0)
1416 pEdit->SetText(pField->GetValue().c_str());
1417 else
1418 pEdit->SetText(pField->GetOptionLabel(nCurSel).c_str());
1419 }
1420
Tom Sepez281a9ea2016-02-26 14:24:28 -08001421 CFX_FloatRect rcContent = pEdit->GetContentRect();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001422
1423 CFX_ByteString sEdit =
Tom Sepez281a9ea2016-02-26 14:24:28 -08001424 CPWL_Utils::GetEditAppStream(pEdit, CFX_FloatPoint(0.0f, 0.0f));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001425 if (sEdit.GetLength() > 0) {
1426 sBody << "/Tx BMC\n"
1427 << "q\n";
1428 if (rcContent.Width() > rcEdit.Width() ||
1429 rcContent.Height() > rcEdit.Height()) {
1430 sBody << rcEdit.left << " " << rcEdit.bottom << " " << rcEdit.Width()
1431 << " " << rcEdit.Height() << " re\nW\nn\n";
1432 }
1433
1434 CPWL_Color crText = GetTextPWLColor();
1435 sBody << "BT\n" << CPWL_Utils::GetColorAppStream(crText) << sEdit
1436 << "ET\n"
1437 << "Q\nEMC\n";
1438 }
1439
1440 IFX_Edit::DelEdit(pEdit);
1441 }
1442
1443 sBody << CPWL_Utils::GetDropButtonAppStream(rcButton);
1444
1445 CFX_ByteString sAP = GetBackgroundAppStream() + GetBorderAppStream() +
1446 sLines.GetByteString() + sBody.GetByteString();
1447
1448 WriteAppearance("N", GetRotatedRect(), GetMatrix(), sAP);
1449}
1450
1451void CPDFSDK_Widget::ResetAppearance_ListBox() {
1452 CPDF_FormControl* pControl = GetFormControl();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001453 CPDF_FormField* pField = pControl->GetField();
Tom Sepez281a9ea2016-02-26 14:24:28 -08001454 CFX_FloatRect rcClient = GetClientRect();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001455 CFX_ByteTextBuf sBody, sLines;
1456
1457 if (IFX_Edit* pEdit = IFX_Edit::NewEdit()) {
1458 pEdit->EnableRefresh(FALSE);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001459
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001460 CPDFSDK_Document* pDoc = m_pInterForm->GetDocument();
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001461 CPDFDoc_Environment* pEnv = pDoc->GetEnv();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001462
Lei Zhangfcfa3b82015-12-24 21:07:28 -08001463 CBA_FontMap font_map(this, pEnv->GetSysHandler());
1464 pEdit->SetFontMap(&font_map);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001465
Tom Sepez281a9ea2016-02-26 14:24:28 -08001466 pEdit->SetPlateRect(
1467 CFX_FloatRect(rcClient.left, 0.0f, rcClient.right, 0.0f));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001468
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001469 FX_FLOAT fFontSize = GetFontSize();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001470
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001471 if (IsFloatZero(fFontSize))
1472 pEdit->SetFontSize(12.0f);
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001473 else
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001474 pEdit->SetFontSize(fFontSize);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001475
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001476 pEdit->Initialize();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001477
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001478 CFX_ByteTextBuf sList;
1479 FX_FLOAT fy = rcClient.top;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001480
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001481 int32_t nTop = pField->GetTopVisibleIndex();
1482 int32_t nCount = pField->CountOptions();
1483 int32_t nSelCount = pField->CountSelectedItems();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001484
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001485 for (int32_t i = nTop; i < nCount; i++) {
1486 FX_BOOL bSelected = FALSE;
1487 for (int32_t j = 0; j < nSelCount; j++) {
1488 if (pField->GetSelectedIndex(j) == i) {
1489 bSelected = TRUE;
1490 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001491 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001492 }
1493
1494 pEdit->SetText(pField->GetOptionLabel(i).c_str());
1495
Tom Sepez281a9ea2016-02-26 14:24:28 -08001496 CFX_FloatRect rcContent = pEdit->GetContentRect();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001497 FX_FLOAT fItemHeight = rcContent.Height();
1498
1499 if (bSelected) {
Tom Sepez281a9ea2016-02-26 14:24:28 -08001500 CFX_FloatRect rcItem =
1501 CFX_FloatRect(rcClient.left, fy - fItemHeight, rcClient.right, fy);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001502 sList << "q\n" << CPWL_Utils::GetColorAppStream(
1503 CPWL_Color(COLORTYPE_RGB, 0, 51.0f / 255.0f,
1504 113.0f / 255.0f),
1505 TRUE)
1506 << rcItem.left << " " << rcItem.bottom << " " << rcItem.Width()
1507 << " " << rcItem.Height() << " re f\n"
1508 << "Q\n";
1509
1510 sList << "BT\n" << CPWL_Utils::GetColorAppStream(
1511 CPWL_Color(COLORTYPE_GRAY, 1), TRUE)
Tom Sepez281a9ea2016-02-26 14:24:28 -08001512 << CPWL_Utils::GetEditAppStream(pEdit, CFX_FloatPoint(0.0f, fy))
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001513 << "ET\n";
1514 } else {
1515 CPWL_Color crText = GetTextPWLColor();
1516 sList << "BT\n" << CPWL_Utils::GetColorAppStream(crText, TRUE)
Tom Sepez281a9ea2016-02-26 14:24:28 -08001517 << CPWL_Utils::GetEditAppStream(pEdit, CFX_FloatPoint(0.0f, fy))
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001518 << "ET\n";
1519 }
1520
1521 fy -= fItemHeight;
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001522 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001523
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001524 if (sList.GetSize() > 0) {
1525 sBody << "/Tx BMC\n"
1526 << "q\n" << rcClient.left << " " << rcClient.bottom << " "
1527 << rcClient.Width() << " " << rcClient.Height() << " re\nW\nn\n";
1528 sBody << sList << "Q\nEMC\n";
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001529 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001530
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001531 IFX_Edit::DelEdit(pEdit);
1532 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001533
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001534 CFX_ByteString sAP = GetBackgroundAppStream() + GetBorderAppStream() +
1535 sLines.GetByteString() + sBody.GetByteString();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001536
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001537 WriteAppearance("N", GetRotatedRect(), GetMatrix(), sAP);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001538}
1539
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001540void CPDFSDK_Widget::ResetAppearance_TextField(const FX_WCHAR* sValue) {
1541 CPDF_FormControl* pControl = GetFormControl();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001542 CPDF_FormField* pField = pControl->GetField();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001543 CFX_ByteTextBuf sBody, sLines;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001544
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001545 if (IFX_Edit* pEdit = IFX_Edit::NewEdit()) {
1546 pEdit->EnableRefresh(FALSE);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001547
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001548 CPDFSDK_Document* pDoc = m_pInterForm->GetDocument();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001549 CPDFDoc_Environment* pEnv = pDoc->GetEnv();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001550
Lei Zhangfcfa3b82015-12-24 21:07:28 -08001551 CBA_FontMap font_map(this, pEnv->GetSysHandler());
1552 pEdit->SetFontMap(&font_map);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001553
Tom Sepez281a9ea2016-02-26 14:24:28 -08001554 CFX_FloatRect rcClient = GetClientRect();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001555 pEdit->SetPlateRect(rcClient);
1556 pEdit->SetAlignmentH(pControl->GetControlAlignment());
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001557
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001558 FX_DWORD dwFieldFlags = pField->GetFieldFlags();
1559 FX_BOOL bMultiLine = (dwFieldFlags >> 12) & 1;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001560
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001561 if (bMultiLine) {
1562 pEdit->SetMultiLine(TRUE);
1563 pEdit->SetAutoReturn(TRUE);
1564 } else {
1565 pEdit->SetAlignmentV(1);
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001566 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001567
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001568 FX_WORD subWord = 0;
1569 if ((dwFieldFlags >> 13) & 1) {
1570 subWord = '*';
1571 pEdit->SetPasswordChar(subWord);
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001572 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001573
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001574 int nMaxLen = pField->GetMaxLen();
1575 FX_BOOL bCharArray = (dwFieldFlags >> 24) & 1;
1576 FX_FLOAT fFontSize = GetFontSize();
Bo Xufdc00a72014-10-28 23:03:33 -07001577
Tom Sepez51da0932015-11-25 16:05:49 -08001578#ifdef PDF_ENABLE_XFA
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001579 CFX_WideString sValueTmp;
Lei Zhang99766722016-02-23 11:21:48 -08001580 if (!sValue && GetMixXFAWidget()) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001581 sValueTmp = GetValue(TRUE);
1582 sValue = sValueTmp;
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001583 }
Tom Sepez40e9ff32015-11-30 12:39:54 -08001584#endif // PDF_ENABLE_XFA
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001585
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001586 if (nMaxLen > 0) {
1587 if (bCharArray) {
1588 pEdit->SetCharArray(nMaxLen);
Tom Sepez7b5bc262015-03-05 16:44:22 -08001589
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001590 if (IsFloatZero(fFontSize)) {
Lei Zhangfcfa3b82015-12-24 21:07:28 -08001591 fFontSize = CPWL_Edit::GetCharArrayAutoFontSize(
1592 font_map.GetPDFFont(0), rcClient, nMaxLen);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001593 }
1594 } else {
1595 if (sValue)
1596 nMaxLen = wcslen((const wchar_t*)sValue);
1597 pEdit->SetLimitChar(nMaxLen);
Lei Zhang606346f2015-06-19 18:11:07 -07001598 }
1599 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001600
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001601 if (IsFloatZero(fFontSize))
1602 pEdit->SetAutoFontSize(TRUE);
1603 else
1604 pEdit->SetFontSize(fFontSize);
1605
1606 pEdit->Initialize();
1607
1608 if (sValue)
1609 pEdit->SetText(sValue);
1610 else
1611 pEdit->SetText(pField->GetValue().c_str());
1612
Tom Sepez281a9ea2016-02-26 14:24:28 -08001613 CFX_FloatRect rcContent = pEdit->GetContentRect();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001614
1615 CFX_ByteString sEdit = CPWL_Utils::GetEditAppStream(
Tom Sepez281a9ea2016-02-26 14:24:28 -08001616 pEdit, CFX_FloatPoint(0.0f, 0.0f), NULL, !bCharArray, subWord);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001617
1618 if (sEdit.GetLength() > 0) {
1619 sBody << "/Tx BMC\n"
1620 << "q\n";
1621 if (rcContent.Width() > rcClient.Width() ||
1622 rcContent.Height() > rcClient.Height()) {
1623 sBody << rcClient.left << " " << rcClient.bottom << " "
1624 << rcClient.Width() << " " << rcClient.Height() << " re\nW\nn\n";
1625 }
1626 CPWL_Color crText = GetTextPWLColor();
1627 sBody << "BT\n" << CPWL_Utils::GetColorAppStream(crText) << sEdit
1628 << "ET\n"
1629 << "Q\nEMC\n";
Lei Zhang606346f2015-06-19 18:11:07 -07001630 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001631
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001632 if (bCharArray) {
1633 switch (GetBorderStyle()) {
1634 case BBS_SOLID: {
1635 CFX_ByteString sColor =
1636 CPWL_Utils::GetColorAppStream(GetBorderPWLColor(), FALSE);
1637 if (sColor.GetLength() > 0) {
1638 sLines << "q\n" << GetBorderWidth() << " w\n"
1639 << CPWL_Utils::GetColorAppStream(GetBorderPWLColor(), FALSE)
1640 << " 2 J 0 j\n";
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001641
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001642 for (int32_t i = 1; i < nMaxLen; i++) {
1643 sLines << rcClient.left +
1644 ((rcClient.right - rcClient.left) / nMaxLen) * i
1645 << " " << rcClient.bottom << " m\n"
1646 << rcClient.left +
1647 ((rcClient.right - rcClient.left) / nMaxLen) * i
1648 << " " << rcClient.top << " l S\n";
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001649 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001650
1651 sLines << "Q\n";
1652 }
1653 } break;
1654 case BBS_DASH: {
1655 CFX_ByteString sColor =
1656 CPWL_Utils::GetColorAppStream(GetBorderPWLColor(), FALSE);
1657 if (sColor.GetLength() > 0) {
1658 CPWL_Dash dsBorder = CPWL_Dash(3, 3, 0);
1659
1660 sLines << "q\n" << GetBorderWidth() << " w\n"
1661 << CPWL_Utils::GetColorAppStream(GetBorderPWLColor(), FALSE)
1662 << "[" << dsBorder.nDash << " " << dsBorder.nGap << "] "
1663 << dsBorder.nPhase << " d\n";
1664
1665 for (int32_t i = 1; i < nMaxLen; i++) {
1666 sLines << rcClient.left +
1667 ((rcClient.right - rcClient.left) / nMaxLen) * i
1668 << " " << rcClient.bottom << " m\n"
1669 << rcClient.left +
1670 ((rcClient.right - rcClient.left) / nMaxLen) * i
1671 << " " << rcClient.top << " l S\n";
1672 }
1673
1674 sLines << "Q\n";
1675 }
1676 } break;
1677 }
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001678 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001679
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001680 IFX_Edit::DelEdit(pEdit);
1681 }
1682
1683 CFX_ByteString sAP = GetBackgroundAppStream() + GetBorderAppStream() +
1684 sLines.GetByteString() + sBody.GetByteString();
1685 WriteAppearance("N", GetRotatedRect(), GetMatrix(), sAP);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001686}
1687
Tom Sepez281a9ea2016-02-26 14:24:28 -08001688CFX_FloatRect CPDFSDK_Widget::GetClientRect() const {
1689 CFX_FloatRect rcWindow = GetRotatedRect();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001690 FX_FLOAT fBorderWidth = (FX_FLOAT)GetBorderWidth();
1691 switch (GetBorderStyle()) {
1692 case BBS_BEVELED:
1693 case BBS_INSET:
1694 fBorderWidth *= 2.0f;
1695 break;
1696 }
1697
1698 return CPWL_Utils::DeflateRect(rcWindow, fBorderWidth);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001699}
1700
Tom Sepez281a9ea2016-02-26 14:24:28 -08001701CFX_FloatRect CPDFSDK_Widget::GetRotatedRect() const {
1702 CFX_FloatRect rectAnnot = GetRect();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001703 FX_FLOAT fWidth = rectAnnot.right - rectAnnot.left;
1704 FX_FLOAT fHeight = rectAnnot.top - rectAnnot.bottom;
1705
1706 CPDF_FormControl* pControl = GetFormControl();
Tom Sepez281a9ea2016-02-26 14:24:28 -08001707 CFX_FloatRect rcPDFWindow;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001708 switch (abs(pControl->GetRotation() % 360)) {
1709 case 0:
1710 case 180:
1711 default:
Tom Sepez281a9ea2016-02-26 14:24:28 -08001712 rcPDFWindow = CFX_FloatRect(0, 0, fWidth, fHeight);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001713 break;
1714 case 90:
1715 case 270:
Tom Sepez281a9ea2016-02-26 14:24:28 -08001716 rcPDFWindow = CFX_FloatRect(0, 0, fHeight, fWidth);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001717 break;
1718 }
1719
1720 return rcPDFWindow;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001721}
1722
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001723CFX_ByteString CPDFSDK_Widget::GetBackgroundAppStream() const {
1724 CPWL_Color crBackground = GetFillPWLColor();
1725 if (crBackground.nColorType != COLORTYPE_TRANSPARENT) {
1726 return CPWL_Utils::GetRectFillAppStream(GetRotatedRect(), crBackground);
1727 }
1728 return "";
Bo Xufdc00a72014-10-28 23:03:33 -07001729}
1730
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001731CFX_ByteString CPDFSDK_Widget::GetBorderAppStream() const {
Tom Sepez281a9ea2016-02-26 14:24:28 -08001732 CFX_FloatRect rcWindow = GetRotatedRect();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001733 CPWL_Color crBorder = GetBorderPWLColor();
1734 CPWL_Color crBackground = GetFillPWLColor();
1735 CPWL_Color crLeftTop, crRightBottom;
1736
1737 FX_FLOAT fBorderWidth = (FX_FLOAT)GetBorderWidth();
1738 int32_t nBorderStyle = 0;
1739 CPWL_Dash dsBorder(3, 0, 0);
1740
1741 switch (GetBorderStyle()) {
1742 case BBS_DASH:
1743 nBorderStyle = PBS_DASH;
1744 dsBorder = CPWL_Dash(3, 3, 0);
1745 break;
1746 case BBS_BEVELED:
1747 nBorderStyle = PBS_BEVELED;
1748 fBorderWidth *= 2;
1749 crLeftTop = CPWL_Color(COLORTYPE_GRAY, 1);
1750 crRightBottom = CPWL_Utils::DevideColor(crBackground, 2);
1751 break;
1752 case BBS_INSET:
1753 nBorderStyle = PBS_INSET;
1754 fBorderWidth *= 2;
1755 crLeftTop = CPWL_Color(COLORTYPE_GRAY, 0.5);
1756 crRightBottom = CPWL_Color(COLORTYPE_GRAY, 0.75);
1757 break;
1758 case BBS_UNDERLINE:
1759 nBorderStyle = PBS_UNDERLINED;
1760 break;
1761 default:
1762 nBorderStyle = PBS_SOLID;
1763 break;
1764 }
1765
1766 return CPWL_Utils::GetBorderAppStream(rcWindow, fBorderWidth, crBorder,
1767 crLeftTop, crRightBottom, nBorderStyle,
1768 dsBorder);
Bo Xufdc00a72014-10-28 23:03:33 -07001769}
1770
Tom Sepez60d909e2015-12-10 15:34:55 -08001771CFX_Matrix CPDFSDK_Widget::GetMatrix() const {
1772 CFX_Matrix mt;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001773 CPDF_FormControl* pControl = GetFormControl();
Tom Sepez281a9ea2016-02-26 14:24:28 -08001774 CFX_FloatRect rcAnnot = GetRect();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001775 FX_FLOAT fWidth = rcAnnot.right - rcAnnot.left;
1776 FX_FLOAT fHeight = rcAnnot.top - rcAnnot.bottom;
1777
1778 switch (abs(pControl->GetRotation() % 360)) {
1779 case 0:
1780 default:
Tom Sepez60d909e2015-12-10 15:34:55 -08001781 mt = CFX_Matrix(1, 0, 0, 1, 0, 0);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001782 break;
1783 case 90:
Tom Sepez60d909e2015-12-10 15:34:55 -08001784 mt = CFX_Matrix(0, 1, -1, 0, fWidth, 0);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001785 break;
1786 case 180:
Tom Sepez60d909e2015-12-10 15:34:55 -08001787 mt = CFX_Matrix(-1, 0, 0, -1, fWidth, fHeight);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001788 break;
1789 case 270:
Tom Sepez60d909e2015-12-10 15:34:55 -08001790 mt = CFX_Matrix(0, -1, 1, 0, 0, fHeight);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001791 break;
1792 }
1793
1794 return mt;
Bo Xufdc00a72014-10-28 23:03:33 -07001795}
1796
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001797CPWL_Color CPDFSDK_Widget::GetTextPWLColor() const {
1798 CPWL_Color crText = CPWL_Color(COLORTYPE_GRAY, 0);
1799
1800 CPDF_FormControl* pFormCtrl = GetFormControl();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001801 CPDF_DefaultAppearance da = pFormCtrl->GetDefaultAppearance();
1802 if (da.HasColor()) {
1803 int32_t iColorType;
1804 FX_FLOAT fc[4];
1805 da.GetColor(iColorType, fc);
1806 crText = CPWL_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
1807 }
1808
1809 return crText;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001810}
1811
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001812CPWL_Color CPDFSDK_Widget::GetBorderPWLColor() const {
1813 CPWL_Color crBorder;
1814
1815 CPDF_FormControl* pFormCtrl = GetFormControl();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001816 int32_t iColorType;
1817 FX_FLOAT fc[4];
1818 pFormCtrl->GetOriginalBorderColor(iColorType, fc);
1819 if (iColorType > 0)
1820 crBorder = CPWL_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
1821
1822 return crBorder;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001823}
1824
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001825CPWL_Color CPDFSDK_Widget::GetFillPWLColor() const {
1826 CPWL_Color crFill;
1827
1828 CPDF_FormControl* pFormCtrl = GetFormControl();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001829 int32_t iColorType;
1830 FX_FLOAT fc[4];
1831 pFormCtrl->GetOriginalBackgroundColor(iColorType, fc);
1832 if (iColorType > 0)
1833 crFill = CPWL_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
1834
1835 return crFill;
Bo Xufdc00a72014-10-28 23:03:33 -07001836}
1837
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001838void CPDFSDK_Widget::AddImageToAppearance(const CFX_ByteString& sAPType,
1839 CPDF_Stream* pImage) {
Tom Sepez33420902015-10-13 15:00:10 -07001840 CPDF_Document* pDoc = m_pPageView->GetPDFDocument();
Lei Zhang96660d62015-12-14 18:27:25 -08001841 ASSERT(pDoc);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001842
Wei Li9b761132016-01-29 15:44:20 -08001843 CPDF_Dictionary* pAPDict = m_pAnnot->GetAnnotDict()->GetDictBy("AP");
1844 CPDF_Stream* pStream = pAPDict->GetStreamBy(sAPType);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001845 CPDF_Dictionary* pStreamDict = pStream->GetDict();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001846 CFX_ByteString sImageAlias = "IMG";
1847
1848 if (CPDF_Dictionary* pImageDict = pImage->GetDict()) {
Wei Li9b761132016-01-29 15:44:20 -08001849 sImageAlias = pImageDict->GetStringBy("Name");
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001850 if (sImageAlias.IsEmpty())
1851 sImageAlias = "IMG";
1852 }
1853
Wei Li9b761132016-01-29 15:44:20 -08001854 CPDF_Dictionary* pStreamResList = pStreamDict->GetDictBy("Resources");
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001855 if (!pStreamResList) {
Tom Sepezae51c812015-08-05 12:34:06 -07001856 pStreamResList = new CPDF_Dictionary();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001857 pStreamDict->SetAt("Resources", pStreamResList);
1858 }
1859
1860 if (pStreamResList) {
Tom Sepezae51c812015-08-05 12:34:06 -07001861 CPDF_Dictionary* pXObject = new CPDF_Dictionary;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001862 pXObject->SetAtReference(sImageAlias, pDoc, pImage);
1863 pStreamResList->SetAt("XObject", pXObject);
1864 }
Bo Xufdc00a72014-10-28 23:03:33 -07001865}
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001866
1867void CPDFSDK_Widget::RemoveAppearance(const CFX_ByteString& sAPType) {
Wei Li9b761132016-01-29 15:44:20 -08001868 if (CPDF_Dictionary* pAPDict = m_pAnnot->GetAnnotDict()->GetDictBy("AP")) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001869 pAPDict->RemoveAt(sAPType);
1870 }
1871}
1872
1873FX_BOOL CPDFSDK_Widget::OnAAction(CPDF_AAction::AActionType type,
1874 PDFSDK_FieldAction& data,
1875 CPDFSDK_PageView* pPageView) {
1876 CPDFSDK_Document* pDocument = pPageView->GetSDKDocument();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001877 CPDFDoc_Environment* pEnv = pDocument->GetEnv();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001878
Tom Sepez40e9ff32015-11-30 12:39:54 -08001879#ifdef PDF_ENABLE_XFA
Tom Sepez540c4362015-11-24 13:33:57 -08001880 CPDFXFA_Document* pDoc = pDocument->GetXFADocument();
1881 if (IXFA_Widget* hWidget = GetMixXFAWidget()) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001882 XFA_EVENTTYPE eEventType = GetXFAEventType(type, data.bWillCommit);
1883
1884 if (eEventType != XFA_EVENT_Unknown) {
Tom Sepez540c4362015-11-24 13:33:57 -08001885 if (IXFA_WidgetHandler* pXFAWidgetHandler = GetXFAWidgetHandler()) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001886 CXFA_EventParam param;
1887 param.m_eType = eEventType;
1888 param.m_wsChange = data.sChange;
1889 param.m_iCommitKey = data.nCommitKey;
1890 param.m_bShift = data.bShift;
1891 param.m_iSelStart = data.nSelStart;
1892 param.m_iSelEnd = data.nSelEnd;
1893 param.m_wsFullText = data.sValue;
1894 param.m_bKeyDown = data.bKeyDown;
1895 param.m_bModifier = data.bModifier;
1896 param.m_wsNewText = data.sValue;
1897 if (data.nSelEnd > data.nSelStart)
1898 param.m_wsNewText.Delete(data.nSelStart,
1899 data.nSelEnd - data.nSelStart);
1900 for (int i = data.sChange.GetLength() - 1; i >= 0; i--)
1901 param.m_wsNewText.Insert(data.nSelStart, data.sChange[i]);
1902 param.m_wsPrevText = data.sValue;
1903
1904 CXFA_WidgetAcc* pAcc = pXFAWidgetHandler->GetDataAcc(hWidget);
1905 param.m_pTarget = pAcc;
1906 int32_t nRet = pXFAWidgetHandler->ProcessEvent(pAcc, &param);
1907
1908 if (IXFA_DocView* pDocView = pDoc->GetXFADocView()) {
1909 pDocView->UpdateDocView();
1910 }
1911
Wei Lie98ac2e2016-03-18 15:43:04 -07001912 if (nRet == XFA_EVENTERROR_Success)
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001913 return TRUE;
1914 }
1915 }
1916 }
Tom Sepez40e9ff32015-11-30 12:39:54 -08001917#endif // PDF_ENABLE_XFA
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001918
1919 CPDF_Action action = GetAAction(type);
Wei Li0fc6b252016-03-01 16:29:41 -08001920 if (action.GetDict() && action.GetType() != CPDF_Action::Unknown) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001921 CPDFSDK_ActionHandler* pActionHandler = pEnv->GetActionHander();
1922 return pActionHandler->DoAction_Field(action, type, pDocument,
1923 GetFormField(), data);
1924 }
1925 return FALSE;
1926}
1927
1928CPDF_Action CPDFSDK_Widget::GetAAction(CPDF_AAction::AActionType eAAT) {
1929 switch (eAAT) {
1930 case CPDF_AAction::CursorEnter:
1931 case CPDF_AAction::CursorExit:
1932 case CPDF_AAction::ButtonDown:
1933 case CPDF_AAction::ButtonUp:
1934 case CPDF_AAction::GetFocus:
1935 case CPDF_AAction::LoseFocus:
1936 case CPDF_AAction::PageOpen:
1937 case CPDF_AAction::PageClose:
1938 case CPDF_AAction::PageVisible:
1939 case CPDF_AAction::PageInvisible:
1940 return CPDFSDK_BAAnnot::GetAAction(eAAT);
1941
1942 case CPDF_AAction::KeyStroke:
1943 case CPDF_AAction::Format:
1944 case CPDF_AAction::Validate:
1945 case CPDF_AAction::Calculate: {
1946 CPDF_FormField* pField = GetFormField();
Wei Li0fc6b252016-03-01 16:29:41 -08001947 if (pField->GetAdditionalAction().GetDict())
1948 return pField->GetAdditionalAction().GetAction(eAAT);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001949 return CPDFSDK_BAAnnot::GetAAction(eAAT);
1950 }
1951 default:
1952 break;
1953 }
1954
1955 return CPDF_Action();
1956}
1957
1958CFX_WideString CPDFSDK_Widget::GetAlternateName() const {
1959 CPDF_FormField* pFormField = GetFormField();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001960 return pFormField->GetAlternateName();
1961}
1962
1963int32_t CPDFSDK_Widget::GetAppearanceAge() const {
1964 return m_nAppAge;
1965}
1966
1967int32_t CPDFSDK_Widget::GetValueAge() const {
1968 return m_nValueAge;
1969}
1970
1971FX_BOOL CPDFSDK_Widget::HitTest(FX_FLOAT pageX, FX_FLOAT pageY) {
1972 CPDF_Annot* pAnnot = GetPDFAnnot();
1973 CFX_FloatRect annotRect;
1974 pAnnot->GetRect(annotRect);
1975 if (annotRect.Contains(pageX, pageY)) {
1976 if (!IsVisible())
1977 return FALSE;
1978
1979 int nFieldFlags = GetFieldFlags();
1980 if ((nFieldFlags & FIELDFLAG_READONLY) == FIELDFLAG_READONLY)
1981 return FALSE;
1982
1983 return TRUE;
1984 }
1985 return FALSE;
1986}
1987
Tom Sepez51da0932015-11-25 16:05:49 -08001988#ifdef PDF_ENABLE_XFA
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001989CPDFSDK_XFAWidget::CPDFSDK_XFAWidget(IXFA_Widget* pAnnot,
1990 CPDFSDK_PageView* pPageView,
1991 CPDFSDK_InterForm* pInterForm)
Dan Sinclairf766ad22016-03-14 13:51:24 -04001992 : CPDFSDK_Annot(pPageView),
1993 m_pInterForm(pInterForm),
1994 m_hXFAWidget(pAnnot) {}
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001995
1996FX_BOOL CPDFSDK_XFAWidget::IsXFAField() {
1997 return TRUE;
1998}
1999
2000CFX_ByteString CPDFSDK_XFAWidget::GetType() const {
2001 return FSDK_XFAWIDGET_TYPENAME;
2002}
2003
Tom Sepez3343d142015-11-02 09:54:54 -08002004CFX_FloatRect CPDFSDK_XFAWidget::GetRect() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002005 CPDFSDK_PageView* pPageView = GetPageView();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002006 CPDFSDK_Document* pDocument = pPageView->GetSDKDocument();
Tom Sepez50d12ad2015-11-24 09:50:51 -08002007 CPDFXFA_Document* pDoc = pDocument->GetXFADocument();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002008 IXFA_DocView* pDocView = pDoc->GetXFADocView();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002009 IXFA_WidgetHandler* pWidgetHandler = pDocView->GetWidgetHandler();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002010
2011 CFX_RectF rcBBox;
2012 pWidgetHandler->GetRect(GetXFAWidget(), rcBBox);
2013
2014 return CFX_FloatRect(rcBBox.left, rcBBox.top, rcBBox.left + rcBBox.width,
2015 rcBBox.top + rcBBox.height);
2016}
Tom Sepez40e9ff32015-11-30 12:39:54 -08002017#endif // PDF_ENABLE_XFA
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002018
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002019CPDFSDK_InterForm::CPDFSDK_InterForm(CPDFSDK_Document* pDocument)
2020 : m_pDocument(pDocument),
2021 m_pInterForm(NULL),
Tom Sepez51da0932015-11-25 16:05:49 -08002022#ifdef PDF_ENABLE_XFA
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002023 m_bXfaCalculate(TRUE),
2024 m_bXfaValidationsEnabled(TRUE),
Tom Sepez40e9ff32015-11-30 12:39:54 -08002025#endif // PDF_ENABLE_XFA
2026 m_bCalculate(TRUE),
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002027 m_bBusy(FALSE) {
Tom Sepez50d12ad2015-11-24 09:50:51 -08002028 m_pInterForm = new CPDF_InterForm(m_pDocument->GetPDFDocument(), FALSE);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002029 m_pInterForm->SetFormNotify(this);
2030
Tom Sepezae7a9172015-11-23 09:22:46 -08002031 for (int i = 0; i < kNumFieldTypes; ++i)
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002032 m_bNeedHightlight[i] = FALSE;
2033 m_iHighlightAlpha = 0;
2034}
2035
2036CPDFSDK_InterForm::~CPDFSDK_InterForm() {
2037 delete m_pInterForm;
2038 m_pInterForm = nullptr;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002039 m_Map.clear();
Tom Sepez51da0932015-11-25 16:05:49 -08002040#ifdef PDF_ENABLE_XFA
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002041 m_XFAMap.RemoveAll();
Tom Sepez40e9ff32015-11-30 12:39:54 -08002042#endif // PDF_ENABLE_XFA
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002043}
2044
2045FX_BOOL CPDFSDK_InterForm::HighlightWidgets() {
2046 return FALSE;
2047}
2048
2049CPDFSDK_Widget* CPDFSDK_InterForm::GetSibling(CPDFSDK_Widget* pWidget,
2050 FX_BOOL bNext) const {
Lei Zhangaa8bf7e2015-12-24 19:13:32 -08002051 std::unique_ptr<CBA_AnnotIterator> pIterator(
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002052 new CBA_AnnotIterator(pWidget->GetPageView(), "Widget", ""));
2053
2054 if (bNext) {
2055 return (CPDFSDK_Widget*)pIterator->GetNextAnnot(pWidget);
2056 }
2057 return (CPDFSDK_Widget*)pIterator->GetPrevAnnot(pWidget);
2058}
2059
2060CPDFSDK_Widget* CPDFSDK_InterForm::GetWidget(CPDF_FormControl* pControl) const {
2061 if (!pControl || !m_pInterForm)
2062 return nullptr;
2063
2064 CPDFSDK_Widget* pWidget = nullptr;
2065 const auto it = m_Map.find(pControl);
2066 if (it != m_Map.end())
2067 pWidget = it->second;
2068
2069 if (pWidget)
2070 return pWidget;
2071
2072 CPDF_Dictionary* pControlDict = pControl->GetWidget();
Tom Sepez50d12ad2015-11-24 09:50:51 -08002073 CPDF_Document* pDocument = m_pDocument->GetPDFDocument();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002074 CPDFSDK_PageView* pPage = nullptr;
2075
Wei Li9b761132016-01-29 15:44:20 -08002076 if (CPDF_Dictionary* pPageDict = pControlDict->GetDictBy("P")) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002077 int nPageIndex = pDocument->GetPageIndex(pPageDict->GetObjNum());
2078 if (nPageIndex >= 0) {
2079 pPage = m_pDocument->GetPageView(nPageIndex);
2080 }
2081 }
2082
2083 if (!pPage) {
2084 int nPageIndex = GetPageIndexByAnnotDict(pDocument, pControlDict);
2085 if (nPageIndex >= 0) {
2086 pPage = m_pDocument->GetPageView(nPageIndex);
2087 }
2088 }
2089
2090 if (!pPage)
2091 return nullptr;
2092 return (CPDFSDK_Widget*)pPage->GetAnnotByDict(pControlDict);
2093}
2094
Lei Zhangd88a3642015-11-10 09:38:57 -08002095void CPDFSDK_InterForm::GetWidgets(
2096 const CFX_WideString& sFieldName,
2097 std::vector<CPDFSDK_Widget*>* widgets) const {
2098 for (int i = 0, sz = m_pInterForm->CountFields(sFieldName); i < sz; ++i) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002099 CPDF_FormField* pFormField = m_pInterForm->GetField(i, sFieldName);
Lei Zhangd88a3642015-11-10 09:38:57 -08002100 ASSERT(pFormField);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002101 GetWidgets(pFormField, widgets);
2102 }
2103}
2104
Lei Zhangd88a3642015-11-10 09:38:57 -08002105void CPDFSDK_InterForm::GetWidgets(
2106 CPDF_FormField* pField,
2107 std::vector<CPDFSDK_Widget*>* widgets) const {
2108 for (int i = 0, sz = pField->CountControls(); i < sz; ++i) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002109 CPDF_FormControl* pFormCtrl = pField->GetControl(i);
Lei Zhangd88a3642015-11-10 09:38:57 -08002110 ASSERT(pFormCtrl);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002111 CPDFSDK_Widget* pWidget = GetWidget(pFormCtrl);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002112 if (pWidget)
Lei Zhangd88a3642015-11-10 09:38:57 -08002113 widgets->push_back(pWidget);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002114 }
2115}
2116
2117int CPDFSDK_InterForm::GetPageIndexByAnnotDict(
2118 CPDF_Document* pDocument,
2119 CPDF_Dictionary* pAnnotDict) const {
Lei Zhang96660d62015-12-14 18:27:25 -08002120 ASSERT(pAnnotDict);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002121
2122 for (int i = 0, sz = pDocument->GetPageCount(); i < sz; i++) {
2123 if (CPDF_Dictionary* pPageDict = pDocument->GetPage(i)) {
Wei Li9b761132016-01-29 15:44:20 -08002124 if (CPDF_Array* pAnnots = pPageDict->GetArrayBy("Annots")) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002125 for (int j = 0, jsz = pAnnots->GetCount(); j < jsz; j++) {
2126 CPDF_Object* pDict = pAnnots->GetElementValue(j);
2127 if (pAnnotDict == pDict) {
2128 return i;
2129 }
2130 }
2131 }
2132 }
2133 }
2134
2135 return -1;
2136}
2137
2138void CPDFSDK_InterForm::AddMap(CPDF_FormControl* pControl,
2139 CPDFSDK_Widget* pWidget) {
2140 m_Map[pControl] = pWidget;
2141}
2142
2143void CPDFSDK_InterForm::RemoveMap(CPDF_FormControl* pControl) {
2144 m_Map.erase(pControl);
2145}
2146
Tom Sepez40e9ff32015-11-30 12:39:54 -08002147void CPDFSDK_InterForm::EnableCalculate(FX_BOOL bEnabled) {
2148 m_bCalculate = bEnabled;
2149}
2150
2151FX_BOOL CPDFSDK_InterForm::IsCalculateEnabled() const {
2152 return m_bCalculate;
2153}
2154
Tom Sepez51da0932015-11-25 16:05:49 -08002155#ifdef PDF_ENABLE_XFA
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002156void CPDFSDK_InterForm::AddXFAMap(IXFA_Widget* hWidget,
2157 CPDFSDK_XFAWidget* pWidget) {
2158 m_XFAMap.SetAt(hWidget, pWidget);
2159}
2160
2161void CPDFSDK_InterForm::RemoveXFAMap(IXFA_Widget* hWidget) {
2162 m_XFAMap.RemoveKey(hWidget);
2163}
2164
2165CPDFSDK_XFAWidget* CPDFSDK_InterForm::GetXFAWidget(IXFA_Widget* hWidget) {
2166 CPDFSDK_XFAWidget* pWidget = NULL;
2167 m_XFAMap.Lookup(hWidget, pWidget);
2168
2169 return pWidget;
2170}
2171
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002172void CPDFSDK_InterForm::XfaEnableCalculate(FX_BOOL bEnabled) {
2173 m_bXfaCalculate = bEnabled;
2174}
2175FX_BOOL CPDFSDK_InterForm::IsXfaCalculateEnabled() const {
2176 return m_bXfaCalculate;
2177}
2178
2179FX_BOOL CPDFSDK_InterForm::IsXfaValidationsEnabled() {
2180 return m_bXfaValidationsEnabled;
2181}
2182void CPDFSDK_InterForm::XfaSetValidationsEnabled(FX_BOOL bEnabled) {
2183 m_bXfaValidationsEnabled = bEnabled;
Bo Xufdc00a72014-10-28 23:03:33 -07002184}
Tom Sepez40e9ff32015-11-30 12:39:54 -08002185#endif // PDF_ENABLE_XFA
Bo Xufdc00a72014-10-28 23:03:33 -07002186
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002187void CPDFSDK_InterForm::OnCalculate(CPDF_FormField* pFormField) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002188 CPDFDoc_Environment* pEnv = m_pDocument->GetEnv();
2189 ASSERT(pEnv);
2190 if (!pEnv->IsJSInitiated())
2191 return;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07002192
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002193 if (m_bBusy)
2194 return;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07002195
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002196 m_bBusy = TRUE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07002197
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002198 if (IsCalculateEnabled()) {
Tom Sepezba038bc2015-10-08 12:03:00 -07002199 IJS_Runtime* pRuntime = m_pDocument->GetJsRuntime();
Tom Sepez2f2ffec2015-07-23 14:42:09 -07002200 pRuntime->SetReaderDocument(m_pDocument);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07002201
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002202 int nSize = m_pInterForm->CountFieldsInCalculationOrder();
2203 for (int i = 0; i < nSize; i++) {
2204 if (CPDF_FormField* pField =
2205 m_pInterForm->GetFieldInCalculationOrder(i)) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002206 int nType = pField->GetFieldType();
2207 if (nType == FIELDTYPE_COMBOBOX || nType == FIELDTYPE_TEXTFIELD) {
2208 CPDF_AAction aAction = pField->GetAdditionalAction();
Wei Li0fc6b252016-03-01 16:29:41 -08002209 if (aAction.GetDict() &&
2210 aAction.ActionExist(CPDF_AAction::Calculate)) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002211 CPDF_Action action = aAction.GetAction(CPDF_AAction::Calculate);
Wei Li0fc6b252016-03-01 16:29:41 -08002212 if (action.GetDict()) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002213 CFX_WideString csJS = action.GetJavaScript();
2214 if (!csJS.IsEmpty()) {
Tom Sepezba038bc2015-10-08 12:03:00 -07002215 IJS_Context* pContext = pRuntime->NewContext();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002216 CFX_WideString sOldValue = pField->GetValue();
2217 CFX_WideString sValue = sOldValue;
2218 FX_BOOL bRC = TRUE;
2219 pContext->OnField_Calculate(pFormField, pField, sValue, bRC);
Lei Zhanga6d9f0e2015-06-13 00:48:38 -07002220
Tom Sepez2f2ffec2015-07-23 14:42:09 -07002221 CFX_WideString sInfo;
Tom Sepez33420902015-10-13 15:00:10 -07002222 FX_BOOL bRet = pContext->RunScript(csJS, &sInfo);
Tom Sepez2f2ffec2015-07-23 14:42:09 -07002223 pRuntime->ReleaseContext(pContext);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07002224
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002225 if (bRet) {
2226 if (bRC) {
2227 if (sValue.Compare(sOldValue) != 0)
2228 pField->SetValue(sValue, TRUE);
2229 }
Tom Sepez2f2ffec2015-07-23 14:42:09 -07002230 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002231 }
Tom Sepez2f2ffec2015-07-23 14:42:09 -07002232 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002233 }
Tom Sepez2f2ffec2015-07-23 14:42:09 -07002234 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002235 }
Tom Sepez2f2ffec2015-07-23 14:42:09 -07002236 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002237 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07002238
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002239 m_bBusy = FALSE;
2240}
2241
2242CFX_WideString CPDFSDK_InterForm::OnFormat(CPDF_FormField* pFormField,
2243 FX_BOOL& bFormated) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002244 CFX_WideString sValue = pFormField->GetValue();
2245 CPDFDoc_Environment* pEnv = m_pDocument->GetEnv();
2246 ASSERT(pEnv);
2247 if (!pEnv->IsJSInitiated()) {
2248 bFormated = FALSE;
Tom Sepez2f2ffec2015-07-23 14:42:09 -07002249 return sValue;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002250 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07002251
Tom Sepezba038bc2015-10-08 12:03:00 -07002252 IJS_Runtime* pRuntime = m_pDocument->GetJsRuntime();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002253 pRuntime->SetReaderDocument(m_pDocument);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07002254
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002255 if (pFormField->GetFieldType() == FIELDTYPE_COMBOBOX) {
2256 if (pFormField->CountSelectedItems() > 0) {
2257 int index = pFormField->GetSelectedIndex(0);
2258 if (index >= 0)
2259 sValue = pFormField->GetOptionLabel(index);
Tom Sepez2f2ffec2015-07-23 14:42:09 -07002260 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002261 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07002262
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002263 bFormated = FALSE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07002264
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002265 CPDF_AAction aAction = pFormField->GetAdditionalAction();
Wei Li0fc6b252016-03-01 16:29:41 -08002266 if (aAction.GetDict() && aAction.ActionExist(CPDF_AAction::Format)) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002267 CPDF_Action action = aAction.GetAction(CPDF_AAction::Format);
Wei Li0fc6b252016-03-01 16:29:41 -08002268 if (action.GetDict()) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002269 CFX_WideString script = action.GetJavaScript();
2270 if (!script.IsEmpty()) {
2271 CFX_WideString Value = sValue;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07002272
Tom Sepezba038bc2015-10-08 12:03:00 -07002273 IJS_Context* pContext = pRuntime->NewContext();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002274 pContext->OnField_Format(pFormField, Value, TRUE);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07002275
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002276 CFX_WideString sInfo;
Tom Sepez33420902015-10-13 15:00:10 -07002277 FX_BOOL bRet = pContext->RunScript(script, &sInfo);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002278 pRuntime->ReleaseContext(pContext);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07002279
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002280 if (bRet) {
2281 sValue = Value;
2282 bFormated = TRUE;
Tom Sepez2f2ffec2015-07-23 14:42:09 -07002283 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002284 }
Tom Sepez2f2ffec2015-07-23 14:42:09 -07002285 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002286 }
2287
2288 return sValue;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07002289}
2290
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002291void CPDFSDK_InterForm::ResetFieldAppearance(CPDF_FormField* pFormField,
2292 const FX_WCHAR* sValue,
2293 FX_BOOL bValueChanged) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002294 for (int i = 0, sz = pFormField->CountControls(); i < sz; i++) {
2295 CPDF_FormControl* pFormCtrl = pFormField->GetControl(i);
Lei Zhang96660d62015-12-14 18:27:25 -08002296 ASSERT(pFormCtrl);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002297 if (CPDFSDK_Widget* pWidget = GetWidget(pFormCtrl))
2298 pWidget->ResetAppearance(sValue, bValueChanged);
2299 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07002300}
2301
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002302void CPDFSDK_InterForm::UpdateField(CPDF_FormField* pFormField) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002303 for (int i = 0, sz = pFormField->CountControls(); i < sz; i++) {
2304 CPDF_FormControl* pFormCtrl = pFormField->GetControl(i);
Lei Zhang96660d62015-12-14 18:27:25 -08002305 ASSERT(pFormCtrl);
Lei Zhanga6d9f0e2015-06-13 00:48:38 -07002306
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002307 if (CPDFSDK_Widget* pWidget = GetWidget(pFormCtrl)) {
2308 CPDFDoc_Environment* pEnv = m_pDocument->GetEnv();
2309 CFFL_IFormFiller* pIFormFiller = pEnv->GetIFormFiller();
Tom Sepez540c4362015-11-24 13:33:57 -08002310 UnderlyingPageType* pPage = pWidget->GetUnderlyingPage();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002311 CPDFSDK_PageView* pPageView = m_pDocument->GetPageView(pPage, FALSE);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002312 FX_RECT rcBBox = pIFormFiller->GetViewBBox(pPageView, pWidget);
Lei Zhanga6d9f0e2015-06-13 00:48:38 -07002313
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002314 pEnv->FFI_Invalidate(pPage, rcBBox.left, rcBBox.top, rcBBox.right,
2315 rcBBox.bottom);
Tom Sepez2f2ffec2015-07-23 14:42:09 -07002316 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002317 }
2318}
2319
Tom Sepezd6262c12016-02-03 14:47:06 -08002320FX_BOOL CPDFSDK_InterForm::OnKeyStrokeCommit(CPDF_FormField* pFormField,
2321 const CFX_WideString& csValue) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002322 CPDF_AAction aAction = pFormField->GetAdditionalAction();
Wei Li0fc6b252016-03-01 16:29:41 -08002323 if (!aAction.GetDict() || !aAction.ActionExist(CPDF_AAction::KeyStroke))
Tom Sepezd6262c12016-02-03 14:47:06 -08002324 return TRUE;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002325
Tom Sepezd6262c12016-02-03 14:47:06 -08002326 CPDF_Action action = aAction.GetAction(CPDF_AAction::KeyStroke);
Wei Li0fc6b252016-03-01 16:29:41 -08002327 if (!action.GetDict())
Tom Sepezd6262c12016-02-03 14:47:06 -08002328 return TRUE;
2329
2330 CPDFDoc_Environment* pEnv = m_pDocument->GetEnv();
2331 CPDFSDK_ActionHandler* pActionHandler = pEnv->GetActionHander();
2332 PDFSDK_FieldAction fa;
2333 fa.bModifier = pEnv->FFI_IsCTRLKeyDown(0);
2334 fa.bShift = pEnv->FFI_IsSHIFTKeyDown(0);
2335 fa.sValue = csValue;
2336 pActionHandler->DoAction_FieldJavaScript(action, CPDF_AAction::KeyStroke,
2337 m_pDocument, pFormField, fa);
2338 return fa.bRC;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002339}
2340
Tom Sepezd6262c12016-02-03 14:47:06 -08002341FX_BOOL CPDFSDK_InterForm::OnValidate(CPDF_FormField* pFormField,
2342 const CFX_WideString& csValue) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002343 CPDF_AAction aAction = pFormField->GetAdditionalAction();
Wei Li0fc6b252016-03-01 16:29:41 -08002344 if (!aAction.GetDict() || !aAction.ActionExist(CPDF_AAction::Validate))
Tom Sepezd6262c12016-02-03 14:47:06 -08002345 return TRUE;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002346
Tom Sepezd6262c12016-02-03 14:47:06 -08002347 CPDF_Action action = aAction.GetAction(CPDF_AAction::Validate);
Wei Li0fc6b252016-03-01 16:29:41 -08002348 if (!action.GetDict())
Tom Sepezd6262c12016-02-03 14:47:06 -08002349 return TRUE;
2350
2351 CPDFDoc_Environment* pEnv = m_pDocument->GetEnv();
2352 CPDFSDK_ActionHandler* pActionHandler = pEnv->GetActionHander();
2353 PDFSDK_FieldAction fa;
2354 fa.bModifier = pEnv->FFI_IsCTRLKeyDown(0);
2355 fa.bShift = pEnv->FFI_IsSHIFTKeyDown(0);
2356 fa.sValue = csValue;
2357 pActionHandler->DoAction_FieldJavaScript(action, CPDF_AAction::Validate,
2358 m_pDocument, pFormField, fa);
2359 return fa.bRC;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07002360}
2361
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002362FX_BOOL CPDFSDK_InterForm::DoAction_Hide(const CPDF_Action& action) {
Wei Li0fc6b252016-03-01 16:29:41 -08002363 ASSERT(action.GetDict());
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07002364
Wei Li0fc6b252016-03-01 16:29:41 -08002365 CPDF_ActionFields af(&action);
Lei Zhangd88a3642015-11-10 09:38:57 -08002366 std::vector<CPDF_Object*> fieldObjects = af.GetAllFields();
2367 std::vector<CPDF_FormField*> fields = GetFieldFromObjects(fieldObjects);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002368
2369 FX_BOOL bHide = action.GetHideStatus();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002370 FX_BOOL bChanged = FALSE;
2371
Lei Zhangd88a3642015-11-10 09:38:57 -08002372 for (CPDF_FormField* pField : fields) {
2373 for (int i = 0, sz = pField->CountControls(); i < sz; ++i) {
2374 CPDF_FormControl* pControl = pField->GetControl(i);
2375 ASSERT(pControl);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002376
2377 if (CPDFSDK_Widget* pWidget = GetWidget(pControl)) {
Wei Li97da9762016-03-11 17:00:48 -08002378 FX_DWORD nFlags = pWidget->GetFlags();
Lei Zhangd88a3642015-11-10 09:38:57 -08002379 nFlags &= ~ANNOTFLAG_INVISIBLE;
2380 nFlags &= ~ANNOTFLAG_NOVIEW;
2381 if (bHide)
2382 nFlags |= ANNOTFLAG_HIDDEN;
2383 else
2384 nFlags &= ~ANNOTFLAG_HIDDEN;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002385 pWidget->SetFlags(nFlags);
Lei Zhangd88a3642015-11-10 09:38:57 -08002386 pWidget->GetPageView()->UpdateView(pWidget);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002387 bChanged = TRUE;
2388 }
2389 }
2390 }
2391
2392 return bChanged;
2393}
2394
2395FX_BOOL CPDFSDK_InterForm::DoAction_SubmitForm(const CPDF_Action& action) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002396 CFX_WideString sDestination = action.GetFilePath();
2397 if (sDestination.IsEmpty())
2398 return FALSE;
2399
2400 CPDF_Dictionary* pActionDict = action.GetDict();
2401 if (pActionDict->KeyExist("Fields")) {
Wei Li0fc6b252016-03-01 16:29:41 -08002402 CPDF_ActionFields af(&action);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002403 FX_DWORD dwFlags = action.GetFlags();
Lei Zhangd88a3642015-11-10 09:38:57 -08002404 std::vector<CPDF_Object*> fieldObjects = af.GetAllFields();
2405 std::vector<CPDF_FormField*> fields = GetFieldFromObjects(fieldObjects);
2406 if (!fields.empty()) {
2407 bool bIncludeOrExclude = !(dwFlags & 0x01);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002408 if (m_pInterForm->CheckRequiredFields(&fields, bIncludeOrExclude))
Tom Sepez2f2ffec2015-07-23 14:42:09 -07002409 return FALSE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07002410
Wei Li97da9762016-03-11 17:00:48 -08002411 return SubmitFields(sDestination, fields, bIncludeOrExclude, false);
Tom Sepez2f2ffec2015-07-23 14:42:09 -07002412 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002413 }
Lei Zhangd88a3642015-11-10 09:38:57 -08002414 if (m_pInterForm->CheckRequiredFields(nullptr, true))
Tom Sepez2f2ffec2015-07-23 14:42:09 -07002415 return FALSE;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002416
2417 return SubmitForm(sDestination, FALSE);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07002418}
2419
Lei Zhangd88a3642015-11-10 09:38:57 -08002420FX_BOOL CPDFSDK_InterForm::SubmitFields(
2421 const CFX_WideString& csDestination,
2422 const std::vector<CPDF_FormField*>& fields,
Wei Li97da9762016-03-11 17:00:48 -08002423 bool bIncludeOrExclude,
2424 bool bUrlEncoded) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002425 CPDFDoc_Environment* pEnv = m_pDocument->GetEnv();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002426
2427 CFX_ByteTextBuf textBuf;
2428 ExportFieldsToFDFTextBuf(fields, bIncludeOrExclude, textBuf);
2429
2430 uint8_t* pBuffer = textBuf.GetBuffer();
2431 FX_STRSIZE nBufSize = textBuf.GetLength();
2432
Lei Zhangd88a3642015-11-10 09:38:57 -08002433 if (bUrlEncoded && !FDFToURLEncodedData(pBuffer, nBufSize))
2434 return FALSE;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002435
2436 pEnv->JS_docSubmitForm(pBuffer, nBufSize, csDestination.c_str());
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002437 return TRUE;
2438}
2439
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002440FX_BOOL CPDFSDK_InterForm::FDFToURLEncodedData(CFX_WideString csFDFFile,
2441 CFX_WideString csTxtFile) {
2442 return TRUE;
2443}
2444
2445FX_BOOL CPDFSDK_InterForm::FDFToURLEncodedData(uint8_t*& pBuf,
2446 FX_STRSIZE& nBufSize) {
2447 CFDF_Document* pFDF = CFDF_Document::ParseMemory(pBuf, nBufSize);
2448 if (pFDF) {
Wei Li9b761132016-01-29 15:44:20 -08002449 CPDF_Dictionary* pMainDict = pFDF->GetRoot()->GetDictBy("FDF");
Lei Zhang997de612015-11-04 18:17:53 -08002450 if (!pMainDict)
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002451 return FALSE;
2452
2453 // Get fields
Wei Li9b761132016-01-29 15:44:20 -08002454 CPDF_Array* pFields = pMainDict->GetArrayBy("Fields");
Lei Zhang997de612015-11-04 18:17:53 -08002455 if (!pFields)
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002456 return FALSE;
2457
2458 CFX_ByteTextBuf fdfEncodedData;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002459 for (FX_DWORD i = 0; i < pFields->GetCount(); i++) {
Wei Li9b761132016-01-29 15:44:20 -08002460 CPDF_Dictionary* pField = pFields->GetDictAt(i);
Lei Zhang997de612015-11-04 18:17:53 -08002461 if (!pField)
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002462 continue;
2463 CFX_WideString name;
Wei Li9b761132016-01-29 15:44:20 -08002464 name = pField->GetUnicodeTextBy("T");
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002465 CFX_ByteString name_b = CFX_ByteString::FromUnicode(name);
Wei Li9b761132016-01-29 15:44:20 -08002466 CFX_ByteString csBValue = pField->GetStringBy("V");
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002467 CFX_WideString csWValue = PDF_DecodeText(csBValue);
2468 CFX_ByteString csValue_b = CFX_ByteString::FromUnicode(csWValue);
2469
Tom Sepez052a8d92016-02-19 14:41:46 -08002470 fdfEncodedData << name_b.GetBuffer(name_b.GetLength());
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002471 name_b.ReleaseBuffer();
Tom Sepez052a8d92016-02-19 14:41:46 -08002472 fdfEncodedData << "=";
2473 fdfEncodedData << csValue_b.GetBuffer(csValue_b.GetLength());
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002474 csValue_b.ReleaseBuffer();
2475 if (i != pFields->GetCount() - 1)
Tom Sepez052a8d92016-02-19 14:41:46 -08002476 fdfEncodedData << "&";
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002477 }
2478
2479 nBufSize = fdfEncodedData.GetLength();
2480 pBuf = FX_Alloc(uint8_t, nBufSize);
2481 FXSYS_memcpy(pBuf, fdfEncodedData.GetBuffer(), nBufSize);
2482 }
2483 return TRUE;
2484}
2485
Lei Zhangd88a3642015-11-10 09:38:57 -08002486FX_BOOL CPDFSDK_InterForm::ExportFieldsToFDFTextBuf(
2487 const std::vector<CPDF_FormField*>& fields,
Wei Li97da9762016-03-11 17:00:48 -08002488 bool bIncludeOrExclude,
Lei Zhangd88a3642015-11-10 09:38:57 -08002489 CFX_ByteTextBuf& textBuf) {
Lei Zhangaa8bf7e2015-12-24 19:13:32 -08002490 std::unique_ptr<CFDF_Document> pFDF(m_pInterForm->ExportToFDF(
Lei Zhangd88a3642015-11-10 09:38:57 -08002491 m_pDocument->GetPath(), fields, bIncludeOrExclude));
2492 return pFDF ? pFDF->WriteBuf(textBuf) : FALSE;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002493}
2494
Tom Sepez51da0932015-11-25 16:05:49 -08002495#ifdef PDF_ENABLE_XFA
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002496void CPDFSDK_InterForm::SynchronizeField(CPDF_FormField* pFormField,
2497 FX_BOOL bSynchronizeElse) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002498 int x = 0;
2499 if (m_FieldSynchronizeMap.Lookup(pFormField, x))
2500 return;
2501
2502 for (int i = 0, sz = pFormField->CountControls(); i < sz; i++) {
2503 CPDF_FormControl* pFormCtrl = pFormField->GetControl(i);
Lei Zhang5eca3052016-02-22 20:32:21 -08002504 ASSERT(pFormCtrl);
2505 ASSERT(m_pInterForm);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002506 if (CPDFSDK_Widget* pWidget = GetWidget(pFormCtrl)) {
2507 pWidget->Synchronize(bSynchronizeElse);
Tom Sepez2f2ffec2015-07-23 14:42:09 -07002508 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002509 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07002510}
Tom Sepez40e9ff32015-11-30 12:39:54 -08002511#endif // PDF_ENABLE_XFA
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07002512
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002513CFX_WideString CPDFSDK_InterForm::GetTemporaryFileName(
2514 const CFX_WideString& sFileExt) {
2515 CFX_WideString sFileName;
2516 return L"";
2517}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07002518
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002519FX_BOOL CPDFSDK_InterForm::SubmitForm(const CFX_WideString& sDestination,
2520 FX_BOOL bUrlEncoded) {
2521 if (sDestination.IsEmpty())
2522 return FALSE;
2523
Lei Zhang96660d62015-12-14 18:27:25 -08002524 if (!m_pDocument || !m_pInterForm)
2525 return FALSE;
2526
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002527 CPDFDoc_Environment* pEnv = m_pDocument->GetEnv();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002528 CFX_WideString wsPDFFilePath = m_pDocument->GetPath();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002529 CFDF_Document* pFDFDoc = m_pInterForm->ExportToFDF(wsPDFFilePath);
Lei Zhang997de612015-11-04 18:17:53 -08002530 if (!pFDFDoc)
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002531 return FALSE;
2532
2533 CFX_ByteTextBuf FdfBuffer;
2534 FX_BOOL bRet = pFDFDoc->WriteBuf(FdfBuffer);
2535 delete pFDFDoc;
2536 if (!bRet)
2537 return FALSE;
2538
2539 uint8_t* pBuffer = FdfBuffer.GetBuffer();
2540 FX_STRSIZE nBufSize = FdfBuffer.GetLength();
2541
2542 if (bUrlEncoded) {
2543 if (!FDFToURLEncodedData(pBuffer, nBufSize))
2544 return FALSE;
2545 }
2546
2547 pEnv->JS_docSubmitForm(pBuffer, nBufSize, sDestination.c_str());
2548
Lei Zhangda180e92015-08-14 22:22:13 -07002549 if (bUrlEncoded) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002550 FX_Free(pBuffer);
2551 pBuffer = NULL;
2552 }
2553
2554 return TRUE;
2555}
2556
2557FX_BOOL CPDFSDK_InterForm::ExportFormToFDFTextBuf(CFX_ByteTextBuf& textBuf) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002558 CFDF_Document* pFDF = m_pInterForm->ExportToFDF(m_pDocument->GetPath());
2559 if (!pFDF)
2560 return FALSE;
2561
2562 FX_BOOL bRet = pFDF->WriteBuf(textBuf);
2563 delete pFDF;
2564
2565 return bRet;
2566}
2567
2568FX_BOOL CPDFSDK_InterForm::DoAction_ResetForm(const CPDF_Action& action) {
Wei Li0fc6b252016-03-01 16:29:41 -08002569 ASSERT(action.GetDict());
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002570
2571 CPDF_Dictionary* pActionDict = action.GetDict();
Lei Zhangd88a3642015-11-10 09:38:57 -08002572 if (!pActionDict->KeyExist("Fields"))
2573 return m_pInterForm->ResetForm(true);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002574
Wei Li0fc6b252016-03-01 16:29:41 -08002575 CPDF_ActionFields af(&action);
Lei Zhangd88a3642015-11-10 09:38:57 -08002576 FX_DWORD dwFlags = action.GetFlags();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002577
Lei Zhangd88a3642015-11-10 09:38:57 -08002578 std::vector<CPDF_Object*> fieldObjects = af.GetAllFields();
2579 std::vector<CPDF_FormField*> fields = GetFieldFromObjects(fieldObjects);
2580 return m_pInterForm->ResetForm(fields, !(dwFlags & 0x01), true);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002581}
2582
2583FX_BOOL CPDFSDK_InterForm::DoAction_ImportData(const CPDF_Action& action) {
2584 return FALSE;
2585}
2586
Lei Zhangd88a3642015-11-10 09:38:57 -08002587std::vector<CPDF_FormField*> CPDFSDK_InterForm::GetFieldFromObjects(
2588 const std::vector<CPDF_Object*>& objects) const {
2589 std::vector<CPDF_FormField*> fields;
2590 for (CPDF_Object* pObject : objects) {
2591 if (pObject && pObject->IsString()) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002592 CFX_WideString csName = pObject->GetUnicodeText();
2593 CPDF_FormField* pField = m_pInterForm->GetField(0, csName);
Dan Sinclaird43ebdd2015-10-27 15:37:54 -04002594 if (pField)
Lei Zhangd88a3642015-11-10 09:38:57 -08002595 fields.push_back(pField);
Tom Sepez2f2ffec2015-07-23 14:42:09 -07002596 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002597 }
Lei Zhangd88a3642015-11-10 09:38:57 -08002598 return fields;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07002599}
2600
Tom Sepezd6262c12016-02-03 14:47:06 -08002601int CPDFSDK_InterForm::BeforeValueChange(CPDF_FormField* pField,
2602 const CFX_WideString& csValue) {
2603 int nType = pField->GetFieldType();
2604 if (nType != FIELDTYPE_COMBOBOX && nType != FIELDTYPE_TEXTFIELD)
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002605 return 0;
2606
Tom Sepezd6262c12016-02-03 14:47:06 -08002607 if (!OnKeyStrokeCommit(pField, csValue))
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002608 return -1;
2609
Tom Sepezd6262c12016-02-03 14:47:06 -08002610 if (!OnValidate(pField, csValue))
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002611 return -1;
2612
2613 return 1;
2614}
2615
Tom Sepezd6262c12016-02-03 14:47:06 -08002616void CPDFSDK_InterForm::AfterValueChange(CPDF_FormField* pField) {
2617#ifdef PDF_ENABLE_XFA
2618 SynchronizeField(pField, FALSE);
2619#endif // PDF_ENABLE_XFA
2620 int nType = pField->GetFieldType();
2621 if (nType == FIELDTYPE_COMBOBOX || nType == FIELDTYPE_TEXTFIELD) {
2622 OnCalculate(pField);
2623 FX_BOOL bFormated = FALSE;
2624 CFX_WideString sValue = OnFormat(pField, bFormated);
2625 ResetFieldAppearance(pField, bFormated ? sValue.c_str() : nullptr, TRUE);
2626 UpdateField(pField);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002627 }
Tom Sepezd6262c12016-02-03 14:47:06 -08002628}
2629
2630int CPDFSDK_InterForm::BeforeSelectionChange(CPDF_FormField* pField,
2631 const CFX_WideString& csValue) {
2632 if (pField->GetFieldType() != FIELDTYPE_LISTBOX)
2633 return 0;
2634
2635 if (!OnKeyStrokeCommit(pField, csValue))
2636 return -1;
2637
2638 if (!OnValidate(pField, csValue))
2639 return -1;
2640
2641 return 1;
2642}
2643
2644void CPDFSDK_InterForm::AfterSelectionChange(CPDF_FormField* pField) {
2645 if (pField->GetFieldType() == FIELDTYPE_LISTBOX) {
2646 OnCalculate(pField);
2647 ResetFieldAppearance(pField, NULL, TRUE);
2648 UpdateField(pField);
2649 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002650}
2651
Tom Sepezed5d7aa2016-02-02 16:02:03 -08002652void CPDFSDK_InterForm::AfterCheckedStatusChange(CPDF_FormField* pField) {
2653 int nType = pField->GetFieldType();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002654 if (nType == FIELDTYPE_CHECKBOX || nType == FIELDTYPE_RADIOBUTTON) {
Tom Sepezed5d7aa2016-02-02 16:02:03 -08002655 OnCalculate(pField);
2656 UpdateField(pField);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002657 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002658}
2659
Tom Sepezd6262c12016-02-03 14:47:06 -08002660int CPDFSDK_InterForm::BeforeFormReset(CPDF_InterForm* pForm) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002661 return 0;
2662}
2663
Tom Sepezd6262c12016-02-03 14:47:06 -08002664void CPDFSDK_InterForm::AfterFormReset(CPDF_InterForm* pForm) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002665 OnCalculate(nullptr);
Tom Sepezd6262c12016-02-03 14:47:06 -08002666}
2667
2668int CPDFSDK_InterForm::BeforeFormImportData(CPDF_InterForm* pForm) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002669 return 0;
2670}
2671
Tom Sepezd6262c12016-02-03 14:47:06 -08002672void CPDFSDK_InterForm::AfterFormImportData(CPDF_InterForm* pForm) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002673 OnCalculate(nullptr);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002674}
2675
2676FX_BOOL CPDFSDK_InterForm::IsNeedHighLight(int nFieldType) {
Tom Sepezae7a9172015-11-23 09:22:46 -08002677 if (nFieldType < 1 || nFieldType > kNumFieldTypes)
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002678 return FALSE;
2679 return m_bNeedHightlight[nFieldType - 1];
2680}
2681
2682void CPDFSDK_InterForm::RemoveAllHighLight() {
Tom Sepezae7a9172015-11-23 09:22:46 -08002683 for (int i = 0; i < kNumFieldTypes; ++i)
2684 m_bNeedHightlight[i] = FALSE;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002685}
Tom Sepezae7a9172015-11-23 09:22:46 -08002686
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002687void CPDFSDK_InterForm::SetHighlightColor(FX_COLORREF clr, int nFieldType) {
Tom Sepezae7a9172015-11-23 09:22:46 -08002688 if (nFieldType < 0 || nFieldType > kNumFieldTypes)
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002689 return;
2690 switch (nFieldType) {
2691 case 0: {
Tom Sepezae7a9172015-11-23 09:22:46 -08002692 for (int i = 0; i < kNumFieldTypes; ++i) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002693 m_aHighlightColor[i] = clr;
2694 m_bNeedHightlight[i] = TRUE;
2695 }
2696 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -07002697 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002698 default: {
2699 m_aHighlightColor[nFieldType - 1] = clr;
2700 m_bNeedHightlight[nFieldType - 1] = TRUE;
2701 break;
2702 }
2703 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07002704}
2705
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002706FX_COLORREF CPDFSDK_InterForm::GetHighlightColor(int nFieldType) {
Tom Sepezae7a9172015-11-23 09:22:46 -08002707 if (nFieldType < 0 || nFieldType > kNumFieldTypes)
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002708 return FXSYS_RGB(255, 255, 255);
2709 if (nFieldType == 0)
2710 return m_aHighlightColor[0];
2711 return m_aHighlightColor[nFieldType - 1];
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07002712}
2713
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002714CBA_AnnotIterator::CBA_AnnotIterator(CPDFSDK_PageView* pPageView,
2715 const CFX_ByteString& sType,
2716 const CFX_ByteString& sSubType)
Tom Sepezb9cc7a02016-02-01 13:42:30 -08002717 : m_eTabOrder(STRUCTURE),
2718 m_pPageView(pPageView),
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002719 m_sType(sType),
Tom Sepezb9cc7a02016-02-01 13:42:30 -08002720 m_sSubType(sSubType) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002721 CPDF_Page* pPDFPage = m_pPageView->GetPDFPage();
Wei Li9b761132016-01-29 15:44:20 -08002722 CFX_ByteString sTabs = pPDFPage->m_pFormDict->GetStringBy("Tabs");
Tom Sepezb9cc7a02016-02-01 13:42:30 -08002723 if (sTabs == "R")
2724 m_eTabOrder = ROW;
2725 else if (sTabs == "C")
2726 m_eTabOrder = COLUMN;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07002727
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002728 GenerateResults();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07002729}
2730
Dan Sinclairf766ad22016-03-14 13:51:24 -04002731CBA_AnnotIterator::~CBA_AnnotIterator() {}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07002732
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002733CPDFSDK_Annot* CBA_AnnotIterator::GetFirstAnnot() {
Tom Sepezb9cc7a02016-02-01 13:42:30 -08002734 return m_Annots.empty() ? nullptr : m_Annots.front();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07002735}
2736
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002737CPDFSDK_Annot* CBA_AnnotIterator::GetLastAnnot() {
Tom Sepezb9cc7a02016-02-01 13:42:30 -08002738 return m_Annots.empty() ? nullptr : m_Annots.back();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07002739}
2740
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002741CPDFSDK_Annot* CBA_AnnotIterator::GetNextAnnot(CPDFSDK_Annot* pAnnot) {
Tom Sepezb9cc7a02016-02-01 13:42:30 -08002742 auto iter = std::find(m_Annots.begin(), m_Annots.end(), pAnnot);
2743 if (iter == m_Annots.end())
2744 return nullptr;
2745 ++iter;
2746 if (iter == m_Annots.end())
2747 iter = m_Annots.begin();
2748 return *iter;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07002749}
2750
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002751CPDFSDK_Annot* CBA_AnnotIterator::GetPrevAnnot(CPDFSDK_Annot* pAnnot) {
Tom Sepezb9cc7a02016-02-01 13:42:30 -08002752 auto iter = std::find(m_Annots.begin(), m_Annots.end(), pAnnot);
2753 if (iter == m_Annots.end())
2754 return nullptr;
2755 if (iter == m_Annots.begin())
2756 iter = m_Annots.end();
2757 return *(--iter);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07002758}
2759
Tom Sepezb9cc7a02016-02-01 13:42:30 -08002760// static
2761bool CBA_AnnotIterator::CompareByLeftAscending(const CPDFSDK_Annot* p1,
2762 const CPDFSDK_Annot* p2) {
2763 return GetAnnotRect(p1).left < GetAnnotRect(p2).left;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07002764}
2765
Tom Sepezb9cc7a02016-02-01 13:42:30 -08002766// static
2767bool CBA_AnnotIterator::CompareByTopDescending(const CPDFSDK_Annot* p1,
2768 const CPDFSDK_Annot* p2) {
2769 return GetAnnotRect(p1).top > GetAnnotRect(p2).top;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07002770}
2771
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002772void CBA_AnnotIterator::GenerateResults() {
Tom Sepezb9cc7a02016-02-01 13:42:30 -08002773 switch (m_eTabOrder) {
2774 case STRUCTURE: {
Lei Zhangbf60b292015-10-26 12:14:35 -07002775 for (size_t i = 0; i < m_pPageView->CountAnnots(); ++i) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002776 CPDFSDK_Annot* pAnnot = m_pPageView->GetAnnot(i);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002777 if (pAnnot->GetType() == m_sType && pAnnot->GetSubType() == m_sSubType)
Tom Sepezb9cc7a02016-02-01 13:42:30 -08002778 m_Annots.push_back(pAnnot);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002779 }
Tom Sepezb9cc7a02016-02-01 13:42:30 -08002780 } break;
2781 case ROW: {
2782 std::vector<CPDFSDK_Annot*> sa;
Lei Zhang50218532015-10-30 14:03:43 -07002783 for (size_t i = 0; i < m_pPageView->CountAnnots(); ++i) {
2784 CPDFSDK_Annot* pAnnot = m_pPageView->GetAnnot(i);
2785 if (pAnnot->GetType() == m_sType && pAnnot->GetSubType() == m_sSubType)
Tom Sepezb9cc7a02016-02-01 13:42:30 -08002786 sa.push_back(pAnnot);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002787 }
2788
Tom Sepezb9cc7a02016-02-01 13:42:30 -08002789 std::sort(sa.begin(), sa.end(), CompareByLeftAscending);
2790 while (!sa.empty()) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002791 int nLeftTopIndex = -1;
Lei Zhang50218532015-10-30 14:03:43 -07002792 FX_FLOAT fTop = 0.0f;
Tom Sepezb9cc7a02016-02-01 13:42:30 -08002793 for (int i = sa.size() - 1; i >= 0; i--) {
Tom Sepez281a9ea2016-02-26 14:24:28 -08002794 CFX_FloatRect rcAnnot = GetAnnotRect(sa[i]);
Lei Zhang50218532015-10-30 14:03:43 -07002795 if (rcAnnot.top > fTop) {
2796 nLeftTopIndex = i;
2797 fTop = rcAnnot.top;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002798 }
Tom Sepez2f2ffec2015-07-23 14:42:09 -07002799 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002800 if (nLeftTopIndex >= 0) {
Tom Sepezb9cc7a02016-02-01 13:42:30 -08002801 CPDFSDK_Annot* pLeftTopAnnot = sa[nLeftTopIndex];
Tom Sepez281a9ea2016-02-26 14:24:28 -08002802 CFX_FloatRect rcLeftTop = GetAnnotRect(pLeftTopAnnot);
Tom Sepezb9cc7a02016-02-01 13:42:30 -08002803 m_Annots.push_back(pLeftTopAnnot);
2804 sa.erase(sa.begin() + nLeftTopIndex);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002805
Tom Sepezb9cc7a02016-02-01 13:42:30 -08002806 std::vector<int> aSelect;
2807 for (int i = 0; i < sa.size(); ++i) {
Tom Sepez281a9ea2016-02-26 14:24:28 -08002808 CFX_FloatRect rcAnnot = GetAnnotRect(sa[i]);
Lei Zhang50218532015-10-30 14:03:43 -07002809 FX_FLOAT fCenterY = (rcAnnot.top + rcAnnot.bottom) / 2.0f;
2810 if (fCenterY > rcLeftTop.bottom && fCenterY < rcLeftTop.top)
Tom Sepezb9cc7a02016-02-01 13:42:30 -08002811 aSelect.push_back(i);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002812 }
Tom Sepezb9cc7a02016-02-01 13:42:30 -08002813 for (int i = 0; i < aSelect.size(); ++i)
2814 m_Annots.push_back(sa[aSelect[i]]);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002815
Tom Sepezb9cc7a02016-02-01 13:42:30 -08002816 for (int i = aSelect.size() - 1; i >= 0; --i)
2817 sa.erase(sa.begin() + aSelect[i]);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002818 }
2819 }
Tom Sepezb9cc7a02016-02-01 13:42:30 -08002820 } break;
2821 case COLUMN: {
2822 std::vector<CPDFSDK_Annot*> sa;
Lei Zhang50218532015-10-30 14:03:43 -07002823 for (size_t i = 0; i < m_pPageView->CountAnnots(); ++i) {
2824 CPDFSDK_Annot* pAnnot = m_pPageView->GetAnnot(i);
2825 if (pAnnot->GetType() == m_sType && pAnnot->GetSubType() == m_sSubType)
Tom Sepezb9cc7a02016-02-01 13:42:30 -08002826 sa.push_back(pAnnot);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002827 }
2828
Tom Sepezb9cc7a02016-02-01 13:42:30 -08002829 std::sort(sa.begin(), sa.end(), CompareByTopDescending);
2830 while (!sa.empty()) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002831 int nLeftTopIndex = -1;
Lei Zhang50218532015-10-30 14:03:43 -07002832 FX_FLOAT fLeft = -1.0f;
Tom Sepezb9cc7a02016-02-01 13:42:30 -08002833 for (int i = sa.size() - 1; i >= 0; --i) {
Tom Sepez281a9ea2016-02-26 14:24:28 -08002834 CFX_FloatRect rcAnnot = GetAnnotRect(sa[i]);
Lei Zhang50218532015-10-30 14:03:43 -07002835 if (fLeft < 0) {
2836 nLeftTopIndex = 0;
2837 fLeft = rcAnnot.left;
2838 } else if (rcAnnot.left < fLeft) {
2839 nLeftTopIndex = i;
2840 fLeft = rcAnnot.left;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002841 }
Tom Sepez2f2ffec2015-07-23 14:42:09 -07002842 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002843
2844 if (nLeftTopIndex >= 0) {
Tom Sepezb9cc7a02016-02-01 13:42:30 -08002845 CPDFSDK_Annot* pLeftTopAnnot = sa[nLeftTopIndex];
Tom Sepez281a9ea2016-02-26 14:24:28 -08002846 CFX_FloatRect rcLeftTop = GetAnnotRect(pLeftTopAnnot);
Tom Sepezb9cc7a02016-02-01 13:42:30 -08002847 m_Annots.push_back(pLeftTopAnnot);
2848 sa.erase(sa.begin() + nLeftTopIndex);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002849
Tom Sepezb9cc7a02016-02-01 13:42:30 -08002850 std::vector<int> aSelect;
2851 for (int i = 0; i < sa.size(); ++i) {
Tom Sepez281a9ea2016-02-26 14:24:28 -08002852 CFX_FloatRect rcAnnot = GetAnnotRect(sa[i]);
Lei Zhang50218532015-10-30 14:03:43 -07002853 FX_FLOAT fCenterX = (rcAnnot.left + rcAnnot.right) / 2.0f;
2854 if (fCenterX > rcLeftTop.left && fCenterX < rcLeftTop.right)
Tom Sepezb9cc7a02016-02-01 13:42:30 -08002855 aSelect.push_back(i);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002856 }
Tom Sepezb9cc7a02016-02-01 13:42:30 -08002857 for (int i = 0; i < aSelect.size(); ++i)
2858 m_Annots.push_back(sa[aSelect[i]]);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002859
Tom Sepezb9cc7a02016-02-01 13:42:30 -08002860 for (int i = aSelect.size() - 1; i >= 0; --i)
2861 sa.erase(sa.begin() + aSelect[i]);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002862 }
2863 }
Lei Zhang50218532015-10-30 14:03:43 -07002864 break;
2865 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002866 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07002867}
2868
Tom Sepez281a9ea2016-02-26 14:24:28 -08002869CFX_FloatRect CBA_AnnotIterator::GetAnnotRect(const CPDFSDK_Annot* pAnnot) {
2870 CFX_FloatRect rcAnnot;
Lei Zhang50218532015-10-30 14:03:43 -07002871 pAnnot->GetPDFAnnot()->GetRect(rcAnnot);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002872 return rcAnnot;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07002873}