OLD | NEW |
1 // Copyright 2014 PDFium Authors. All rights reserved. | 1 // Copyright 2016 PDFium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com | 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com |
6 | 6 |
7 #include "fpdfsdk/include/fsdk_baseform.h" | 7 #include "fpdfsdk/include/cpdfsdk_widget.h" |
8 | 8 |
9 #include <algorithm> | |
10 #include <map> | |
11 #include <memory> | 9 #include <memory> |
12 #include <vector> | |
13 | 10 |
14 #include "core/fpdfapi/fpdf_page/include/cpdf_page.h" | 11 #include "core/fpdfapi/fpdf_parser/include/cpdf_dictionary.h" |
15 #include "core/fpdfapi/fpdf_parser/include/cfdf_document.h" | |
16 #include "core/fpdfapi/fpdf_parser/include/cpdf_array.h" | |
17 #include "core/fpdfapi/fpdf_parser/include/cpdf_document.h" | 12 #include "core/fpdfapi/fpdf_parser/include/cpdf_document.h" |
18 #include "core/fpdfapi/fpdf_parser/include/cpdf_stream.h" | 13 #include "core/fpdfapi/fpdf_parser/include/cpdf_stream.h" |
19 #include "core/fpdfdoc/include/cpdf_actionfields.h" | 14 #include "core/fpdfdoc/include/cpdf_defaultappearance.h" |
| 15 #include "core/fpdfdoc/include/cpdf_formcontrol.h" |
| 16 #include "core/fpdfdoc/include/cpdf_formfield.h" |
| 17 #include "core/fpdfdoc/include/cpdf_iconfit.h" |
20 #include "core/fpdfdoc/include/cpdf_interform.h" | 18 #include "core/fpdfdoc/include/cpdf_interform.h" |
21 #include "core/fxge/include/cfx_graphstatedata.h" | 19 #include "core/fxge/include/cfx_graphstatedata.h" |
22 #include "core/fxge/include/cfx_pathdata.h" | 20 #include "core/fxge/include/cfx_pathdata.h" |
23 #include "core/fxge/include/cfx_renderdevice.h" | 21 #include "core/fxge/include/cfx_renderdevice.h" |
24 #include "fpdfsdk/formfiller/cffl_formfiller.h" | 22 #include "fpdfsdk/formfiller/cba_fontmap.h" |
25 #include "fpdfsdk/fxedit/include/fxet_edit.h" | 23 #include "fpdfsdk/fxedit/include/fxet_edit.h" |
26 #include "fpdfsdk/include/cpdfsdk_annot.h" | 24 #include "fpdfsdk/include/cpdfsdk_interform.h" |
27 #include "fpdfsdk/include/fsdk_actionhandler.h" | |
28 #include "fpdfsdk/include/fsdk_define.h" | 25 #include "fpdfsdk/include/fsdk_define.h" |
29 #include "fpdfsdk/include/fsdk_mgr.h" | 26 #include "fpdfsdk/include/fsdk_mgr.h" |
30 #include "fpdfsdk/include/ipdfsdk_annothandler.h" | 27 #include "fpdfsdk/pdfwindow/PWL_Edit.h" |
31 #include "fpdfsdk/javascript/ijs_context.h" | |
32 #include "fpdfsdk/javascript/ijs_runtime.h" | |
33 #include "fpdfsdk/pdfwindow/PWL_Utils.h" | 28 #include "fpdfsdk/pdfwindow/PWL_Utils.h" |
34 #include "third_party/base/stl_util.h" | 29 #include "third_party/base/stl_util.h" |
35 | 30 |
36 #ifdef PDF_ENABLE_XFA | 31 #ifdef PDF_ENABLE_XFA |
37 #include "fpdfsdk/fpdfxfa/include/fpdfxfa_doc.h" | 32 #include "fpdfsdk/fpdfxfa/include/fpdfxfa_doc.h" |
38 #include "fpdfsdk/fpdfxfa/include/fpdfxfa_util.h" | |
39 #include "xfa/fxfa/include/cxfa_eventparam.h" | 33 #include "xfa/fxfa/include/cxfa_eventparam.h" |
| 34 #include "xfa/fxfa/include/fxfa_widget.h" |
40 #include "xfa/fxfa/include/xfa_ffdocview.h" | 35 #include "xfa/fxfa/include/xfa_ffdocview.h" |
41 #include "xfa/fxfa/include/xfa_ffwidget.h" | 36 #include "xfa/fxfa/include/xfa_ffwidget.h" |
42 #include "xfa/fxfa/include/xfa_ffwidgethandler.h" | 37 #include "xfa/fxfa/include/xfa_ffwidgethandler.h" |
43 #endif // PDF_ENABLE_XFA | 38 #endif // PDF_ENABLE_XFA |
44 | 39 |
45 PDFSDK_FieldAction::PDFSDK_FieldAction() | |
46 : bModifier(FALSE), | |
47 bShift(FALSE), | |
48 nCommitKey(0), | |
49 bKeyDown(FALSE), | |
50 nSelEnd(0), | |
51 nSelStart(0), | |
52 bWillCommit(FALSE), | |
53 bFieldFull(FALSE), | |
54 bRC(TRUE) {} | |
55 | |
56 CPDFSDK_Widget::Observer::Observer(CPDFSDK_Widget** pWatchedPtr) | 40 CPDFSDK_Widget::Observer::Observer(CPDFSDK_Widget** pWatchedPtr) |
57 : m_pWatchedPtr(pWatchedPtr) { | 41 : m_pWatchedPtr(pWatchedPtr) { |
58 (*m_pWatchedPtr)->AddObserver(this); | 42 (*m_pWatchedPtr)->AddObserver(this); |
59 } | 43 } |
60 | 44 |
61 CPDFSDK_Widget::Observer::~Observer() { | 45 CPDFSDK_Widget::Observer::~Observer() { |
62 if (m_pWatchedPtr) | 46 if (m_pWatchedPtr) |
63 (*m_pWatchedPtr)->RemoveObserver(this); | 47 (*m_pWatchedPtr)->RemoveObserver(this); |
64 } | 48 } |
65 | 49 |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
137 } | 121 } |
138 | 122 |
139 return nullptr; | 123 return nullptr; |
140 } | 124 } |
141 | 125 |
142 CXFA_FFWidgetHandler* CPDFSDK_Widget::GetXFAWidgetHandler() const { | 126 CXFA_FFWidgetHandler* CPDFSDK_Widget::GetXFAWidgetHandler() const { |
143 CPDFSDK_Document* pSDKDoc = m_pPageView->GetSDKDocument(); | 127 CPDFSDK_Document* pSDKDoc = m_pPageView->GetSDKDocument(); |
144 CPDFXFA_Document* pDoc = pSDKDoc->GetXFADocument(); | 128 CPDFXFA_Document* pDoc = pSDKDoc->GetXFADocument(); |
145 if (pDoc->GetDocType() == DOCTYPE_STATIC_XFA) { | 129 if (pDoc->GetDocType() == DOCTYPE_STATIC_XFA) { |
146 if (!m_pWidgetHandler) { | 130 if (!m_pWidgetHandler) { |
147 if (CXFA_FFDocView* pDocView = pDoc->GetXFADocView()) { | 131 if (CXFA_FFDocView* pDocView = pDoc->GetXFADocView()) |
148 m_pWidgetHandler = pDocView->GetWidgetHandler(); | 132 m_pWidgetHandler = pDocView->GetWidgetHandler(); |
149 } | |
150 } | 133 } |
151 return m_pWidgetHandler; | 134 return m_pWidgetHandler; |
152 } | 135 } |
153 | 136 |
154 return nullptr; | 137 return nullptr; |
155 } | 138 } |
156 | 139 |
157 static XFA_EVENTTYPE GetXFAEventType(PDFSDK_XFAAActionType eXFAAAT) { | 140 static XFA_EVENTTYPE GetXFAEventType(PDFSDK_XFAAActionType eXFAAAT) { |
158 XFA_EVENTTYPE eEventType = XFA_EVENT_Unknown; | 141 XFA_EVENTTYPE eEventType = XFA_EVENT_Unknown; |
159 | 142 |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
200 break; | 183 break; |
201 case CPDF_AAction::PageOpen: | 184 case CPDF_AAction::PageOpen: |
202 break; | 185 break; |
203 case CPDF_AAction::PageClose: | 186 case CPDF_AAction::PageClose: |
204 break; | 187 break; |
205 case CPDF_AAction::PageVisible: | 188 case CPDF_AAction::PageVisible: |
206 break; | 189 break; |
207 case CPDF_AAction::PageInvisible: | 190 case CPDF_AAction::PageInvisible: |
208 break; | 191 break; |
209 case CPDF_AAction::KeyStroke: | 192 case CPDF_AAction::KeyStroke: |
210 if (!bWillCommit) { | 193 if (!bWillCommit) |
211 eEventType = XFA_EVENT_Change; | 194 eEventType = XFA_EVENT_Change; |
212 } | |
213 break; | 195 break; |
214 case CPDF_AAction::Validate: | 196 case CPDF_AAction::Validate: |
215 eEventType = XFA_EVENT_Validate; | 197 eEventType = XFA_EVENT_Validate; |
216 break; | 198 break; |
217 case CPDF_AAction::OpenPage: | 199 case CPDF_AAction::OpenPage: |
218 case CPDF_AAction::ClosePage: | 200 case CPDF_AAction::ClosePage: |
219 case CPDF_AAction::Format: | 201 case CPDF_AAction::Format: |
220 case CPDF_AAction::Calculate: | 202 case CPDF_AAction::Calculate: |
221 case CPDF_AAction::CloseDocument: | 203 case CPDF_AAction::CloseDocument: |
222 case CPDF_AAction::SaveDocument: | 204 case CPDF_AAction::SaveDocument: |
223 case CPDF_AAction::DocumentSaved: | 205 case CPDF_AAction::DocumentSaved: |
224 case CPDF_AAction::PrintDocument: | 206 case CPDF_AAction::PrintDocument: |
225 case CPDF_AAction::DocumentPrinted: | 207 case CPDF_AAction::DocumentPrinted: |
226 break; | 208 break; |
227 } | 209 } |
228 | 210 |
229 return eEventType; | 211 return eEventType; |
230 } | 212 } |
231 | 213 |
232 FX_BOOL CPDFSDK_Widget::HasXFAAAction(PDFSDK_XFAAActionType eXFAAAT) { | 214 FX_BOOL CPDFSDK_Widget::HasXFAAAction(PDFSDK_XFAAActionType eXFAAAT) { |
233 if (CXFA_FFWidget* hWidget = GetMixXFAWidget()) { | 215 CXFA_FFWidget* hWidget = GetMixXFAWidget(); |
234 if (CXFA_FFWidgetHandler* pXFAWidgetHandler = GetXFAWidgetHandler()) { | 216 if (!hWidget) |
235 XFA_EVENTTYPE eEventType = GetXFAEventType(eXFAAAT); | 217 return FALSE; |
236 | 218 |
237 if ((eEventType == XFA_EVENT_Click || eEventType == XFA_EVENT_Change) && | 219 CXFA_FFWidgetHandler* pXFAWidgetHandler = GetXFAWidgetHandler(); |
238 GetFieldType() == FIELDTYPE_RADIOBUTTON) { | 220 if (!pXFAWidgetHandler) |
239 if (CXFA_FFWidget* hGroupWidget = GetGroupMixXFAWidget()) { | 221 return FALSE; |
240 CXFA_WidgetAcc* pAcc = hGroupWidget->GetDataAcc(); | |
241 if (pXFAWidgetHandler->HasEvent(pAcc, eEventType)) | |
242 return TRUE; | |
243 } | |
244 } | |
245 | 222 |
246 { | 223 XFA_EVENTTYPE eEventType = GetXFAEventType(eXFAAAT); |
247 CXFA_WidgetAcc* pAcc = hWidget->GetDataAcc(); | 224 |
248 return pXFAWidgetHandler->HasEvent(pAcc, eEventType); | 225 CXFA_WidgetAcc* pAcc; |
249 } | 226 if ((eEventType == XFA_EVENT_Click || eEventType == XFA_EVENT_Change) && |
| 227 GetFieldType() == FIELDTYPE_RADIOBUTTON) { |
| 228 if (CXFA_FFWidget* hGroupWidget = GetGroupMixXFAWidget()) { |
| 229 pAcc = hGroupWidget->GetDataAcc(); |
| 230 if (pXFAWidgetHandler->HasEvent(pAcc, eEventType)) |
| 231 return TRUE; |
250 } | 232 } |
251 } | 233 } |
252 | 234 |
253 return FALSE; | 235 pAcc = hWidget->GetDataAcc(); |
| 236 return pXFAWidgetHandler->HasEvent(pAcc, eEventType); |
254 } | 237 } |
255 | 238 |
256 FX_BOOL CPDFSDK_Widget::OnXFAAAction(PDFSDK_XFAAActionType eXFAAAT, | 239 FX_BOOL CPDFSDK_Widget::OnXFAAAction(PDFSDK_XFAAActionType eXFAAAT, |
257 PDFSDK_FieldAction& data, | 240 PDFSDK_FieldAction& data, |
258 CPDFSDK_PageView* pPageView) { | 241 CPDFSDK_PageView* pPageView) { |
259 CPDFSDK_Document* pSDKDoc = m_pPageView->GetSDKDocument(); | 242 CPDFSDK_Document* pSDKDoc = m_pPageView->GetSDKDocument(); |
260 CPDFXFA_Document* pDoc = pSDKDoc->GetXFADocument(); | 243 CPDFXFA_Document* pDoc = pSDKDoc->GetXFADocument(); |
261 if (CXFA_FFWidget* hWidget = GetMixXFAWidget()) { | |
262 XFA_EVENTTYPE eEventType = GetXFAEventType(eXFAAAT); | |
263 | 244 |
264 if (eEventType != XFA_EVENT_Unknown) { | 245 CXFA_FFWidget* hWidget = GetMixXFAWidget(); |
265 if (CXFA_FFWidgetHandler* pXFAWidgetHandler = GetXFAWidgetHandler()) { | 246 if (!hWidget) |
266 CXFA_EventParam param; | 247 return FALSE; |
267 param.m_eType = eEventType; | |
268 param.m_wsChange = data.sChange; | |
269 param.m_iCommitKey = data.nCommitKey; | |
270 param.m_bShift = data.bShift; | |
271 param.m_iSelStart = data.nSelStart; | |
272 param.m_iSelEnd = data.nSelEnd; | |
273 param.m_wsFullText = data.sValue; | |
274 param.m_bKeyDown = data.bKeyDown; | |
275 param.m_bModifier = data.bModifier; | |
276 param.m_wsNewText = data.sValue; | |
277 if (data.nSelEnd > data.nSelStart) | |
278 param.m_wsNewText.Delete(data.nSelStart, | |
279 data.nSelEnd - data.nSelStart); | |
280 for (int i = 0; i < data.sChange.GetLength(); i++) | |
281 param.m_wsNewText.Insert(data.nSelStart, data.sChange[i]); | |
282 param.m_wsPrevText = data.sValue; | |
283 | 248 |
284 if ((eEventType == XFA_EVENT_Click || eEventType == XFA_EVENT_Change) && | 249 XFA_EVENTTYPE eEventType = GetXFAEventType(eXFAAAT); |
285 GetFieldType() == FIELDTYPE_RADIOBUTTON) { | 250 if (eEventType == XFA_EVENT_Unknown) |
286 if (CXFA_FFWidget* hGroupWidget = GetGroupMixXFAWidget()) { | 251 return FALSE; |
287 CXFA_WidgetAcc* pAcc = hGroupWidget->GetDataAcc(); | |
288 param.m_pTarget = pAcc; | |
289 if (pXFAWidgetHandler->ProcessEvent(pAcc, ¶m) != | |
290 XFA_EVENTERROR_Success) { | |
291 return FALSE; | |
292 } | |
293 } | |
294 } | |
295 CXFA_WidgetAcc* pAcc = hWidget->GetDataAcc(); | |
296 param.m_pTarget = pAcc; | |
297 int32_t nRet = pXFAWidgetHandler->ProcessEvent(pAcc, ¶m); | |
298 | 252 |
299 if (CXFA_FFDocView* pDocView = pDoc->GetXFADocView()) { | 253 CXFA_FFWidgetHandler* pXFAWidgetHandler = GetXFAWidgetHandler(); |
300 pDocView->UpdateDocView(); | 254 if (!pXFAWidgetHandler) |
301 } | 255 return FALSE; |
302 return nRet == XFA_EVENTERROR_Success; | 256 |
| 257 CXFA_EventParam param; |
| 258 param.m_eType = eEventType; |
| 259 param.m_wsChange = data.sChange; |
| 260 param.m_iCommitKey = data.nCommitKey; |
| 261 param.m_bShift = data.bShift; |
| 262 param.m_iSelStart = data.nSelStart; |
| 263 param.m_iSelEnd = data.nSelEnd; |
| 264 param.m_wsFullText = data.sValue; |
| 265 param.m_bKeyDown = data.bKeyDown; |
| 266 param.m_bModifier = data.bModifier; |
| 267 param.m_wsNewText = data.sValue; |
| 268 if (data.nSelEnd > data.nSelStart) |
| 269 param.m_wsNewText.Delete(data.nSelStart, data.nSelEnd - data.nSelStart); |
| 270 |
| 271 for (int i = 0; i < data.sChange.GetLength(); i++) |
| 272 param.m_wsNewText.Insert(data.nSelStart, data.sChange[i]); |
| 273 param.m_wsPrevText = data.sValue; |
| 274 |
| 275 if ((eEventType == XFA_EVENT_Click || eEventType == XFA_EVENT_Change) && |
| 276 GetFieldType() == FIELDTYPE_RADIOBUTTON) { |
| 277 if (CXFA_FFWidget* hGroupWidget = GetGroupMixXFAWidget()) { |
| 278 CXFA_WidgetAcc* pAcc = hGroupWidget->GetDataAcc(); |
| 279 param.m_pTarget = pAcc; |
| 280 if (pXFAWidgetHandler->ProcessEvent(pAcc, ¶m) != |
| 281 XFA_EVENTERROR_Success) { |
| 282 return FALSE; |
303 } | 283 } |
304 } | 284 } |
305 } | 285 } |
| 286 CXFA_WidgetAcc* pAcc = hWidget->GetDataAcc(); |
| 287 param.m_pTarget = pAcc; |
| 288 int32_t nRet = pXFAWidgetHandler->ProcessEvent(pAcc, ¶m); |
306 | 289 |
307 return FALSE; | 290 if (CXFA_FFDocView* pDocView = pDoc->GetXFADocView()) |
| 291 pDocView->UpdateDocView(); |
| 292 |
| 293 return nRet == XFA_EVENTERROR_Success; |
308 } | 294 } |
309 | 295 |
310 void CPDFSDK_Widget::Synchronize(FX_BOOL bSynchronizeElse) { | 296 void CPDFSDK_Widget::Synchronize(FX_BOOL bSynchronizeElse) { |
311 if (CXFA_FFWidget* hWidget = GetMixXFAWidget()) { | 297 CXFA_FFWidget* hWidget = GetMixXFAWidget(); |
312 CPDF_FormField* pFormField = GetFormField(); | 298 if (!hWidget) |
313 if (CXFA_WidgetAcc* pWidgetAcc = hWidget->GetDataAcc()) { | 299 return; |
314 switch (GetFieldType()) { | |
315 case FIELDTYPE_CHECKBOX: | |
316 case FIELDTYPE_RADIOBUTTON: { | |
317 CPDF_FormControl* pFormCtrl = GetFormControl(); | |
318 XFA_CHECKSTATE eCheckState = | |
319 pFormCtrl->IsChecked() ? XFA_CHECKSTATE_On : XFA_CHECKSTATE_Off; | |
320 pWidgetAcc->SetCheckState(eCheckState, true); | |
321 } break; | |
322 case FIELDTYPE_TEXTFIELD: | |
323 pWidgetAcc->SetValue(pFormField->GetValue(), XFA_VALUEPICTURE_Edit); | |
324 break; | |
325 case FIELDTYPE_LISTBOX: { | |
326 pWidgetAcc->ClearAllSelections(); | |
327 | 300 |
328 for (int i = 0, sz = pFormField->CountSelectedItems(); i < sz; i++) { | 301 CXFA_WidgetAcc* pWidgetAcc = hWidget->GetDataAcc(); |
329 int nIndex = pFormField->GetSelectedIndex(i); | 302 if (!pWidgetAcc) |
330 if (nIndex > -1 && nIndex < pWidgetAcc->CountChoiceListItems()) | 303 return; |
331 pWidgetAcc->SetItemState(nIndex, TRUE, false, FALSE, TRUE); | |
332 } | |
333 } break; | |
334 case FIELDTYPE_COMBOBOX: { | |
335 pWidgetAcc->ClearAllSelections(); | |
336 | 304 |
337 for (int i = 0, sz = pFormField->CountSelectedItems(); i < sz; i++) { | 305 CPDF_FormField* pFormField = GetFormField(); |
338 int nIndex = pFormField->GetSelectedIndex(i); | 306 switch (GetFieldType()) { |
339 if (nIndex > -1 && nIndex < pWidgetAcc->CountChoiceListItems()) | 307 case FIELDTYPE_CHECKBOX: |
340 pWidgetAcc->SetItemState(nIndex, TRUE, false, FALSE, TRUE); | 308 case FIELDTYPE_RADIOBUTTON: { |
341 } | 309 CPDF_FormControl* pFormCtrl = GetFormControl(); |
342 } | 310 XFA_CHECKSTATE eCheckState = |
| 311 pFormCtrl->IsChecked() ? XFA_CHECKSTATE_On : XFA_CHECKSTATE_Off; |
| 312 pWidgetAcc->SetCheckState(eCheckState, true); |
| 313 break; |
| 314 } |
| 315 case FIELDTYPE_TEXTFIELD: |
| 316 pWidgetAcc->SetValue(pFormField->GetValue(), XFA_VALUEPICTURE_Edit); |
| 317 break; |
| 318 case FIELDTYPE_LISTBOX: { |
| 319 pWidgetAcc->ClearAllSelections(); |
343 | 320 |
344 pWidgetAcc->SetValue(pFormField->GetValue(), XFA_VALUEPICTURE_Edit); | 321 for (int i = 0, sz = pFormField->CountSelectedItems(); i < sz; i++) { |
345 break; | 322 int nIndex = pFormField->GetSelectedIndex(i); |
| 323 if (nIndex > -1 && nIndex < pWidgetAcc->CountChoiceListItems()) |
| 324 pWidgetAcc->SetItemState(nIndex, TRUE, false, FALSE, TRUE); |
346 } | 325 } |
| 326 break; |
| 327 } |
| 328 case FIELDTYPE_COMBOBOX: { |
| 329 pWidgetAcc->ClearAllSelections(); |
347 | 330 |
348 if (bSynchronizeElse) | 331 for (int i = 0, sz = pFormField->CountSelectedItems(); i < sz; i++) { |
349 pWidgetAcc->ProcessValueChanged(); | 332 int nIndex = pFormField->GetSelectedIndex(i); |
| 333 if (nIndex > -1 && nIndex < pWidgetAcc->CountChoiceListItems()) |
| 334 pWidgetAcc->SetItemState(nIndex, TRUE, false, FALSE, TRUE); |
| 335 } |
| 336 pWidgetAcc->SetValue(pFormField->GetValue(), XFA_VALUEPICTURE_Edit); |
| 337 break; |
350 } | 338 } |
351 } | 339 } |
| 340 |
| 341 if (bSynchronizeElse) |
| 342 pWidgetAcc->ProcessValueChanged(); |
352 } | 343 } |
353 | 344 |
354 void CPDFSDK_Widget::SynchronizeXFAValue() { | 345 void CPDFSDK_Widget::SynchronizeXFAValue() { |
355 CPDFSDK_Document* pSDKDoc = m_pPageView->GetSDKDocument(); | 346 CPDFSDK_Document* pSDKDoc = m_pPageView->GetSDKDocument(); |
356 CPDFXFA_Document* pDoc = pSDKDoc->GetXFADocument(); | 347 CPDFXFA_Document* pDoc = pSDKDoc->GetXFADocument(); |
357 CXFA_FFDocView* pXFADocView = pDoc->GetXFADocView(); | 348 CXFA_FFDocView* pXFADocView = pDoc->GetXFADocView(); |
358 if (!pXFADocView) | 349 if (!pXFADocView) |
359 return; | 350 return; |
360 | 351 |
361 if (CXFA_FFWidget* hWidget = GetMixXFAWidget()) { | 352 if (CXFA_FFWidget* hWidget = GetMixXFAWidget()) { |
(...skipping 24 matching lines...) Expand all Loading... |
386 ASSERT(hWidget); | 377 ASSERT(hWidget); |
387 ASSERT(pFormControl); | 378 ASSERT(pFormControl); |
388 | 379 |
389 switch (pFormField->GetFieldType()) { | 380 switch (pFormField->GetFieldType()) { |
390 case FIELDTYPE_CHECKBOX: { | 381 case FIELDTYPE_CHECKBOX: { |
391 if (CXFA_WidgetAcc* pWidgetAcc = hWidget->GetDataAcc()) { | 382 if (CXFA_WidgetAcc* pWidgetAcc = hWidget->GetDataAcc()) { |
392 pFormField->CheckControl( | 383 pFormField->CheckControl( |
393 pFormField->GetControlIndex(pFormControl), | 384 pFormField->GetControlIndex(pFormControl), |
394 pWidgetAcc->GetCheckState() == XFA_CHECKSTATE_On, true); | 385 pWidgetAcc->GetCheckState() == XFA_CHECKSTATE_On, true); |
395 } | 386 } |
396 } break; | 387 break; |
| 388 } |
397 case FIELDTYPE_RADIOBUTTON: { | 389 case FIELDTYPE_RADIOBUTTON: { |
398 // TODO(weili): Check whether we need to handle checkbox and radio | 390 // TODO(weili): Check whether we need to handle checkbox and radio |
399 // button differently, otherwise, merge these two cases. | 391 // button differently, otherwise, merge these two cases. |
400 if (CXFA_WidgetAcc* pWidgetAcc = hWidget->GetDataAcc()) { | 392 if (CXFA_WidgetAcc* pWidgetAcc = hWidget->GetDataAcc()) { |
401 pFormField->CheckControl( | 393 pFormField->CheckControl( |
402 pFormField->GetControlIndex(pFormControl), | 394 pFormField->GetControlIndex(pFormControl), |
403 pWidgetAcc->GetCheckState() == XFA_CHECKSTATE_On, true); | 395 pWidgetAcc->GetCheckState() == XFA_CHECKSTATE_On, true); |
404 } | 396 } |
405 } break; | 397 break; |
| 398 } |
406 case FIELDTYPE_TEXTFIELD: { | 399 case FIELDTYPE_TEXTFIELD: { |
407 if (CXFA_WidgetAcc* pWidgetAcc = hWidget->GetDataAcc()) { | 400 if (CXFA_WidgetAcc* pWidgetAcc = hWidget->GetDataAcc()) { |
408 CFX_WideString sValue; | 401 CFX_WideString sValue; |
409 pWidgetAcc->GetValue(sValue, XFA_VALUEPICTURE_Display); | 402 pWidgetAcc->GetValue(sValue, XFA_VALUEPICTURE_Display); |
410 pFormField->SetValue(sValue, TRUE); | 403 pFormField->SetValue(sValue, TRUE); |
411 } | 404 } |
412 } break; | 405 break; |
| 406 } |
413 case FIELDTYPE_LISTBOX: { | 407 case FIELDTYPE_LISTBOX: { |
414 pFormField->ClearSelection(FALSE); | 408 pFormField->ClearSelection(FALSE); |
415 | 409 |
416 if (CXFA_WidgetAcc* pWidgetAcc = hWidget->GetDataAcc()) { | 410 if (CXFA_WidgetAcc* pWidgetAcc = hWidget->GetDataAcc()) { |
417 for (int i = 0, sz = pWidgetAcc->CountSelectedItems(); i < sz; i++) { | 411 for (int i = 0, sz = pWidgetAcc->CountSelectedItems(); i < sz; i++) { |
418 int nIndex = pWidgetAcc->GetSelectedItem(i); | 412 int nIndex = pWidgetAcc->GetSelectedItem(i); |
419 | 413 |
420 if (nIndex > -1 && nIndex < pFormField->CountOptions()) { | 414 if (nIndex > -1 && nIndex < pFormField->CountOptions()) { |
421 pFormField->SetItemSelection(nIndex, TRUE, TRUE); | 415 pFormField->SetItemSelection(nIndex, TRUE, TRUE); |
422 } | 416 } |
423 } | 417 } |
424 } | 418 } |
425 } break; | 419 break; |
| 420 } |
426 case FIELDTYPE_COMBOBOX: { | 421 case FIELDTYPE_COMBOBOX: { |
427 pFormField->ClearSelection(FALSE); | 422 pFormField->ClearSelection(FALSE); |
428 | 423 |
429 if (CXFA_WidgetAcc* pWidgetAcc = hWidget->GetDataAcc()) { | 424 if (CXFA_WidgetAcc* pWidgetAcc = hWidget->GetDataAcc()) { |
430 for (int i = 0, sz = pWidgetAcc->CountSelectedItems(); i < sz; i++) { | 425 for (int i = 0, sz = pWidgetAcc->CountSelectedItems(); i < sz; i++) { |
431 int nIndex = pWidgetAcc->GetSelectedItem(i); | 426 int nIndex = pWidgetAcc->GetSelectedItem(i); |
432 | 427 |
433 if (nIndex > -1 && nIndex < pFormField->CountOptions()) { | 428 if (nIndex > -1 && nIndex < pFormField->CountOptions()) { |
434 pFormField->SetItemSelection(nIndex, TRUE, TRUE); | 429 pFormField->SetItemSelection(nIndex, TRUE, TRUE); |
435 } | 430 } |
436 } | 431 } |
437 | 432 |
438 CFX_WideString sValue; | 433 CFX_WideString sValue; |
439 pWidgetAcc->GetValue(sValue, XFA_VALUEPICTURE_Display); | 434 pWidgetAcc->GetValue(sValue, XFA_VALUEPICTURE_Display); |
440 pFormField->SetValue(sValue, TRUE); | 435 pFormField->SetValue(sValue, TRUE); |
441 } | 436 } |
442 } break; | 437 break; |
| 438 } |
443 } | 439 } |
444 } | 440 } |
445 | 441 |
446 void CPDFSDK_Widget::SynchronizeXFAItems(CXFA_FFDocView* pXFADocView, | 442 void CPDFSDK_Widget::SynchronizeXFAItems(CXFA_FFDocView* pXFADocView, |
447 CXFA_FFWidget* hWidget, | 443 CXFA_FFWidget* hWidget, |
448 CPDF_FormField* pFormField, | 444 CPDF_FormField* pFormField, |
449 CPDF_FormControl* pFormControl) { | 445 CPDF_FormControl* pFormControl) { |
450 ASSERT(hWidget); | 446 ASSERT(hWidget); |
451 | 447 |
452 switch (pFormField->GetFieldType()) { | 448 switch (pFormField->GetFieldType()) { |
453 case FIELDTYPE_LISTBOX: { | 449 case FIELDTYPE_LISTBOX: { |
454 pFormField->ClearSelection(FALSE); | 450 pFormField->ClearSelection(FALSE); |
455 pFormField->ClearOptions(TRUE); | 451 pFormField->ClearOptions(TRUE); |
456 | 452 |
457 if (CXFA_WidgetAcc* pWidgetAcc = hWidget->GetDataAcc()) { | 453 if (CXFA_WidgetAcc* pWidgetAcc = hWidget->GetDataAcc()) { |
458 for (int i = 0, sz = pWidgetAcc->CountChoiceListItems(); i < sz; i++) { | 454 for (int i = 0, sz = pWidgetAcc->CountChoiceListItems(); i < sz; i++) { |
459 CFX_WideString swText; | 455 CFX_WideString swText; |
460 pWidgetAcc->GetChoiceListItem(swText, i); | 456 pWidgetAcc->GetChoiceListItem(swText, i); |
461 | 457 |
462 pFormField->InsertOption(swText, i, TRUE); | 458 pFormField->InsertOption(swText, i, TRUE); |
463 } | 459 } |
464 } | 460 } |
465 } break; | 461 break; |
| 462 } |
466 case FIELDTYPE_COMBOBOX: { | 463 case FIELDTYPE_COMBOBOX: { |
467 pFormField->ClearSelection(FALSE); | 464 pFormField->ClearSelection(FALSE); |
468 pFormField->ClearOptions(FALSE); | 465 pFormField->ClearOptions(FALSE); |
469 | 466 |
470 if (CXFA_WidgetAcc* pWidgetAcc = hWidget->GetDataAcc()) { | 467 if (CXFA_WidgetAcc* pWidgetAcc = hWidget->GetDataAcc()) { |
471 for (int i = 0, sz = pWidgetAcc->CountChoiceListItems(); i < sz; i++) { | 468 for (int i = 0, sz = pWidgetAcc->CountChoiceListItems(); i < sz; i++) { |
472 CFX_WideString swText; | 469 CFX_WideString swText; |
473 pWidgetAcc->GetChoiceListItem(swText, i); | 470 pWidgetAcc->GetChoiceListItem(swText, i); |
474 | 471 |
475 pFormField->InsertOption(swText, i, FALSE); | 472 pFormField->InsertOption(swText, i, FALSE); |
476 } | 473 } |
477 } | 474 } |
478 | 475 |
479 pFormField->SetValue(L"", TRUE); | 476 pFormField->SetValue(L"", TRUE); |
480 } break; | 477 break; |
| 478 } |
481 } | 479 } |
482 } | 480 } |
483 #endif // PDF_ENABLE_XFA | 481 #endif // PDF_ENABLE_XFA |
484 | 482 |
485 FX_BOOL CPDFSDK_Widget::IsWidgetAppearanceValid( | 483 FX_BOOL CPDFSDK_Widget::IsWidgetAppearanceValid( |
486 CPDF_Annot::AppearanceMode mode) { | 484 CPDF_Annot::AppearanceMode mode) { |
487 CPDF_Dictionary* pAP = m_pAnnot->GetAnnotDict()->GetDictBy("AP"); | 485 CPDF_Dictionary* pAP = m_pAnnot->GetAnnotDict()->GetDictBy("AP"); |
488 if (!pAP) | 486 if (!pAP) |
489 return FALSE; | 487 return FALSE; |
490 | 488 |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
595 CPDF_FormControl* pFormCtrl = GetFormControl(); | 593 CPDF_FormControl* pFormCtrl = GetFormControl(); |
596 int iColorType = 0; | 594 int iColorType = 0; |
597 color = FX_ARGBTOCOLORREF(pFormCtrl->GetBorderColor(iColorType)); | 595 color = FX_ARGBTOCOLORREF(pFormCtrl->GetBorderColor(iColorType)); |
598 | 596 |
599 return iColorType != COLORTYPE_TRANSPARENT; | 597 return iColorType != COLORTYPE_TRANSPARENT; |
600 } | 598 } |
601 | 599 |
602 FX_BOOL CPDFSDK_Widget::GetTextColor(FX_COLORREF& color) const { | 600 FX_BOOL CPDFSDK_Widget::GetTextColor(FX_COLORREF& color) const { |
603 CPDF_FormControl* pFormCtrl = GetFormControl(); | 601 CPDF_FormControl* pFormCtrl = GetFormControl(); |
604 CPDF_DefaultAppearance da = pFormCtrl->GetDefaultAppearance(); | 602 CPDF_DefaultAppearance da = pFormCtrl->GetDefaultAppearance(); |
605 if (da.HasColor()) { | 603 if (!da.HasColor()) |
606 FX_ARGB argb; | 604 return FALSE; |
607 int iColorType = COLORTYPE_TRANSPARENT; | |
608 da.GetColor(argb, iColorType); | |
609 color = FX_ARGBTOCOLORREF(argb); | |
610 | 605 |
611 return iColorType != COLORTYPE_TRANSPARENT; | 606 FX_ARGB argb; |
612 } | 607 int iColorType = COLORTYPE_TRANSPARENT; |
| 608 da.GetColor(argb, iColorType); |
| 609 color = FX_ARGBTOCOLORREF(argb); |
613 | 610 |
614 return FALSE; | 611 return iColorType != COLORTYPE_TRANSPARENT; |
615 } | 612 } |
616 | 613 |
617 FX_FLOAT CPDFSDK_Widget::GetFontSize() const { | 614 FX_FLOAT CPDFSDK_Widget::GetFontSize() const { |
618 CPDF_FormControl* pFormCtrl = GetFormControl(); | 615 CPDF_FormControl* pFormCtrl = GetFormControl(); |
619 CPDF_DefaultAppearance pDa = pFormCtrl->GetDefaultAppearance(); | 616 CPDF_DefaultAppearance pDa = pFormCtrl->GetDefaultAppearance(); |
620 CFX_ByteString csFont = ""; | 617 CFX_ByteString csFont = ""; |
621 FX_FLOAT fFontSize = 0.0f; | 618 FX_FLOAT fFontSize = 0.0f; |
622 pDa.GetFont(csFont, fFontSize); | 619 pDa.GetFont(csFont, fFontSize); |
623 | 620 |
624 return fFontSize; | 621 return fFontSize; |
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
768 } | 765 } |
769 | 766 |
770 #ifdef PDF_ENABLE_XFA | 767 #ifdef PDF_ENABLE_XFA |
771 void CPDFSDK_Widget::ResetAppearance(FX_BOOL bValueChanged) { | 768 void CPDFSDK_Widget::ResetAppearance(FX_BOOL bValueChanged) { |
772 switch (GetFieldType()) { | 769 switch (GetFieldType()) { |
773 case FIELDTYPE_TEXTFIELD: | 770 case FIELDTYPE_TEXTFIELD: |
774 case FIELDTYPE_COMBOBOX: { | 771 case FIELDTYPE_COMBOBOX: { |
775 FX_BOOL bFormated = FALSE; | 772 FX_BOOL bFormated = FALSE; |
776 CFX_WideString sValue = OnFormat(bFormated); | 773 CFX_WideString sValue = OnFormat(bFormated); |
777 ResetAppearance(bFormated ? sValue.c_str() : nullptr, TRUE); | 774 ResetAppearance(bFormated ? sValue.c_str() : nullptr, TRUE); |
778 } break; | 775 break; |
| 776 } |
779 default: | 777 default: |
780 ResetAppearance(nullptr, FALSE); | 778 ResetAppearance(nullptr, FALSE); |
781 break; | 779 break; |
782 } | 780 } |
783 } | 781 } |
784 #endif // PDF_ENABLE_XFA | 782 #endif // PDF_ENABLE_XFA |
785 | 783 |
786 void CPDFSDK_Widget::ResetAppearance(const FX_WCHAR* sValue, | 784 void CPDFSDK_Widget::ResetAppearance(const FX_WCHAR* sValue, |
787 FX_BOOL bValueChanged) { | 785 FX_BOOL bValueChanged) { |
788 SetAppModified(); | 786 SetAppModified(); |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
860 | 858 |
861 void CPDFSDK_Widget::UpdateField() { | 859 void CPDFSDK_Widget::UpdateField() { |
862 CPDF_FormField* pFormField = GetFormField(); | 860 CPDF_FormField* pFormField = GetFormField(); |
863 ASSERT(pFormField); | 861 ASSERT(pFormField); |
864 m_pInterForm->UpdateField(pFormField); | 862 m_pInterForm->UpdateField(pFormField); |
865 } | 863 } |
866 | 864 |
867 void CPDFSDK_Widget::DrawShadow(CFX_RenderDevice* pDevice, | 865 void CPDFSDK_Widget::DrawShadow(CFX_RenderDevice* pDevice, |
868 CPDFSDK_PageView* pPageView) { | 866 CPDFSDK_PageView* pPageView) { |
869 int nFieldType = GetFieldType(); | 867 int nFieldType = GetFieldType(); |
870 if (m_pInterForm->IsNeedHighLight(nFieldType)) { | 868 if (!m_pInterForm->IsNeedHighLight(nFieldType)) |
871 CFX_FloatRect rc = GetRect(); | 869 return; |
872 FX_COLORREF color = m_pInterForm->GetHighlightColor(nFieldType); | |
873 uint8_t alpha = m_pInterForm->GetHighlightAlpha(); | |
874 | 870 |
875 CFX_FloatRect rcDevice; | 871 CFX_FloatRect rc = GetRect(); |
876 ASSERT(m_pInterForm->GetDocument()); | 872 FX_COLORREF color = m_pInterForm->GetHighlightColor(nFieldType); |
877 CPDFDoc_Environment* pEnv = m_pInterForm->GetDocument()->GetEnv(); | 873 uint8_t alpha = m_pInterForm->GetHighlightAlpha(); |
878 if (!pEnv) | |
879 return; | |
880 CFX_Matrix page2device; | |
881 pPageView->GetCurrentMatrix(page2device); | |
882 page2device.Transform(((FX_FLOAT)rc.left), ((FX_FLOAT)rc.bottom), | |
883 rcDevice.left, rcDevice.bottom); | |
884 page2device.Transform(((FX_FLOAT)rc.right), ((FX_FLOAT)rc.top), | |
885 rcDevice.right, rcDevice.top); | |
886 | 874 |
887 rcDevice.Normalize(); | 875 CFX_FloatRect rcDevice; |
| 876 ASSERT(m_pInterForm->GetDocument()); |
| 877 CPDFDoc_Environment* pEnv = m_pInterForm->GetDocument()->GetEnv(); |
| 878 if (!pEnv) |
| 879 return; |
| 880 CFX_Matrix page2device; |
| 881 pPageView->GetCurrentMatrix(page2device); |
| 882 page2device.Transform(((FX_FLOAT)rc.left), ((FX_FLOAT)rc.bottom), |
| 883 rcDevice.left, rcDevice.bottom); |
| 884 page2device.Transform(((FX_FLOAT)rc.right), ((FX_FLOAT)rc.top), |
| 885 rcDevice.right, rcDevice.top); |
888 | 886 |
889 FX_ARGB argb = ArgbEncode((int)alpha, color); | 887 rcDevice.Normalize(); |
890 FX_RECT rcDev((int)rcDevice.left, (int)rcDevice.top, (int)rcDevice.right, | 888 |
891 (int)rcDevice.bottom); | 889 FX_ARGB argb = ArgbEncode((int)alpha, color); |
892 pDevice->FillRect(&rcDev, argb); | 890 FX_RECT rcDev((int)rcDevice.left, (int)rcDevice.top, (int)rcDevice.right, |
893 } | 891 (int)rcDevice.bottom); |
| 892 pDevice->FillRect(&rcDev, argb); |
894 } | 893 } |
895 | 894 |
896 void CPDFSDK_Widget::ResetAppearance_PushButton() { | 895 void CPDFSDK_Widget::ResetAppearance_PushButton() { |
897 CPDF_FormControl* pControl = GetFormControl(); | 896 CPDF_FormControl* pControl = GetFormControl(); |
898 CFX_FloatRect rcWindow = GetRotatedRect(); | 897 CFX_FloatRect rcWindow = GetRotatedRect(); |
899 int32_t nLayout = 0; | 898 int32_t nLayout = 0; |
900 switch (pControl->GetTextPosition()) { | 899 switch (pControl->GetTextPosition()) { |
901 case TEXTPOS_ICON: | 900 case TEXTPOS_ICON: |
902 nLayout = PPBL_ICON; | 901 nLayout = PPBL_ICON; |
903 break; | 902 break; |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
969 da.GetColor(iColorType, fc); | 968 da.GetColor(iColorType, fc); |
970 crText = CPWL_Color(iColorType, fc[0], fc[1], fc[2], fc[3]); | 969 crText = CPWL_Color(iColorType, fc[0], fc[1], fc[2], fc[3]); |
971 } | 970 } |
972 | 971 |
973 if (da.HasFont()) | 972 if (da.HasFont()) |
974 da.GetFont(csNameTag, fFontSize); | 973 da.GetFont(csNameTag, fFontSize); |
975 | 974 |
976 CFX_WideString csWCaption; | 975 CFX_WideString csWCaption; |
977 CFX_WideString csNormalCaption, csRolloverCaption, csDownCaption; | 976 CFX_WideString csNormalCaption, csRolloverCaption, csDownCaption; |
978 | 977 |
979 if (pControl->HasMKEntry("CA")) { | 978 if (pControl->HasMKEntry("CA")) |
980 csNormalCaption = pControl->GetNormalCaption(); | 979 csNormalCaption = pControl->GetNormalCaption(); |
981 } | 980 |
982 if (pControl->HasMKEntry("RC")) { | 981 if (pControl->HasMKEntry("RC")) |
983 csRolloverCaption = pControl->GetRolloverCaption(); | 982 csRolloverCaption = pControl->GetRolloverCaption(); |
984 } | 983 |
985 if (pControl->HasMKEntry("AC")) { | 984 if (pControl->HasMKEntry("AC")) |
986 csDownCaption = pControl->GetDownCaption(); | 985 csDownCaption = pControl->GetDownCaption(); |
987 } | |
988 | 986 |
989 CPDF_Stream* pNormalIcon = nullptr; | 987 CPDF_Stream* pNormalIcon = nullptr; |
990 CPDF_Stream* pRolloverIcon = nullptr; | 988 CPDF_Stream* pRolloverIcon = nullptr; |
991 CPDF_Stream* pDownIcon = nullptr; | 989 CPDF_Stream* pDownIcon = nullptr; |
992 | 990 |
993 if (pControl->HasMKEntry("I")) { | 991 if (pControl->HasMKEntry("I")) |
994 pNormalIcon = pControl->GetNormalIcon(); | 992 pNormalIcon = pControl->GetNormalIcon(); |
995 } | 993 |
996 if (pControl->HasMKEntry("RI")) { | 994 if (pControl->HasMKEntry("RI")) |
997 pRolloverIcon = pControl->GetRolloverIcon(); | 995 pRolloverIcon = pControl->GetRolloverIcon(); |
998 } | 996 |
999 if (pControl->HasMKEntry("IX")) { | 997 if (pControl->HasMKEntry("IX")) |
1000 pDownIcon = pControl->GetDownIcon(); | 998 pDownIcon = pControl->GetDownIcon(); |
1001 } | |
1002 | 999 |
1003 if (pNormalIcon) { | 1000 if (pNormalIcon) { |
1004 if (CPDF_Dictionary* pImageDict = pNormalIcon->GetDict()) { | 1001 if (CPDF_Dictionary* pImageDict = pNormalIcon->GetDict()) { |
1005 if (pImageDict->GetStringBy("Name").IsEmpty()) | 1002 if (pImageDict->GetStringBy("Name").IsEmpty()) |
1006 pImageDict->SetAtString("Name", "ImgA"); | 1003 pImageDict->SetAtString("Name", "ImgA"); |
1007 } | 1004 } |
1008 } | 1005 } |
1009 | 1006 |
1010 if (pRolloverIcon) { | 1007 if (pRolloverIcon) { |
1011 if (CPDF_Dictionary* pImageDict = pRolloverIcon->GetDict()) { | 1008 if (CPDF_Dictionary* pImageDict = pRolloverIcon->GetDict()) { |
(...skipping 718 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1730 case 270: | 1727 case 270: |
1731 rcPDFWindow = CFX_FloatRect(0, 0, fHeight, fWidth); | 1728 rcPDFWindow = CFX_FloatRect(0, 0, fHeight, fWidth); |
1732 break; | 1729 break; |
1733 } | 1730 } |
1734 | 1731 |
1735 return rcPDFWindow; | 1732 return rcPDFWindow; |
1736 } | 1733 } |
1737 | 1734 |
1738 CFX_ByteString CPDFSDK_Widget::GetBackgroundAppStream() const { | 1735 CFX_ByteString CPDFSDK_Widget::GetBackgroundAppStream() const { |
1739 CPWL_Color crBackground = GetFillPWLColor(); | 1736 CPWL_Color crBackground = GetFillPWLColor(); |
1740 if (crBackground.nColorType != COLORTYPE_TRANSPARENT) { | 1737 if (crBackground.nColorType != COLORTYPE_TRANSPARENT) |
1741 return CPWL_Utils::GetRectFillAppStream(GetRotatedRect(), crBackground); | 1738 return CPWL_Utils::GetRectFillAppStream(GetRotatedRect(), crBackground); |
1742 } | 1739 |
1743 return ""; | 1740 return ""; |
1744 } | 1741 } |
1745 | 1742 |
1746 CFX_ByteString CPDFSDK_Widget::GetBorderAppStream() const { | 1743 CFX_ByteString CPDFSDK_Widget::GetBorderAppStream() const { |
1747 CFX_FloatRect rcWindow = GetRotatedRect(); | 1744 CFX_FloatRect rcWindow = GetRotatedRect(); |
1748 CPWL_Color crBorder = GetBorderPWLColor(); | 1745 CPWL_Color crBorder = GetBorderPWLColor(); |
1749 CPWL_Color crBackground = GetFillPWLColor(); | 1746 CPWL_Color crBackground = GetFillPWLColor(); |
1750 CPWL_Color crLeftTop, crRightBottom; | 1747 CPWL_Color crLeftTop, crRightBottom; |
1751 | 1748 |
1752 FX_FLOAT fBorderWidth = (FX_FLOAT)GetBorderWidth(); | 1749 FX_FLOAT fBorderWidth = (FX_FLOAT)GetBorderWidth(); |
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1905 param.m_wsNewText.Delete(data.nSelStart, | 1902 param.m_wsNewText.Delete(data.nSelStart, |
1906 data.nSelEnd - data.nSelStart); | 1903 data.nSelEnd - data.nSelStart); |
1907 for (int i = data.sChange.GetLength() - 1; i >= 0; i--) | 1904 for (int i = data.sChange.GetLength() - 1; i >= 0; i--) |
1908 param.m_wsNewText.Insert(data.nSelStart, data.sChange[i]); | 1905 param.m_wsNewText.Insert(data.nSelStart, data.sChange[i]); |
1909 param.m_wsPrevText = data.sValue; | 1906 param.m_wsPrevText = data.sValue; |
1910 | 1907 |
1911 CXFA_WidgetAcc* pAcc = hWidget->GetDataAcc(); | 1908 CXFA_WidgetAcc* pAcc = hWidget->GetDataAcc(); |
1912 param.m_pTarget = pAcc; | 1909 param.m_pTarget = pAcc; |
1913 int32_t nRet = pXFAWidgetHandler->ProcessEvent(pAcc, ¶m); | 1910 int32_t nRet = pXFAWidgetHandler->ProcessEvent(pAcc, ¶m); |
1914 | 1911 |
1915 if (CXFA_FFDocView* pDocView = pDoc->GetXFADocView()) { | 1912 if (CXFA_FFDocView* pDocView = pDoc->GetXFADocView()) |
1916 pDocView->UpdateDocView(); | 1913 pDocView->UpdateDocView(); |
1917 } | |
1918 | 1914 |
1919 if (nRet == XFA_EVENTERROR_Success) | 1915 if (nRet == XFA_EVENTERROR_Success) |
1920 return TRUE; | 1916 return TRUE; |
1921 } | 1917 } |
1922 } | 1918 } |
1923 } | 1919 } |
1924 #endif // PDF_ENABLE_XFA | 1920 #endif // PDF_ENABLE_XFA |
1925 | 1921 |
1926 CPDF_Action action = GetAAction(type); | 1922 CPDF_Action action = GetAAction(type); |
1927 if (action.GetDict() && action.GetType() != CPDF_Action::Unknown) { | 1923 if (action.GetDict() && action.GetType() != CPDF_Action::Unknown) { |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1972 } | 1968 } |
1973 | 1969 |
1974 int32_t CPDFSDK_Widget::GetValueAge() const { | 1970 int32_t CPDFSDK_Widget::GetValueAge() const { |
1975 return m_nValueAge; | 1971 return m_nValueAge; |
1976 } | 1972 } |
1977 | 1973 |
1978 FX_BOOL CPDFSDK_Widget::HitTest(FX_FLOAT pageX, FX_FLOAT pageY) { | 1974 FX_BOOL CPDFSDK_Widget::HitTest(FX_FLOAT pageX, FX_FLOAT pageY) { |
1979 CPDF_Annot* pAnnot = GetPDFAnnot(); | 1975 CPDF_Annot* pAnnot = GetPDFAnnot(); |
1980 CFX_FloatRect annotRect; | 1976 CFX_FloatRect annotRect; |
1981 pAnnot->GetRect(annotRect); | 1977 pAnnot->GetRect(annotRect); |
1982 if (annotRect.Contains(pageX, pageY)) { | 1978 if (!annotRect.Contains(pageX, pageY)) |
1983 if (!IsVisible()) | |
1984 return FALSE; | |
1985 | |
1986 int nFieldFlags = GetFieldFlags(); | |
1987 if ((nFieldFlags & FIELDFLAG_READONLY) == FIELDFLAG_READONLY) | |
1988 return FALSE; | |
1989 | |
1990 return TRUE; | |
1991 } | |
1992 return FALSE; | |
1993 } | |
1994 | |
1995 #ifdef PDF_ENABLE_XFA | |
1996 CPDFSDK_XFAWidget::CPDFSDK_XFAWidget(CXFA_FFWidget* pAnnot, | |
1997 CPDFSDK_PageView* pPageView, | |
1998 CPDFSDK_InterForm* pInterForm) | |
1999 : CPDFSDK_Annot(pPageView), | |
2000 m_pInterForm(pInterForm), | |
2001 m_hXFAWidget(pAnnot) {} | |
2002 | |
2003 FX_BOOL CPDFSDK_XFAWidget::IsXFAField() { | |
2004 return TRUE; | |
2005 } | |
2006 | |
2007 CXFA_FFWidget* CPDFSDK_XFAWidget::GetXFAWidget() const { | |
2008 return m_hXFAWidget; | |
2009 } | |
2010 | |
2011 CFX_ByteString CPDFSDK_XFAWidget::GetType() const { | |
2012 return FSDK_XFAWIDGET_TYPENAME; | |
2013 } | |
2014 | |
2015 CFX_ByteString CPDFSDK_XFAWidget::GetSubType() const { | |
2016 return ""; | |
2017 } | |
2018 | |
2019 CFX_FloatRect CPDFSDK_XFAWidget::GetRect() const { | |
2020 CFX_RectF rcBBox; | |
2021 GetXFAWidget()->GetRect(rcBBox); | |
2022 return CFX_FloatRect(rcBBox.left, rcBBox.top, rcBBox.left + rcBBox.width, | |
2023 rcBBox.top + rcBBox.height); | |
2024 } | |
2025 #endif // PDF_ENABLE_XFA | |
2026 | |
2027 CPDFSDK_InterForm::CPDFSDK_InterForm(CPDFSDK_Document* pDocument) | |
2028 : m_pDocument(pDocument), | |
2029 m_pInterForm(new CPDF_InterForm(m_pDocument->GetPDFDocument())), | |
2030 #ifdef PDF_ENABLE_XFA | |
2031 m_bXfaCalculate(TRUE), | |
2032 m_bXfaValidationsEnabled(TRUE), | |
2033 #endif // PDF_ENABLE_XFA | |
2034 m_bCalculate(TRUE), | |
2035 m_bBusy(FALSE) { | |
2036 m_pInterForm->SetFormNotify(this); | |
2037 for (int i = 0; i < kNumFieldTypes; ++i) | |
2038 m_bNeedHightlight[i] = FALSE; | |
2039 m_iHighlightAlpha = 0; | |
2040 } | |
2041 | |
2042 CPDFSDK_InterForm::~CPDFSDK_InterForm() { | |
2043 m_Map.clear(); | |
2044 #ifdef PDF_ENABLE_XFA | |
2045 m_XFAMap.clear(); | |
2046 #endif // PDF_ENABLE_XFA | |
2047 } | |
2048 | |
2049 FX_BOOL CPDFSDK_InterForm::HighlightWidgets() { | |
2050 return FALSE; | |
2051 } | |
2052 | |
2053 CPDFSDK_Widget* CPDFSDK_InterForm::GetSibling(CPDFSDK_Widget* pWidget, | |
2054 FX_BOOL bNext) const { | |
2055 std::unique_ptr<CBA_AnnotIterator> pIterator( | |
2056 new CBA_AnnotIterator(pWidget->GetPageView(), "Widget", "")); | |
2057 | |
2058 if (bNext) { | |
2059 return (CPDFSDK_Widget*)pIterator->GetNextAnnot(pWidget); | |
2060 } | |
2061 return (CPDFSDK_Widget*)pIterator->GetPrevAnnot(pWidget); | |
2062 } | |
2063 | |
2064 CPDFSDK_Widget* CPDFSDK_InterForm::GetWidget(CPDF_FormControl* pControl, | |
2065 bool createIfNeeded) const { | |
2066 if (!pControl || !m_pInterForm) | |
2067 return nullptr; | |
2068 | |
2069 CPDFSDK_Widget* pWidget = nullptr; | |
2070 const auto it = m_Map.find(pControl); | |
2071 if (it != m_Map.end()) | |
2072 pWidget = it->second; | |
2073 if (pWidget) | |
2074 return pWidget; | |
2075 if (!createIfNeeded) | |
2076 return nullptr; | |
2077 | |
2078 CPDF_Dictionary* pControlDict = pControl->GetWidget(); | |
2079 CPDF_Document* pDocument = m_pDocument->GetPDFDocument(); | |
2080 CPDFSDK_PageView* pPage = nullptr; | |
2081 | |
2082 if (CPDF_Dictionary* pPageDict = pControlDict->GetDictBy("P")) { | |
2083 int nPageIndex = pDocument->GetPageIndex(pPageDict->GetObjNum()); | |
2084 if (nPageIndex >= 0) { | |
2085 pPage = m_pDocument->GetPageView(nPageIndex); | |
2086 } | |
2087 } | |
2088 | |
2089 if (!pPage) { | |
2090 int nPageIndex = GetPageIndexByAnnotDict(pDocument, pControlDict); | |
2091 if (nPageIndex >= 0) { | |
2092 pPage = m_pDocument->GetPageView(nPageIndex); | |
2093 } | |
2094 } | |
2095 | |
2096 if (!pPage) | |
2097 return nullptr; | |
2098 | |
2099 return (CPDFSDK_Widget*)pPage->GetAnnotByDict(pControlDict); | |
2100 } | |
2101 | |
2102 void CPDFSDK_InterForm::GetWidgets( | |
2103 const CFX_WideString& sFieldName, | |
2104 std::vector<CPDFSDK_Widget*>* widgets) const { | |
2105 for (int i = 0, sz = m_pInterForm->CountFields(sFieldName); i < sz; ++i) { | |
2106 CPDF_FormField* pFormField = m_pInterForm->GetField(i, sFieldName); | |
2107 ASSERT(pFormField); | |
2108 GetWidgets(pFormField, widgets); | |
2109 } | |
2110 } | |
2111 | |
2112 void CPDFSDK_InterForm::GetWidgets( | |
2113 CPDF_FormField* pField, | |
2114 std::vector<CPDFSDK_Widget*>* widgets) const { | |
2115 for (int i = 0, sz = pField->CountControls(); i < sz; ++i) { | |
2116 CPDF_FormControl* pFormCtrl = pField->GetControl(i); | |
2117 ASSERT(pFormCtrl); | |
2118 CPDFSDK_Widget* pWidget = GetWidget(pFormCtrl, true); | |
2119 if (pWidget) | |
2120 widgets->push_back(pWidget); | |
2121 } | |
2122 } | |
2123 | |
2124 int CPDFSDK_InterForm::GetPageIndexByAnnotDict( | |
2125 CPDF_Document* pDocument, | |
2126 CPDF_Dictionary* pAnnotDict) const { | |
2127 ASSERT(pAnnotDict); | |
2128 | |
2129 for (int i = 0, sz = pDocument->GetPageCount(); i < sz; i++) { | |
2130 if (CPDF_Dictionary* pPageDict = pDocument->GetPage(i)) { | |
2131 if (CPDF_Array* pAnnots = pPageDict->GetArrayBy("Annots")) { | |
2132 for (int j = 0, jsz = pAnnots->GetCount(); j < jsz; j++) { | |
2133 CPDF_Object* pDict = pAnnots->GetDirectObjectAt(j); | |
2134 if (pAnnotDict == pDict) { | |
2135 return i; | |
2136 } | |
2137 } | |
2138 } | |
2139 } | |
2140 } | |
2141 | |
2142 return -1; | |
2143 } | |
2144 | |
2145 void CPDFSDK_InterForm::AddMap(CPDF_FormControl* pControl, | |
2146 CPDFSDK_Widget* pWidget) { | |
2147 m_Map[pControl] = pWidget; | |
2148 } | |
2149 | |
2150 void CPDFSDK_InterForm::RemoveMap(CPDF_FormControl* pControl) { | |
2151 m_Map.erase(pControl); | |
2152 } | |
2153 | |
2154 void CPDFSDK_InterForm::EnableCalculate(FX_BOOL bEnabled) { | |
2155 m_bCalculate = bEnabled; | |
2156 } | |
2157 | |
2158 FX_BOOL CPDFSDK_InterForm::IsCalculateEnabled() const { | |
2159 return m_bCalculate; | |
2160 } | |
2161 | |
2162 #ifdef PDF_ENABLE_XFA | |
2163 void CPDFSDK_InterForm::AddXFAMap(CXFA_FFWidget* hWidget, | |
2164 CPDFSDK_XFAWidget* pWidget) { | |
2165 ASSERT(hWidget); | |
2166 m_XFAMap[hWidget] = pWidget; | |
2167 } | |
2168 | |
2169 void CPDFSDK_InterForm::RemoveXFAMap(CXFA_FFWidget* hWidget) { | |
2170 ASSERT(hWidget); | |
2171 m_XFAMap.erase(hWidget); | |
2172 } | |
2173 | |
2174 CPDFSDK_XFAWidget* CPDFSDK_InterForm::GetXFAWidget(CXFA_FFWidget* hWidget) { | |
2175 ASSERT(hWidget); | |
2176 auto it = m_XFAMap.find(hWidget); | |
2177 return it != m_XFAMap.end() ? it->second : nullptr; | |
2178 } | |
2179 | |
2180 void CPDFSDK_InterForm::XfaEnableCalculate(FX_BOOL bEnabled) { | |
2181 m_bXfaCalculate = bEnabled; | |
2182 } | |
2183 FX_BOOL CPDFSDK_InterForm::IsXfaCalculateEnabled() const { | |
2184 return m_bXfaCalculate; | |
2185 } | |
2186 | |
2187 FX_BOOL CPDFSDK_InterForm::IsXfaValidationsEnabled() { | |
2188 return m_bXfaValidationsEnabled; | |
2189 } | |
2190 void CPDFSDK_InterForm::XfaSetValidationsEnabled(FX_BOOL bEnabled) { | |
2191 m_bXfaValidationsEnabled = bEnabled; | |
2192 } | |
2193 #endif // PDF_ENABLE_XFA | |
2194 | |
2195 void CPDFSDK_InterForm::OnCalculate(CPDF_FormField* pFormField) { | |
2196 CPDFDoc_Environment* pEnv = m_pDocument->GetEnv(); | |
2197 ASSERT(pEnv); | |
2198 if (!pEnv->IsJSInitiated()) | |
2199 return; | |
2200 | |
2201 if (m_bBusy) | |
2202 return; | |
2203 | |
2204 m_bBusy = TRUE; | |
2205 | |
2206 if (IsCalculateEnabled()) { | |
2207 IJS_Runtime* pRuntime = m_pDocument->GetJsRuntime(); | |
2208 pRuntime->SetReaderDocument(m_pDocument); | |
2209 | |
2210 int nSize = m_pInterForm->CountFieldsInCalculationOrder(); | |
2211 for (int i = 0; i < nSize; i++) { | |
2212 if (CPDF_FormField* pField = | |
2213 m_pInterForm->GetFieldInCalculationOrder(i)) { | |
2214 int nType = pField->GetFieldType(); | |
2215 if (nType == FIELDTYPE_COMBOBOX || nType == FIELDTYPE_TEXTFIELD) { | |
2216 CPDF_AAction aAction = pField->GetAdditionalAction(); | |
2217 if (aAction.GetDict() && | |
2218 aAction.ActionExist(CPDF_AAction::Calculate)) { | |
2219 CPDF_Action action = aAction.GetAction(CPDF_AAction::Calculate); | |
2220 if (action.GetDict()) { | |
2221 CFX_WideString csJS = action.GetJavaScript(); | |
2222 if (!csJS.IsEmpty()) { | |
2223 IJS_Context* pContext = pRuntime->NewContext(); | |
2224 CFX_WideString sOldValue = pField->GetValue(); | |
2225 CFX_WideString sValue = sOldValue; | |
2226 FX_BOOL bRC = TRUE; | |
2227 pContext->OnField_Calculate(pFormField, pField, sValue, bRC); | |
2228 | |
2229 CFX_WideString sInfo; | |
2230 FX_BOOL bRet = pContext->RunScript(csJS, &sInfo); | |
2231 pRuntime->ReleaseContext(pContext); | |
2232 | |
2233 if (bRet) { | |
2234 if (bRC) { | |
2235 if (sValue.Compare(sOldValue) != 0) | |
2236 pField->SetValue(sValue, TRUE); | |
2237 } | |
2238 } | |
2239 } | |
2240 } | |
2241 } | |
2242 } | |
2243 } | |
2244 } | |
2245 } | |
2246 | |
2247 m_bBusy = FALSE; | |
2248 } | |
2249 | |
2250 CFX_WideString CPDFSDK_InterForm::OnFormat(CPDF_FormField* pFormField, | |
2251 FX_BOOL& bFormated) { | |
2252 CFX_WideString sValue = pFormField->GetValue(); | |
2253 CPDFDoc_Environment* pEnv = m_pDocument->GetEnv(); | |
2254 ASSERT(pEnv); | |
2255 if (!pEnv->IsJSInitiated()) { | |
2256 bFormated = FALSE; | |
2257 return sValue; | |
2258 } | |
2259 | |
2260 IJS_Runtime* pRuntime = m_pDocument->GetJsRuntime(); | |
2261 pRuntime->SetReaderDocument(m_pDocument); | |
2262 | |
2263 if (pFormField->GetFieldType() == FIELDTYPE_COMBOBOX) { | |
2264 if (pFormField->CountSelectedItems() > 0) { | |
2265 int index = pFormField->GetSelectedIndex(0); | |
2266 if (index >= 0) | |
2267 sValue = pFormField->GetOptionLabel(index); | |
2268 } | |
2269 } | |
2270 | |
2271 bFormated = FALSE; | |
2272 | |
2273 CPDF_AAction aAction = pFormField->GetAdditionalAction(); | |
2274 if (aAction.GetDict() && aAction.ActionExist(CPDF_AAction::Format)) { | |
2275 CPDF_Action action = aAction.GetAction(CPDF_AAction::Format); | |
2276 if (action.GetDict()) { | |
2277 CFX_WideString script = action.GetJavaScript(); | |
2278 if (!script.IsEmpty()) { | |
2279 CFX_WideString Value = sValue; | |
2280 | |
2281 IJS_Context* pContext = pRuntime->NewContext(); | |
2282 pContext->OnField_Format(pFormField, Value, TRUE); | |
2283 CFX_WideString sInfo; | |
2284 FX_BOOL bRet = pContext->RunScript(script, &sInfo); | |
2285 pRuntime->ReleaseContext(pContext); | |
2286 | |
2287 if (bRet) { | |
2288 sValue = Value; | |
2289 bFormated = TRUE; | |
2290 } | |
2291 } | |
2292 } | |
2293 } | |
2294 | |
2295 return sValue; | |
2296 } | |
2297 | |
2298 void CPDFSDK_InterForm::ResetFieldAppearance(CPDF_FormField* pFormField, | |
2299 const FX_WCHAR* sValue, | |
2300 FX_BOOL bValueChanged) { | |
2301 for (int i = 0, sz = pFormField->CountControls(); i < sz; i++) { | |
2302 CPDF_FormControl* pFormCtrl = pFormField->GetControl(i); | |
2303 ASSERT(pFormCtrl); | |
2304 if (CPDFSDK_Widget* pWidget = GetWidget(pFormCtrl, false)) | |
2305 pWidget->ResetAppearance(sValue, bValueChanged); | |
2306 } | |
2307 } | |
2308 | |
2309 void CPDFSDK_InterForm::UpdateField(CPDF_FormField* pFormField) { | |
2310 for (int i = 0, sz = pFormField->CountControls(); i < sz; i++) { | |
2311 CPDF_FormControl* pFormCtrl = pFormField->GetControl(i); | |
2312 ASSERT(pFormCtrl); | |
2313 | |
2314 if (CPDFSDK_Widget* pWidget = GetWidget(pFormCtrl, false)) { | |
2315 CPDFDoc_Environment* pEnv = m_pDocument->GetEnv(); | |
2316 CFFL_IFormFiller* pIFormFiller = pEnv->GetIFormFiller(); | |
2317 UnderlyingPageType* pPage = pWidget->GetUnderlyingPage(); | |
2318 CPDFSDK_PageView* pPageView = m_pDocument->GetPageView(pPage, false); | |
2319 FX_RECT rcBBox = pIFormFiller->GetViewBBox(pPageView, pWidget); | |
2320 | |
2321 pEnv->FFI_Invalidate(pPage, rcBBox.left, rcBBox.top, rcBBox.right, | |
2322 rcBBox.bottom); | |
2323 } | |
2324 } | |
2325 } | |
2326 | |
2327 FX_BOOL CPDFSDK_InterForm::OnKeyStrokeCommit(CPDF_FormField* pFormField, | |
2328 const CFX_WideString& csValue) { | |
2329 CPDF_AAction aAction = pFormField->GetAdditionalAction(); | |
2330 if (!aAction.GetDict() || !aAction.ActionExist(CPDF_AAction::KeyStroke)) | |
2331 return TRUE; | |
2332 | |
2333 CPDF_Action action = aAction.GetAction(CPDF_AAction::KeyStroke); | |
2334 if (!action.GetDict()) | |
2335 return TRUE; | |
2336 | |
2337 CPDFDoc_Environment* pEnv = m_pDocument->GetEnv(); | |
2338 CPDFSDK_ActionHandler* pActionHandler = pEnv->GetActionHander(); | |
2339 PDFSDK_FieldAction fa; | |
2340 fa.bModifier = pEnv->FFI_IsCTRLKeyDown(0); | |
2341 fa.bShift = pEnv->FFI_IsSHIFTKeyDown(0); | |
2342 fa.sValue = csValue; | |
2343 pActionHandler->DoAction_FieldJavaScript(action, CPDF_AAction::KeyStroke, | |
2344 m_pDocument, pFormField, fa); | |
2345 return fa.bRC; | |
2346 } | |
2347 | |
2348 FX_BOOL CPDFSDK_InterForm::OnValidate(CPDF_FormField* pFormField, | |
2349 const CFX_WideString& csValue) { | |
2350 CPDF_AAction aAction = pFormField->GetAdditionalAction(); | |
2351 if (!aAction.GetDict() || !aAction.ActionExist(CPDF_AAction::Validate)) | |
2352 return TRUE; | |
2353 | |
2354 CPDF_Action action = aAction.GetAction(CPDF_AAction::Validate); | |
2355 if (!action.GetDict()) | |
2356 return TRUE; | |
2357 | |
2358 CPDFDoc_Environment* pEnv = m_pDocument->GetEnv(); | |
2359 CPDFSDK_ActionHandler* pActionHandler = pEnv->GetActionHander(); | |
2360 PDFSDK_FieldAction fa; | |
2361 fa.bModifier = pEnv->FFI_IsCTRLKeyDown(0); | |
2362 fa.bShift = pEnv->FFI_IsSHIFTKeyDown(0); | |
2363 fa.sValue = csValue; | |
2364 pActionHandler->DoAction_FieldJavaScript(action, CPDF_AAction::Validate, | |
2365 m_pDocument, pFormField, fa); | |
2366 return fa.bRC; | |
2367 } | |
2368 | |
2369 FX_BOOL CPDFSDK_InterForm::DoAction_Hide(const CPDF_Action& action) { | |
2370 ASSERT(action.GetDict()); | |
2371 | |
2372 CPDF_ActionFields af(&action); | |
2373 std::vector<CPDF_Object*> fieldObjects = af.GetAllFields(); | |
2374 std::vector<CPDF_FormField*> fields = GetFieldFromObjects(fieldObjects); | |
2375 | |
2376 bool bHide = action.GetHideStatus(); | |
2377 FX_BOOL bChanged = FALSE; | |
2378 | |
2379 for (CPDF_FormField* pField : fields) { | |
2380 for (int i = 0, sz = pField->CountControls(); i < sz; ++i) { | |
2381 CPDF_FormControl* pControl = pField->GetControl(i); | |
2382 ASSERT(pControl); | |
2383 | |
2384 if (CPDFSDK_Widget* pWidget = GetWidget(pControl, false)) { | |
2385 uint32_t nFlags = pWidget->GetFlags(); | |
2386 nFlags &= ~ANNOTFLAG_INVISIBLE; | |
2387 nFlags &= ~ANNOTFLAG_NOVIEW; | |
2388 if (bHide) | |
2389 nFlags |= ANNOTFLAG_HIDDEN; | |
2390 else | |
2391 nFlags &= ~ANNOTFLAG_HIDDEN; | |
2392 pWidget->SetFlags(nFlags); | |
2393 pWidget->GetPageView()->UpdateView(pWidget); | |
2394 bChanged = TRUE; | |
2395 } | |
2396 } | |
2397 } | |
2398 | |
2399 return bChanged; | |
2400 } | |
2401 | |
2402 FX_BOOL CPDFSDK_InterForm::DoAction_SubmitForm(const CPDF_Action& action) { | |
2403 CFX_WideString sDestination = action.GetFilePath(); | |
2404 if (sDestination.IsEmpty()) | |
2405 return FALSE; | 1979 return FALSE; |
2406 | 1980 |
2407 CPDF_Dictionary* pActionDict = action.GetDict(); | 1981 if (!IsVisible()) |
2408 if (pActionDict->KeyExist("Fields")) { | |
2409 CPDF_ActionFields af(&action); | |
2410 uint32_t dwFlags = action.GetFlags(); | |
2411 std::vector<CPDF_Object*> fieldObjects = af.GetAllFields(); | |
2412 std::vector<CPDF_FormField*> fields = GetFieldFromObjects(fieldObjects); | |
2413 if (!fields.empty()) { | |
2414 bool bIncludeOrExclude = !(dwFlags & 0x01); | |
2415 if (m_pInterForm->CheckRequiredFields(&fields, bIncludeOrExclude)) | |
2416 return FALSE; | |
2417 | |
2418 return SubmitFields(sDestination, fields, bIncludeOrExclude, false); | |
2419 } | |
2420 } | |
2421 if (m_pInterForm->CheckRequiredFields(nullptr, true)) | |
2422 return FALSE; | 1982 return FALSE; |
2423 | 1983 |
2424 return SubmitForm(sDestination, FALSE); | 1984 if ((GetFieldFlags() & FIELDFLAG_READONLY) == FIELDFLAG_READONLY) |
2425 } | |
2426 | |
2427 FX_BOOL CPDFSDK_InterForm::SubmitFields( | |
2428 const CFX_WideString& csDestination, | |
2429 const std::vector<CPDF_FormField*>& fields, | |
2430 bool bIncludeOrExclude, | |
2431 bool bUrlEncoded) { | |
2432 CPDFDoc_Environment* pEnv = m_pDocument->GetEnv(); | |
2433 | |
2434 CFX_ByteTextBuf textBuf; | |
2435 ExportFieldsToFDFTextBuf(fields, bIncludeOrExclude, textBuf); | |
2436 | |
2437 uint8_t* pBuffer = textBuf.GetBuffer(); | |
2438 FX_STRSIZE nBufSize = textBuf.GetLength(); | |
2439 | |
2440 if (bUrlEncoded && !FDFToURLEncodedData(pBuffer, nBufSize)) | |
2441 return FALSE; | 1985 return FALSE; |
2442 | 1986 |
2443 pEnv->JS_docSubmitForm(pBuffer, nBufSize, csDestination.c_str()); | |
2444 return TRUE; | |
2445 } | |
2446 | |
2447 FX_BOOL CPDFSDK_InterForm::FDFToURLEncodedData(CFX_WideString csFDFFile, | |
2448 CFX_WideString csTxtFile) { | |
2449 return TRUE; | |
2450 } | |
2451 | |
2452 FX_BOOL CPDFSDK_InterForm::FDFToURLEncodedData(uint8_t*& pBuf, | |
2453 FX_STRSIZE& nBufSize) { | |
2454 CFDF_Document* pFDF = CFDF_Document::ParseMemory(pBuf, nBufSize); | |
2455 if (pFDF) { | |
2456 CPDF_Dictionary* pMainDict = pFDF->GetRoot()->GetDictBy("FDF"); | |
2457 if (!pMainDict) | |
2458 return FALSE; | |
2459 | |
2460 // Get fields | |
2461 CPDF_Array* pFields = pMainDict->GetArrayBy("Fields"); | |
2462 if (!pFields) | |
2463 return FALSE; | |
2464 | |
2465 CFX_ByteTextBuf fdfEncodedData; | |
2466 for (uint32_t i = 0; i < pFields->GetCount(); i++) { | |
2467 CPDF_Dictionary* pField = pFields->GetDictAt(i); | |
2468 if (!pField) | |
2469 continue; | |
2470 CFX_WideString name; | |
2471 name = pField->GetUnicodeTextBy("T"); | |
2472 CFX_ByteString name_b = CFX_ByteString::FromUnicode(name); | |
2473 CFX_ByteString csBValue = pField->GetStringBy("V"); | |
2474 CFX_WideString csWValue = PDF_DecodeText(csBValue); | |
2475 CFX_ByteString csValue_b = CFX_ByteString::FromUnicode(csWValue); | |
2476 | |
2477 fdfEncodedData << name_b.GetBuffer(name_b.GetLength()); | |
2478 name_b.ReleaseBuffer(); | |
2479 fdfEncodedData << "="; | |
2480 fdfEncodedData << csValue_b.GetBuffer(csValue_b.GetLength()); | |
2481 csValue_b.ReleaseBuffer(); | |
2482 if (i != pFields->GetCount() - 1) | |
2483 fdfEncodedData << "&"; | |
2484 } | |
2485 | |
2486 nBufSize = fdfEncodedData.GetLength(); | |
2487 pBuf = FX_Alloc(uint8_t, nBufSize); | |
2488 FXSYS_memcpy(pBuf, fdfEncodedData.GetBuffer(), nBufSize); | |
2489 } | |
2490 return TRUE; | |
2491 } | |
2492 | |
2493 FX_BOOL CPDFSDK_InterForm::ExportFieldsToFDFTextBuf( | |
2494 const std::vector<CPDF_FormField*>& fields, | |
2495 bool bIncludeOrExclude, | |
2496 CFX_ByteTextBuf& textBuf) { | |
2497 std::unique_ptr<CFDF_Document> pFDF(m_pInterForm->ExportToFDF( | |
2498 m_pDocument->GetPath().AsStringC(), fields, bIncludeOrExclude)); | |
2499 return pFDF ? pFDF->WriteBuf(textBuf) : FALSE; | |
2500 } | |
2501 | |
2502 #ifdef PDF_ENABLE_XFA | |
2503 void CPDFSDK_InterForm::SynchronizeField(CPDF_FormField* pFormField, | |
2504 FX_BOOL bSynchronizeElse) { | |
2505 for (int i = 0, sz = pFormField->CountControls(); i < sz; i++) { | |
2506 CPDF_FormControl* pFormCtrl = pFormField->GetControl(i); | |
2507 if (CPDFSDK_Widget* pWidget = GetWidget(pFormCtrl, false)) { | |
2508 pWidget->Synchronize(bSynchronizeElse); | |
2509 } | |
2510 } | |
2511 } | |
2512 #endif // PDF_ENABLE_XFA | |
2513 | |
2514 CFX_WideString CPDFSDK_InterForm::GetTemporaryFileName( | |
2515 const CFX_WideString& sFileExt) { | |
2516 CFX_WideString sFileName; | |
2517 return L""; | |
2518 } | |
2519 | |
2520 FX_BOOL CPDFSDK_InterForm::SubmitForm(const CFX_WideString& sDestination, | |
2521 FX_BOOL bUrlEncoded) { | |
2522 if (sDestination.IsEmpty()) | |
2523 return FALSE; | |
2524 | |
2525 if (!m_pDocument || !m_pInterForm) | |
2526 return FALSE; | |
2527 | |
2528 CPDFDoc_Environment* pEnv = m_pDocument->GetEnv(); | |
2529 CFX_WideString wsPDFFilePath = m_pDocument->GetPath(); | |
2530 CFDF_Document* pFDFDoc = m_pInterForm->ExportToFDF(wsPDFFilePath.AsStringC()); | |
2531 if (!pFDFDoc) | |
2532 return FALSE; | |
2533 | |
2534 CFX_ByteTextBuf FdfBuffer; | |
2535 FX_BOOL bRet = pFDFDoc->WriteBuf(FdfBuffer); | |
2536 delete pFDFDoc; | |
2537 if (!bRet) | |
2538 return FALSE; | |
2539 | |
2540 uint8_t* pBuffer = FdfBuffer.GetBuffer(); | |
2541 FX_STRSIZE nBufSize = FdfBuffer.GetLength(); | |
2542 | |
2543 if (bUrlEncoded) { | |
2544 if (!FDFToURLEncodedData(pBuffer, nBufSize)) | |
2545 return FALSE; | |
2546 } | |
2547 | |
2548 pEnv->JS_docSubmitForm(pBuffer, nBufSize, sDestination.c_str()); | |
2549 | |
2550 if (bUrlEncoded) | |
2551 FX_Free(pBuffer); | |
2552 | |
2553 return TRUE; | 1987 return TRUE; |
2554 } | 1988 } |
2555 | |
2556 FX_BOOL CPDFSDK_InterForm::ExportFormToFDFTextBuf(CFX_ByteTextBuf& textBuf) { | |
2557 CFDF_Document* pFDF = | |
2558 m_pInterForm->ExportToFDF(m_pDocument->GetPath().AsStringC()); | |
2559 if (!pFDF) | |
2560 return FALSE; | |
2561 | |
2562 FX_BOOL bRet = pFDF->WriteBuf(textBuf); | |
2563 delete pFDF; | |
2564 | |
2565 return bRet; | |
2566 } | |
2567 | |
2568 FX_BOOL CPDFSDK_InterForm::DoAction_ResetForm(const CPDF_Action& action) { | |
2569 ASSERT(action.GetDict()); | |
2570 | |
2571 CPDF_Dictionary* pActionDict = action.GetDict(); | |
2572 if (!pActionDict->KeyExist("Fields")) | |
2573 return m_pInterForm->ResetForm(true); | |
2574 | |
2575 CPDF_ActionFields af(&action); | |
2576 uint32_t dwFlags = action.GetFlags(); | |
2577 | |
2578 std::vector<CPDF_Object*> fieldObjects = af.GetAllFields(); | |
2579 std::vector<CPDF_FormField*> fields = GetFieldFromObjects(fieldObjects); | |
2580 return m_pInterForm->ResetForm(fields, !(dwFlags & 0x01), true); | |
2581 } | |
2582 | |
2583 FX_BOOL CPDFSDK_InterForm::DoAction_ImportData(const CPDF_Action& action) { | |
2584 return FALSE; | |
2585 } | |
2586 | |
2587 std::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()) { | |
2592 CFX_WideString csName = pObject->GetUnicodeText(); | |
2593 CPDF_FormField* pField = m_pInterForm->GetField(0, csName); | |
2594 if (pField) | |
2595 fields.push_back(pField); | |
2596 } | |
2597 } | |
2598 return fields; | |
2599 } | |
2600 | |
2601 int CPDFSDK_InterForm::BeforeValueChange(CPDF_FormField* pField, | |
2602 const CFX_WideString& csValue) { | |
2603 int nType = pField->GetFieldType(); | |
2604 if (nType != FIELDTYPE_COMBOBOX && nType != FIELDTYPE_TEXTFIELD) | |
2605 return 0; | |
2606 | |
2607 if (!OnKeyStrokeCommit(pField, csValue)) | |
2608 return -1; | |
2609 | |
2610 if (!OnValidate(pField, csValue)) | |
2611 return -1; | |
2612 | |
2613 return 1; | |
2614 } | |
2615 | |
2616 void 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); | |
2627 } | |
2628 } | |
2629 | |
2630 int 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 | |
2644 void CPDFSDK_InterForm::AfterSelectionChange(CPDF_FormField* pField) { | |
2645 if (pField->GetFieldType() == FIELDTYPE_LISTBOX) { | |
2646 OnCalculate(pField); | |
2647 ResetFieldAppearance(pField, nullptr, TRUE); | |
2648 UpdateField(pField); | |
2649 } | |
2650 } | |
2651 | |
2652 void CPDFSDK_InterForm::AfterCheckedStatusChange(CPDF_FormField* pField) { | |
2653 int nType = pField->GetFieldType(); | |
2654 if (nType == FIELDTYPE_CHECKBOX || nType == FIELDTYPE_RADIOBUTTON) { | |
2655 OnCalculate(pField); | |
2656 UpdateField(pField); | |
2657 } | |
2658 } | |
2659 | |
2660 int CPDFSDK_InterForm::BeforeFormReset(CPDF_InterForm* pForm) { | |
2661 return 0; | |
2662 } | |
2663 | |
2664 void CPDFSDK_InterForm::AfterFormReset(CPDF_InterForm* pForm) { | |
2665 OnCalculate(nullptr); | |
2666 } | |
2667 | |
2668 int CPDFSDK_InterForm::BeforeFormImportData(CPDF_InterForm* pForm) { | |
2669 return 0; | |
2670 } | |
2671 | |
2672 void CPDFSDK_InterForm::AfterFormImportData(CPDF_InterForm* pForm) { | |
2673 OnCalculate(nullptr); | |
2674 } | |
2675 | |
2676 FX_BOOL CPDFSDK_InterForm::IsNeedHighLight(int nFieldType) { | |
2677 if (nFieldType < 1 || nFieldType > kNumFieldTypes) | |
2678 return FALSE; | |
2679 return m_bNeedHightlight[nFieldType - 1]; | |
2680 } | |
2681 | |
2682 void CPDFSDK_InterForm::RemoveAllHighLight() { | |
2683 for (int i = 0; i < kNumFieldTypes; ++i) | |
2684 m_bNeedHightlight[i] = FALSE; | |
2685 } | |
2686 | |
2687 void CPDFSDK_InterForm::SetHighlightColor(FX_COLORREF clr, int nFieldType) { | |
2688 if (nFieldType < 0 || nFieldType > kNumFieldTypes) | |
2689 return; | |
2690 switch (nFieldType) { | |
2691 case 0: { | |
2692 for (int i = 0; i < kNumFieldTypes; ++i) { | |
2693 m_aHighlightColor[i] = clr; | |
2694 m_bNeedHightlight[i] = TRUE; | |
2695 } | |
2696 break; | |
2697 } | |
2698 default: { | |
2699 m_aHighlightColor[nFieldType - 1] = clr; | |
2700 m_bNeedHightlight[nFieldType - 1] = TRUE; | |
2701 break; | |
2702 } | |
2703 } | |
2704 } | |
2705 | |
2706 FX_COLORREF CPDFSDK_InterForm::GetHighlightColor(int nFieldType) { | |
2707 if (nFieldType < 0 || nFieldType > kNumFieldTypes) | |
2708 return FXSYS_RGB(255, 255, 255); | |
2709 if (nFieldType == 0) | |
2710 return m_aHighlightColor[0]; | |
2711 return m_aHighlightColor[nFieldType - 1]; | |
2712 } | |
2713 | |
2714 CBA_AnnotIterator::CBA_AnnotIterator(CPDFSDK_PageView* pPageView, | |
2715 const CFX_ByteString& sType, | |
2716 const CFX_ByteString& sSubType) | |
2717 : m_eTabOrder(STRUCTURE), | |
2718 m_pPageView(pPageView), | |
2719 m_sType(sType), | |
2720 m_sSubType(sSubType) { | |
2721 CPDF_Page* pPDFPage = m_pPageView->GetPDFPage(); | |
2722 CFX_ByteString sTabs = pPDFPage->m_pFormDict->GetStringBy("Tabs"); | |
2723 if (sTabs == "R") | |
2724 m_eTabOrder = ROW; | |
2725 else if (sTabs == "C") | |
2726 m_eTabOrder = COLUMN; | |
2727 | |
2728 GenerateResults(); | |
2729 } | |
2730 | |
2731 CBA_AnnotIterator::~CBA_AnnotIterator() {} | |
2732 | |
2733 CPDFSDK_Annot* CBA_AnnotIterator::GetFirstAnnot() { | |
2734 return m_Annots.empty() ? nullptr : m_Annots.front(); | |
2735 } | |
2736 | |
2737 CPDFSDK_Annot* CBA_AnnotIterator::GetLastAnnot() { | |
2738 return m_Annots.empty() ? nullptr : m_Annots.back(); | |
2739 } | |
2740 | |
2741 CPDFSDK_Annot* CBA_AnnotIterator::GetNextAnnot(CPDFSDK_Annot* pAnnot) { | |
2742 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; | |
2749 } | |
2750 | |
2751 CPDFSDK_Annot* CBA_AnnotIterator::GetPrevAnnot(CPDFSDK_Annot* pAnnot) { | |
2752 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); | |
2758 } | |
2759 | |
2760 // static | |
2761 bool CBA_AnnotIterator::CompareByLeftAscending(const CPDFSDK_Annot* p1, | |
2762 const CPDFSDK_Annot* p2) { | |
2763 return GetAnnotRect(p1).left < GetAnnotRect(p2).left; | |
2764 } | |
2765 | |
2766 // static | |
2767 bool CBA_AnnotIterator::CompareByTopDescending(const CPDFSDK_Annot* p1, | |
2768 const CPDFSDK_Annot* p2) { | |
2769 return GetAnnotRect(p1).top > GetAnnotRect(p2).top; | |
2770 } | |
2771 | |
2772 void CBA_AnnotIterator::GenerateResults() { | |
2773 switch (m_eTabOrder) { | |
2774 case STRUCTURE: { | |
2775 for (size_t i = 0; i < m_pPageView->CountAnnots(); ++i) { | |
2776 CPDFSDK_Annot* pAnnot = m_pPageView->GetAnnot(i); | |
2777 if (pAnnot->GetType() == m_sType && pAnnot->GetSubType() == m_sSubType) | |
2778 m_Annots.push_back(pAnnot); | |
2779 } | |
2780 } break; | |
2781 case ROW: { | |
2782 std::vector<CPDFSDK_Annot*> sa; | |
2783 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) | |
2786 sa.push_back(pAnnot); | |
2787 } | |
2788 | |
2789 std::sort(sa.begin(), sa.end(), CompareByLeftAscending); | |
2790 while (!sa.empty()) { | |
2791 int nLeftTopIndex = -1; | |
2792 FX_FLOAT fTop = 0.0f; | |
2793 for (int i = sa.size() - 1; i >= 0; i--) { | |
2794 CFX_FloatRect rcAnnot = GetAnnotRect(sa[i]); | |
2795 if (rcAnnot.top > fTop) { | |
2796 nLeftTopIndex = i; | |
2797 fTop = rcAnnot.top; | |
2798 } | |
2799 } | |
2800 if (nLeftTopIndex >= 0) { | |
2801 CPDFSDK_Annot* pLeftTopAnnot = sa[nLeftTopIndex]; | |
2802 CFX_FloatRect rcLeftTop = GetAnnotRect(pLeftTopAnnot); | |
2803 m_Annots.push_back(pLeftTopAnnot); | |
2804 sa.erase(sa.begin() + nLeftTopIndex); | |
2805 | |
2806 std::vector<int> aSelect; | |
2807 for (size_t i = 0; i < sa.size(); ++i) { | |
2808 CFX_FloatRect rcAnnot = GetAnnotRect(sa[i]); | |
2809 FX_FLOAT fCenterY = (rcAnnot.top + rcAnnot.bottom) / 2.0f; | |
2810 if (fCenterY > rcLeftTop.bottom && fCenterY < rcLeftTop.top) | |
2811 aSelect.push_back(i); | |
2812 } | |
2813 for (size_t i = 0; i < aSelect.size(); ++i) | |
2814 m_Annots.push_back(sa[aSelect[i]]); | |
2815 | |
2816 for (int i = aSelect.size() - 1; i >= 0; --i) | |
2817 sa.erase(sa.begin() + aSelect[i]); | |
2818 } | |
2819 } | |
2820 } break; | |
2821 case COLUMN: { | |
2822 std::vector<CPDFSDK_Annot*> sa; | |
2823 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) | |
2826 sa.push_back(pAnnot); | |
2827 } | |
2828 | |
2829 std::sort(sa.begin(), sa.end(), CompareByTopDescending); | |
2830 while (!sa.empty()) { | |
2831 int nLeftTopIndex = -1; | |
2832 FX_FLOAT fLeft = -1.0f; | |
2833 for (int i = sa.size() - 1; i >= 0; --i) { | |
2834 CFX_FloatRect rcAnnot = GetAnnotRect(sa[i]); | |
2835 if (fLeft < 0) { | |
2836 nLeftTopIndex = 0; | |
2837 fLeft = rcAnnot.left; | |
2838 } else if (rcAnnot.left < fLeft) { | |
2839 nLeftTopIndex = i; | |
2840 fLeft = rcAnnot.left; | |
2841 } | |
2842 } | |
2843 | |
2844 if (nLeftTopIndex >= 0) { | |
2845 CPDFSDK_Annot* pLeftTopAnnot = sa[nLeftTopIndex]; | |
2846 CFX_FloatRect rcLeftTop = GetAnnotRect(pLeftTopAnnot); | |
2847 m_Annots.push_back(pLeftTopAnnot); | |
2848 sa.erase(sa.begin() + nLeftTopIndex); | |
2849 | |
2850 std::vector<int> aSelect; | |
2851 for (size_t i = 0; i < sa.size(); ++i) { | |
2852 CFX_FloatRect rcAnnot = GetAnnotRect(sa[i]); | |
2853 FX_FLOAT fCenterX = (rcAnnot.left + rcAnnot.right) / 2.0f; | |
2854 if (fCenterX > rcLeftTop.left && fCenterX < rcLeftTop.right) | |
2855 aSelect.push_back(i); | |
2856 } | |
2857 for (size_t i = 0; i < aSelect.size(); ++i) | |
2858 m_Annots.push_back(sa[aSelect[i]]); | |
2859 | |
2860 for (int i = aSelect.size() - 1; i >= 0; --i) | |
2861 sa.erase(sa.begin() + aSelect[i]); | |
2862 } | |
2863 } | |
2864 break; | |
2865 } | |
2866 } | |
2867 } | |
2868 | |
2869 CFX_FloatRect CBA_AnnotIterator::GetAnnotRect(const CPDFSDK_Annot* pAnnot) { | |
2870 CFX_FloatRect rcAnnot; | |
2871 pAnnot->GetPDFAnnot()->GetRect(rcAnnot); | |
2872 return rcAnnot; | |
2873 } | |
OLD | NEW |