1 // Copyright 2014 PDFium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com 6 7 #include "../../include/fpdfdoc/fpdf_doc.h" 8 CFX_WideString GetFullName(CPDF_Dictionary* pFieldDict); 9 void SaveCheckedFieldStatus(CPDF_FormField* pField, CFX_ByteArray& statusArray); 10 FX_BOOL PDF_FormField_IsUnison(CPDF_FormField *pField) 11 { 12 FX_BOOL bUnison = FALSE; 13 if (pField->GetType() == CPDF_FormField::CheckBox) { 14 bUnison = TRUE; 15 } else { 16 FX_DWORD dwFlags = pField->GetFieldFlags(); 17 bUnison = ((dwFlags & 0x2000000) != 0); 18 } 19 return bUnison; 20 } 21 CPDF_FormField::CPDF_FormField(CPDF_InterForm* pForm, CPDF_Dictionary* pDict) 22 { 23 m_pDict = pDict; 24 m_Type = Unknown; 25 m_pForm = pForm; 26 m_pFont = NULL; 27 m_FontSize = 0; 28 SyncFieldFlags(); 29 } 30 CPDF_FormField::~CPDF_FormField() 31 { 32 } 33 void CPDF_FormField::SyncFieldFlags() 34 { 35 CFX_ByteString type_name = FPDF_GetFieldAttr(m_pDict, "FT")->GetString(); 36 FX_DWORD flags = FPDF_GetFieldAttr(m_pDict, "Ff")->GetInteger(); 37 m_Flags = 0; 38 if (flags & 1) { 39 m_Flags |= FORMFIELD_READONLY; 40 } 41 if (flags & 2) { 42 m_Flags |= FORMFIELD_REQUIRED; 43 } 44 if (flags & 4) { 45 m_Flags |= FORMFIELD_NOEXPORT; 46 } 47 if (type_name == "Btn") { 48 if (flags & 0x8000) { 49 m_Type = RadioButton; 50 if (flags & 0x4000) { 51 m_Flags |= FORMRADIO_NOTOGGLEOFF; 52 } 53 if (flags & 0x2000000) { 54 m_Flags |= FORMRADIO_UNISON; 55 } 56 } else if (flags & 0x10000) { 57 m_Type = PushButton; 58 } else { 59 m_Type = CheckBox; 60 } 61 } else if (type_name == "Tx") { 62 if (flags & 0x100000) { 63 m_Type = File; 64 } else if (flags & 0x2000000) { 65 m_Type = RichText; 66 } else { 67 m_Type = Text; 68 if (flags & 0x1000) { 69 m_Flags |= FORMTEXT_MULTILINE; 70 } 71 if (flags & 0x2000) { 72 m_Flags |= FORMTEXT_PASSWORD; 73 } 74 if (flags & 0x800000) { 75 m_Flags |= FORMTEXT_NOSCROLL; 76 } 77 if (flags & 0x100000) { 78 m_Flags |= FORMTEXT_COMB; 79 } 80 } 81 LoadDA(); 82 } else if (type_name == "Ch") { 83 if (flags & 0x20000) { 84 m_Type = ComboBox; 85 if (flags & 0x40000) { 86 m_Flags |= FORMCOMBO_EDIT; 87 } 88 } else { 89 m_Type = ListBox; 90 if (flags & 0x200000) { 91 m_Flags |= FORMLIST_MULTISELECT; 92 } 93 } 94 LoadDA(); 95 } else if (type_name == "Sig") { 96 m_Type = Sign; 97 } 98 } 99 CFX_WideString CPDF_FormField::GetFullName() 100 { 101 return ::GetFullName(m_pDict); 102 } 103 FX_BOOL CPDF_FormField::ResetField(FX_BOOL bNotify) 104 { 105 switch (m_Type) { 106 case CPDF_FormField::CheckBox: 107 case CPDF_FormField::RadioButton: { 108 CFX_ByteArray statusArray; 109 if (bNotify && m_pForm->m_pFormNotify != NULL) { 110 SaveCheckedFieldStatus(this, statusArray); 111 } 112 int iCount = CountControls(); 113 if (iCount) { 114 if (PDF_FormField_IsUnison(this)) { 115 for(int i = 0; i < iCount; i++) { 116 CheckControl(i, GetControl(i)->IsDefaultChecked(), FALSE); 117 } 118 } else { 119 for (int i = 0; i < iCount; i ++) { 120 CPDF_FormControl* pControl = GetControl(i); 121 FX_BOOL bChecked = pControl->IsDefaultChecked(); 122 CheckControl(i, bChecked, FALSE); 123 } 124 } 125 } 126 if (bNotify && m_pForm->m_pFormNotify != NULL) { 127 m_pForm->m_pFormNotify->AfterCheckedStatusChange(this, statusArray); 128 } 129 } 130 break; 131 case CPDF_FormField::ComboBox: { 132 CFX_WideString csValue; 133 ClearSelection(); 134 int iIndex = GetDefaultSelectedItem(); 135 if (iIndex >= 0) { 136 csValue = GetOptionLabel(iIndex); 137 } 138 if (bNotify && m_pForm->m_pFormNotify != NULL) { 139 int iRet = m_pForm->m_pFormNotify->BeforeValueChange(this, csValue); 140 if (iRet < 0) { 141 return FALSE; 142 } 143 } 144 SetItemSelection(iIndex, TRUE); 145 if (bNotify && m_pForm->m_pFormNotify != NULL) { 146 m_pForm->m_pFormNotify->AfterValueChange(this); 147 } 148 } 149 break; 150 case CPDF_FormField::ListBox: { 151 CFX_WideString csValue; 152 ClearSelection(); 153 int iIndex = GetDefaultSelectedItem(); 154 if (iIndex >= 0) { 155 csValue = GetOptionLabel(iIndex); 156 } 157 if (bNotify && m_pForm->m_pFormNotify != NULL) { 158 int iRet = m_pForm->m_pFormNotify->BeforeSelectionChange(this, csValue); 159 if (iRet < 0) { 160 return FALSE; 161 } 162 } 163 SetItemSelection(iIndex, TRUE); 164 if (bNotify && m_pForm->m_pFormNotify != NULL) { 165 m_pForm->m_pFormNotify->AfterSelectionChange(this); 166 } 167 } 168 break; 169 case CPDF_FormField::Text: 170 case CPDF_FormField::RichText: 171 case CPDF_FormField::File: 172 default: { 173 CPDF_Object* pDV = FPDF_GetFieldAttr(m_pDict, "DV"); 174 CFX_WideString csDValue; 175 if (pDV != NULL) { 176 csDValue = pDV->GetUnicodeText(); 177 } 178 CPDF_Object* pV = FPDF_GetFieldAttr(m_pDict, "V"); 179 CFX_WideString csValue; 180 if (pV != NULL) { 181 csValue = pV->GetUnicodeText(); 182 } 183 CPDF_Object* pRV = FPDF_GetFieldAttr(m_pDict, "RV"); 184 if (!pRV && (csDValue == csValue)) { 185 return FALSE; 186 } 187 if (bNotify && m_pForm->m_pFormNotify != NULL) { 188 int iRet = m_pForm->m_pFormNotify->BeforeValueChange(this, csDValue); 189 if (iRet < 0) { 190 return FALSE; 191 } 192 } 193 if (pDV == NULL) { 194 m_pDict->RemoveAt("V"); 195 m_pDict->RemoveAt("RV"); 196 } else { 197 CPDF_Object* pClone = pDV->Clone(); 198 if (pClone == NULL) { 199 return FALSE; 200 } 201 m_pDict->SetAt("V", pClone); 202 if(pRV) { 203 CPDF_Object* pCloneR = pDV->Clone(); 204 m_pDict->SetAt("RV", pCloneR); 205 } 206 } 207 if (bNotify && m_pForm->m_pFormNotify != NULL) { 208 m_pForm->m_pFormNotify->AfterValueChange(this); 209 } 210 m_pForm->m_bUpdated = TRUE; 211 } 212 break; 213 } 214 return TRUE; 215 } 216 int CPDF_FormField::GetControlIndex(const CPDF_FormControl* pControl) 217 { 218 if (pControl == NULL) { 219 return -1; 220 } 221 int iCount = m_ControlList.GetSize(); 222 for (int i = 0; i < iCount; i ++) { 223 CPDF_FormControl* pFind = (CPDF_FormControl*)m_ControlList.GetAt(i); 224 if (pFind == pControl) { 225 return i; 226 } 227 } 228 return -1; 229 } 230 int CPDF_FormField::GetFieldType() 231 { 232 switch (m_Type) { 233 case PushButton: 234 return FIELDTYPE_PUSHBUTTON; 235 case CheckBox: 236 return FIELDTYPE_CHECKBOX; 237 case RadioButton: 238 return FIELDTYPE_RADIOBUTTON; 239 case ComboBox: 240 return FIELDTYPE_COMBOBOX; 241 case ListBox: 242 return FIELDTYPE_LISTBOX; 243 case Text: 244 case RichText: 245 case File: 246 return FIELDTYPE_TEXTFIELD; 247 case Sign: 248 return FIELDTYPE_SIGNATURE; 249 default: 250 break; 251 } 252 return FIELDTYPE_UNKNOWN; 253 } 254 CPDF_AAction CPDF_FormField::GetAdditionalAction() 255 { 256 CPDF_Object* pObj = FPDF_GetFieldAttr(m_pDict, "AA"); 257 if (pObj == NULL) { 258 return NULL; 259 } 260 return pObj->GetDict(); 261 } 262 CFX_WideString CPDF_FormField::GetAlternateName() 263 { 264 CPDF_Object* pObj = FPDF_GetFieldAttr(m_pDict, "TU"); 265 if (pObj == NULL) { 266 return L""; 267 } 268 return pObj->GetUnicodeText(); 269 } 270 CFX_WideString CPDF_FormField::GetMappingName() 271 { 272 CPDF_Object* pObj = FPDF_GetFieldAttr(m_pDict, "TM"); 273 if (pObj == NULL) { 274 return L""; 275 } 276 return pObj->GetUnicodeText(); 277 } 278 FX_DWORD CPDF_FormField::GetFieldFlags() 279 { 280 CPDF_Object* pObj = FPDF_GetFieldAttr(m_pDict, "Ff"); 281 if (pObj == NULL) { 282 return 0; 283 } 284 return pObj->GetInteger(); 285 } 286 CFX_ByteString CPDF_FormField::GetDefaultStyle() 287 { 288 CPDF_Object* pObj = FPDF_GetFieldAttr(m_pDict, "DS"); 289 if (pObj == NULL) { 290 return ""; 291 } 292 return pObj->GetString(); 293 } 294 CFX_WideString CPDF_FormField::GetRichTextString() 295 { 296 CPDF_Object* pObj = FPDF_GetFieldAttr(m_pDict, "RV"); 297 if (pObj == NULL) { 298 return L""; 299 } 300 return pObj->GetUnicodeText(); 301 } 302 CFX_WideString CPDF_FormField::GetValue(FX_BOOL bDefault) 303 { 304 if (GetType() == CheckBox || GetType() == RadioButton) { 305 return GetCheckValue(bDefault); 306 } 307 CPDF_Object* pValue = FPDF_GetFieldAttr(m_pDict, bDefault ? "DV" : "V"); 308 if (pValue == NULL) { 309 if (!bDefault) { 310 if (m_Type == RichText) { 311 pValue = FPDF_GetFieldAttr(m_pDict, "V"); 312 } 313 if (pValue == NULL && m_Type != Text) { 314 pValue = FPDF_GetFieldAttr(m_pDict, "DV"); 315 } 316 } 317 if (pValue == NULL) { 318 return CFX_WideString(); 319 } 320 } 321 switch (pValue->GetType()) { 322 case PDFOBJ_STRING: 323 case PDFOBJ_STREAM: 324 return pValue->GetUnicodeText(); 325 case PDFOBJ_ARRAY: 326 pValue = ((CPDF_Array*)pValue)->GetElementValue(0); 327 return pValue->GetUnicodeText(); 328 break; 329 } 330 return CFX_WideString(); 331 } 332 CFX_WideString CPDF_FormField::GetValue() 333 { 334 return GetValue(FALSE); 335 } 336 CFX_WideString CPDF_FormField::GetDefaultValue() 337 { 338 return GetValue(TRUE); 339 } 340 FX_BOOL CPDF_FormField::SetValue(const CFX_WideString& value, FX_BOOL bDefault, FX_BOOL bNotify) 341 { 342 switch (m_Type) { 343 case CheckBox: 344 case RadioButton: { 345 SetCheckValue(value, bDefault, bNotify); 346 return TRUE; 347 } 348 case File: 349 case RichText: 350 case Text: 351 case ComboBox: { 352 CFX_WideString csValue = value; 353 if (bNotify && m_pForm->m_pFormNotify != NULL) { 354 int iRet = m_pForm->m_pFormNotify->BeforeValueChange(this, csValue); 355 if (iRet < 0) { 356 return FALSE; 357 } 358 } 359 int iIndex = FindOptionValue(csValue); 360 if (iIndex < 0) { 361 CFX_ByteString bsEncodeText = PDF_EncodeText(csValue); 362 m_pDict->SetAtString(bDefault ? "DV" : "V", bsEncodeText); 363 if (m_Type == RichText && !bDefault) { 364 m_pDict->SetAtString("RV", bsEncodeText); 365 } 366 m_pDict->RemoveAt("I"); 367 } else { 368 m_pDict->SetAtString(bDefault ? "DV" : "V", PDF_EncodeText(csValue)); 369 if (bDefault) { 370 } else { 371 ClearSelection(); 372 SetItemSelection(iIndex, TRUE); 373 } 374 } 375 if (bNotify && m_pForm->m_pFormNotify != NULL) { 376 m_pForm->m_pFormNotify->AfterValueChange(this); 377 } 378 m_pForm->m_bUpdated = TRUE; 379 } 380 break; 381 case ListBox: { 382 int iIndex = FindOptionValue(value); 383 if (iIndex < 0) { 384 return FALSE; 385 } 386 if (bDefault && iIndex == GetDefaultSelectedItem()) { 387 return FALSE; 388 } 389 if (bNotify && m_pForm->m_pFormNotify != NULL) { 390 CFX_WideString csValue = value; 391 int iRet = m_pForm->m_pFormNotify->BeforeSelectionChange(this, csValue); 392 if (iRet < 0) { 393 return FALSE; 394 } 395 } 396 if (bDefault) { 397 } else { 398 ClearSelection(); 399 SetItemSelection(iIndex, TRUE); 400 } 401 if (bNotify && m_pForm->m_pFormNotify != NULL) { 402 m_pForm->m_pFormNotify->AfterSelectionChange(this); 403 } 404 m_pForm->m_bUpdated = TRUE; 405 break; 406 } 407 default: 408 break; 409 } 410 if (CPDF_InterForm::m_bUpdateAP) { 411 UpdateAP(NULL); 412 } 413 return TRUE; 414 } 415 FX_BOOL CPDF_FormField::SetValue(const CFX_WideString& value, FX_BOOL bNotify) 416 { 417 return SetValue(value, FALSE, bNotify); 418 } 419 int CPDF_FormField::GetMaxLen() 420 { 421 CPDF_Object* pObj = FPDF_GetFieldAttr(m_pDict, "MaxLen"); 422 if (pObj == NULL) { 423 int iCount = m_ControlList.GetSize(); 424 for (int i = 0; i < iCount; i ++) { 425 CPDF_FormControl* pControl = (CPDF_FormControl*)m_ControlList.GetAt(i); 426 if (pControl == NULL) { 427 continue; 428 } 429 CPDF_Dictionary* pWidgetDict = pControl->m_pWidgetDict; 430 if (pWidgetDict->KeyExist("MaxLen")) { 431 return pWidgetDict->GetInteger("MaxLen"); 432 } 433 } 434 return 0; 435 } 436 return pObj->GetInteger(); 437 } 438 int CPDF_FormField::CountSelectedItems() 439 { 440 CPDF_Object* pValue = FPDF_GetFieldAttr(m_pDict, "V"); 441 if (pValue == NULL) { 442 pValue = FPDF_GetFieldAttr(m_pDict, "I"); 443 if (pValue == NULL) { 444 return 0; 445 } 446 } 447 if (pValue->GetType() == PDFOBJ_STRING) { 448 if (pValue->GetString().IsEmpty()) { 449 return 0; 450 } 451 return 1; 452 } 453 if (pValue->GetType() == PDFOBJ_NUMBER) { 454 if (pValue->GetString().IsEmpty()) { 455 return 0; 456 } 457 return 1; 458 } 459 if (pValue->GetType() != PDFOBJ_ARRAY) { 460 return 0; 461 } 462 return ((CPDF_Array*)pValue)->GetCount(); 463 } 464 int CPDF_FormField::GetSelectedIndex(int index) 465 { 466 CPDF_Object* pValue = FPDF_GetFieldAttr(m_pDict, "V"); 467 if (pValue == NULL) { 468 pValue = FPDF_GetFieldAttr(m_pDict, "I"); 469 if (pValue == NULL) { 470 return -1; 471 } 472 } 473 CFX_WideString sel_value; 474 if (pValue->GetType() == PDFOBJ_STRING) { 475 if (index != 0) { 476 return -1; 477 } 478 sel_value = pValue->GetUnicodeText(); 479 } else if (pValue->GetType() == PDFOBJ_NUMBER) { 480 return pValue->GetInteger(); 481 } else { 482 if (pValue->GetType() != PDFOBJ_ARRAY) { 483 return -1; 484 } 485 if (index < 0) { 486 return -1; 487 } 488 sel_value = ((CPDF_Array*)pValue)->GetElementValue(index)->GetUnicodeText(); 489 } 490 if (index < CountSelectedOptions()) { 491 int iOptIndex = GetSelectedOptionIndex(index); 492 CFX_WideString csOpt = GetOptionValue(iOptIndex); 493 if (csOpt == sel_value) { 494 return iOptIndex; 495 } 496 } 497 int nOpts = CountOptions(); 498 for (int i = 0; i < nOpts; i ++) { 499 if (sel_value == GetOptionValue(i)) { 500 return i; 501 } 502 } 503 return -1; 504 } 505 FX_BOOL CPDF_FormField::ClearSelection(FX_BOOL bNotify) 506 { 507 if (bNotify && m_pForm->m_pFormNotify != NULL) { 508 int iRet = 0; 509 CFX_WideString csValue; 510 int iIndex = GetSelectedIndex(0); 511 if (iIndex >= 0) { 512 csValue = GetOptionLabel(iIndex); 513 } 514 if (GetType() == ListBox) { 515 iRet = m_pForm->m_pFormNotify->BeforeSelectionChange(this, csValue); 516 } 517 if (GetType() == ComboBox) { 518 iRet = m_pForm->m_pFormNotify->BeforeValueChange(this, csValue); 519 } 520 if (iRet < 0) { 521 return FALSE; 522 } 523 } 524 m_pDict->RemoveAt("V"); 525 m_pDict->RemoveAt("I"); 526 if (bNotify && m_pForm->m_pFormNotify != NULL) { 527 if (GetType() == ListBox) { 528 m_pForm->m_pFormNotify->AfterSelectionChange(this); 529 } 530 if (GetType() == ComboBox) { 531 m_pForm->m_pFormNotify->AfterValueChange(this); 532 } 533 } 534 if (CPDF_InterForm::m_bUpdateAP) { 535 UpdateAP(NULL); 536 } 537 m_pForm->m_bUpdated = TRUE; 538 return TRUE; 539 } 540 FX_BOOL CPDF_FormField::IsItemSelected(int index) 541 { 542 ASSERT(GetType() == ComboBox || GetType() == ListBox); 543 if (index < 0 || index >= CountOptions()) { 544 return FALSE; 545 } 546 if (IsOptionSelected(index)) { 547 return TRUE; 548 } 549 CFX_WideString opt_value = GetOptionValue(index); 550 CPDF_Object* pValue = FPDF_GetFieldAttr(m_pDict, "V"); 551 if (pValue == NULL) { 552 pValue = FPDF_GetFieldAttr(m_pDict, "I"); 553 if (pValue == NULL) { 554 return FALSE; 555 } 556 } 557 if (pValue->GetType() == PDFOBJ_STRING) { 558 if (pValue->GetUnicodeText() == opt_value) { 559 return TRUE; 560 } 561 return FALSE; 562 } 563 if (pValue->GetType() == PDFOBJ_NUMBER) { 564 if (pValue->GetString().IsEmpty()) { 565 return FALSE; 566 } 567 if (pValue->GetInteger() == index) { 568 return TRUE; 569 } 570 return FALSE; 571 } 572 if (pValue->GetType() != PDFOBJ_ARRAY) { 573 return FALSE; 574 } 575 CPDF_Array* pArray = (CPDF_Array*)pValue; 576 int iPos = -1; 577 for (int j = 0; j < CountSelectedOptions(); j ++) { 578 if (GetSelectedOptionIndex(j) == index) { 579 iPos = j; 580 break; 581 } 582 } 583 for (FX_DWORD i = 0; i < pArray->GetCount(); i ++) 584 if (pArray->GetElementValue(i)->GetUnicodeText() == opt_value && (int)i == iPos) { 585 return TRUE; 586 } 587 return FALSE; 588 } 589 FX_BOOL CPDF_FormField::SetItemSelection(int index, FX_BOOL bSelected, FX_BOOL bNotify) 590 { 591 ASSERT(GetType() == ComboBox || GetType() == ListBox); 592 if (index < 0 || index >= CountOptions()) { 593 return FALSE; 594 } 595 CFX_WideString opt_value = GetOptionValue(index); 596 if (bNotify && m_pForm->m_pFormNotify != NULL) { 597 int iRet = 0; 598 if (GetType() == ListBox) { 599 iRet = m_pForm->m_pFormNotify->BeforeSelectionChange(this, opt_value); 600 } 601 if (GetType() == ComboBox) { 602 iRet = m_pForm->m_pFormNotify->BeforeValueChange(this, opt_value); 603 } 604 if (iRet < 0) { 605 return FALSE; 606 } 607 } 608 if (!bSelected) { 609 CPDF_Object* pValue = FPDF_GetFieldAttr(m_pDict, "V"); 610 if (pValue != NULL) { 611 if (m_Type == ListBox) { 612 SelectOption(index, FALSE); 613 if (pValue->GetType() == PDFOBJ_STRING) { 614 if (pValue->GetUnicodeText() == opt_value) { 615 m_pDict->RemoveAt("V"); 616 } 617 } else if (pValue->GetType() == PDFOBJ_ARRAY) { 618 CPDF_Array* pArray = CPDF_Array::Create(); 619 if (pArray == NULL) { 620 return FALSE; 621 } 622 int iCount = CountOptions(); 623 for (int i = 0; i < iCount; i ++) { 624 if (i != index) { 625 if (IsItemSelected(i)) { 626 opt_value = GetOptionValue(i); 627 pArray->AddString(PDF_EncodeText(opt_value)); 628 } 629 } 630 } 631 if (pArray->GetCount() < 1) { 632 pArray->Release(); 633 } else { 634 m_pDict->SetAt("V", pArray); 635 } 636 } 637 } else if (m_Type == ComboBox) { 638 m_pDict->RemoveAt("V"); 639 m_pDict->RemoveAt("I"); 640 } 641 } 642 } else { 643 if (m_Type == ListBox) { 644 SelectOption(index, TRUE); 645 if (!(m_Flags & FORMLIST_MULTISELECT)) { 646 m_pDict->SetAtString("V", PDF_EncodeText(opt_value, opt_value.GetLength())); 647 } else { 648 CPDF_Array* pArray = CPDF_Array::Create(); 649 if (pArray == NULL) { 650 return FALSE; 651 } 652 FX_BOOL bSelected; 653 int iCount = CountOptions(); 654 for (int i = 0; i < iCount; i ++) { 655 if (i != index) { 656 bSelected = IsItemSelected(i); 657 } else { 658 bSelected = TRUE; 659 } 660 if (bSelected) { 661 opt_value = GetOptionValue(i); 662 pArray->AddString(PDF_EncodeText(opt_value)); 663 } 664 } 665 m_pDict->SetAt("V", pArray); 666 } 667 } else if (m_Type == ComboBox) { 668 m_pDict->SetAtString("V", PDF_EncodeText(opt_value, opt_value.GetLength())); 669 CPDF_Array* pI = CPDF_Array::Create(); 670 if (pI == NULL) { 671 return FALSE; 672 } 673 pI->AddInteger(index); 674 m_pDict->SetAt("I", pI); 675 } 676 } 677 if (bNotify && m_pForm->m_pFormNotify != NULL) { 678 if (GetType() == ListBox) { 679 m_pForm->m_pFormNotify->AfterSelectionChange(this); 680 } 681 if (GetType() == ComboBox) { 682 m_pForm->m_pFormNotify->AfterValueChange(this); 683 } 684 } 685 if (CPDF_InterForm::m_bUpdateAP) { 686 UpdateAP(NULL); 687 } 688 m_pForm->m_bUpdated = TRUE; 689 return TRUE; 690 } 691 FX_BOOL CPDF_FormField::IsItemDefaultSelected(int index) 692 { 693 ASSERT(GetType() == ComboBox || GetType() == ListBox); 694 if (index < 0 || index >= CountOptions()) { 695 return FALSE; 696 } 697 int iDVIndex = GetDefaultSelectedItem(); 698 if (iDVIndex < 0) { 699 return FALSE; 700 } 701 return (iDVIndex == index); 702 } 703 int CPDF_FormField::GetDefaultSelectedItem() 704 { 705 ASSERT(GetType() == ComboBox || GetType() == ListBox); 706 CPDF_Object* pValue = FPDF_GetFieldAttr(m_pDict, "DV"); 707 if (pValue == NULL) { 708 return -1; 709 } 710 CFX_WideString csDV = pValue->GetUnicodeText(); 711 if (csDV.IsEmpty()) { 712 return -1; 713 } 714 int iCount = CountOptions(); 715 for (int i = 0; i < iCount; i ++) { 716 if (csDV == GetOptionValue(i)) { 717 return i; 718 } 719 } 720 return -1; 721 } 722 void CPDF_FormField::UpdateAP(CPDF_FormControl* pControl) 723 { 724 if (m_Type == PushButton) { 725 return; 726 } 727 if (m_Type == RadioButton || m_Type == CheckBox) { 728 return; 729 } 730 if (!m_pForm->m_bGenerateAP) { 731 return; 732 } 733 for (int i = 0; i < CountControls(); i ++) { 734 CPDF_FormControl* pControl = GetControl(i); 735 FPDF_GenerateAP(m_pForm->m_pDocument, pControl->m_pWidgetDict); 736 } 737 } 738 int CPDF_FormField::CountOptions() 739 { 740 CPDF_Object* pValue = FPDF_GetFieldAttr(m_pDict, "Opt"); 741 if (pValue == NULL || pValue->GetType() != PDFOBJ_ARRAY) { 742 return 0; 743 } 744 return ((CPDF_Array*)pValue)->GetCount(); 745 } 746 CFX_WideString CPDF_FormField::GetOptionText(int index, int sub_index) 747 { 748 CPDF_Object* pValue = FPDF_GetFieldAttr(m_pDict, "Opt"); 749 if (pValue == NULL || pValue->GetType() != PDFOBJ_ARRAY) { 750 return CFX_WideString(); 751 } 752 CPDF_Object* pOption = ((CPDF_Array*)pValue)->GetElementValue(index); 753 if (pOption == NULL) { 754 return CFX_WideString(); 755 } 756 if (pOption->GetType() == PDFOBJ_ARRAY) { 757 pOption = ((CPDF_Array*)pOption)->GetElementValue(sub_index); 758 } 759 if (pOption == NULL || pOption->GetType() != PDFOBJ_STRING) { 760 return CFX_WideString(); 761 } 762 return ((CPDF_String*)pOption)->GetUnicodeText(); 763 } 764 CFX_WideString CPDF_FormField::GetOptionLabel(int index) 765 { 766 return GetOptionText(index, 1); 767 } 768 CFX_WideString CPDF_FormField::GetOptionValue(int index) 769 { 770 return GetOptionText(index, 0); 771 } 772 int CPDF_FormField::FindOption(CFX_WideString csOptLabel) 773 { 774 int iCount = CountOptions(); 775 for (int i = 0; i < iCount; i ++) { 776 CFX_WideString csValue = GetOptionValue(i); 777 if (csValue == csOptLabel) { 778 return i; 779 } 780 } 781 return -1; 782 } 783 int CPDF_FormField::FindOptionValue(FX_LPCWSTR csOptValue, int iStartIndex) 784 { 785 if (iStartIndex < 0) { 786 iStartIndex = 0; 787 } 788 int iCount = CountOptions(); 789 for (; iStartIndex < iCount; iStartIndex ++) { 790 CFX_WideString csValue = GetOptionValue(iStartIndex); 791 if (csValue == csOptValue) { 792 return iStartIndex; 793 } 794 } 795 return -1; 796 } 797 FX_BOOL CPDF_FormField::CheckControl(int iControlIndex, FX_BOOL bChecked, FX_BOOL bNotify) 798 { 799 ASSERT(GetType() == CheckBox || GetType() == RadioButton); 800 CPDF_FormControl* pControl = GetControl(iControlIndex); 801 if (pControl == NULL) { 802 return FALSE; 803 } 804 if (!bChecked && pControl->IsChecked() == bChecked) { 805 return FALSE; 806 } 807 CFX_ByteArray statusArray; 808 if (bNotify && m_pForm->m_pFormNotify != NULL) { 809 SaveCheckedFieldStatus(this, statusArray); 810 } 811 CFX_WideString csWExport = pControl->GetExportValue(); 812 CFX_ByteString csBExport = PDF_EncodeText(csWExport); 813 int iCount = CountControls(); 814 FX_BOOL bUnison = PDF_FormField_IsUnison(this); 815 for (int i = 0; i < iCount; i ++) { 816 CPDF_FormControl* pCtrl = GetControl(i); 817 if (bUnison) { 818 CFX_WideString csEValue = pCtrl->GetExportValue(); 819 if (csEValue == csWExport) { 820 if (pCtrl->GetOnStateName() == pControl->GetOnStateName()) { 821 pCtrl->CheckControl(bChecked); 822 } else if (bChecked) { 823 pCtrl->CheckControl(FALSE); 824 } 825 } else if (bChecked) { 826 pCtrl->CheckControl(FALSE); 827 } 828 } else { 829 if (i == iControlIndex) { 830 pCtrl->CheckControl(bChecked); 831 } else if (bChecked) { 832 pCtrl->CheckControl(FALSE); 833 } 834 } 835 } 836 CPDF_Object* pOpt = FPDF_GetFieldAttr(m_pDict, "Opt"); 837 if (pOpt == NULL || pOpt->GetType() != PDFOBJ_ARRAY) { 838 if (bChecked) { 839 m_pDict->SetAtName("V", csBExport); 840 } else { 841 CFX_ByteString csV; 842 CPDF_Object* pV = FPDF_GetFieldAttr(m_pDict, "V"); 843 if (pV != NULL) { 844 csV = pV->GetString(); 845 } 846 if (csV == csBExport) { 847 m_pDict->SetAtName("V", "Off"); 848 } 849 } 850 } else if (bChecked) { 851 CFX_ByteString csIndex; 852 csIndex.Format("%d", iControlIndex); 853 m_pDict->SetAtName("V", csIndex); 854 } 855 if (bNotify && m_pForm->m_pFormNotify != NULL) { 856 m_pForm->m_pFormNotify->AfterCheckedStatusChange(this, statusArray); 857 } 858 m_pForm->m_bUpdated = TRUE; 859 return TRUE; 860 } 861 CFX_WideString CPDF_FormField::GetCheckValue(FX_BOOL bDefault) 862 { 863 ASSERT(GetType() == CheckBox || GetType() == RadioButton); 864 CFX_WideString csExport = L"Off"; 865 FX_BOOL bChecked; 866 int iCount = CountControls(); 867 for (int i = 0; i < iCount; i ++) { 868 CPDF_FormControl* pControl = GetControl(i); 869 if (bDefault) { 870 bChecked = pControl->IsDefaultChecked(); 871 } else { 872 bChecked = pControl->IsChecked(); 873 } 874 if (bChecked) { 875 csExport = pControl->GetExportValue(); 876 break; 877 } 878 } 879 return csExport; 880 } 881 FX_BOOL CPDF_FormField::SetCheckValue(const CFX_WideString& value, FX_BOOL bDefault, FX_BOOL bNotify) 882 { 883 ASSERT(GetType() == CheckBox || GetType() == RadioButton); 884 CFX_ByteArray statusArray; 885 if (bNotify && m_pForm->m_pFormNotify != NULL) { 886 SaveCheckedFieldStatus(this, statusArray); 887 } 888 int iCount = CountControls(); 889 for (int i = 0; i < iCount; i ++) { 890 CPDF_FormControl* pControl = GetControl(i); 891 CFX_WideString csExport = pControl->GetExportValue(); 892 if (csExport == value) { 893 if (bDefault) { 894 } else { 895 CheckControl(GetControlIndex(pControl), TRUE); 896 } 897 break; 898 } else { 899 if (bDefault) { 900 } else { 901 CheckControl(GetControlIndex(pControl), FALSE); 902 } 903 } 904 } 905 if (bNotify && m_pForm->m_pFormNotify != NULL) { 906 m_pForm->m_pFormNotify->AfterCheckedStatusChange(this, statusArray); 907 } 908 m_pForm->m_bUpdated = TRUE; 909 return TRUE; 910 } 911 int CPDF_FormField::GetTopVisibleIndex() 912 { 913 CPDF_Object* pObj = FPDF_GetFieldAttr(m_pDict, "TI"); 914 if (pObj == NULL) { 915 return 0; 916 } 917 return pObj->GetInteger(); 918 } 919 int CPDF_FormField::CountSelectedOptions() 920 { 921 CPDF_Object* pObj = FPDF_GetFieldAttr(m_pDict, "I"); 922 if (pObj == NULL) { 923 return 0; 924 } 925 CPDF_Array* pArray = pObj->GetArray(); 926 if (pArray == NULL) { 927 return 0; 928 } 929 return (int)pArray->GetCount(); 930 } 931 int CPDF_FormField::GetSelectedOptionIndex(int index) 932 { 933 CPDF_Object* pObj = FPDF_GetFieldAttr(m_pDict, "I"); 934 if (pObj == NULL) { 935 return -1; 936 } 937 CPDF_Array* pArray = pObj->GetArray(); 938 if (pArray == NULL) { 939 return -1; 940 } 941 int iCount = (int)pArray->GetCount(); 942 if (iCount > 0 && index < iCount) { 943 return pArray->GetInteger(index); 944 } 945 return -1; 946 } 947 FX_BOOL CPDF_FormField::IsOptionSelected(int iOptIndex) 948 { 949 CPDF_Object* pObj = FPDF_GetFieldAttr(m_pDict, "I"); 950 if (pObj == NULL) { 951 return FALSE; 952 } 953 CPDF_Array* pArray = pObj->GetArray(); 954 if (pArray == NULL) { 955 return FALSE; 956 } 957 int iCount = (int)pArray->GetCount(); 958 for (int i = 0; i < iCount; i ++) { 959 if (pArray->GetInteger(i) == iOptIndex) { 960 return TRUE; 961 } 962 } 963 return FALSE; 964 } 965 FX_BOOL CPDF_FormField::SelectOption(int iOptIndex, FX_BOOL bSelected, FX_BOOL bNotify) 966 { 967 CPDF_Array* pArray = m_pDict->GetArray("I"); 968 if (pArray == NULL) { 969 if (!bSelected) { 970 return TRUE; 971 } 972 pArray = CPDF_Array::Create(); 973 if (pArray == NULL) { 974 return FALSE; 975 } 976 m_pDict->SetAt("I", pArray); 977 } 978 FX_BOOL bReturn = FALSE; 979 for (int i = 0; i < (int)pArray->GetCount(); i ++) { 980 int iFind = pArray->GetInteger(i); 981 if (iFind == iOptIndex) { 982 if (bSelected) { 983 return TRUE; 984 } 985 if (bNotify && m_pForm->m_pFormNotify != NULL) { 986 int iRet = 0; 987 CFX_WideString csValue = GetOptionLabel(iOptIndex); 988 if (GetType() == ListBox) { 989 iRet = m_pForm->m_pFormNotify->BeforeSelectionChange(this, csValue); 990 } 991 if (GetType() == ComboBox) { 992 iRet = m_pForm->m_pFormNotify->BeforeValueChange(this, csValue); 993 } 994 if (iRet < 0) { 995 return FALSE; 996 } 997 } 998 pArray->RemoveAt(i); 999 bReturn = TRUE; 1000 break; 1001 } else if (iFind > iOptIndex) { 1002 if (!bSelected) { 1003 continue; 1004 } 1005 if (bNotify && m_pForm->m_pFormNotify != NULL) { 1006 int iRet = 0; 1007 CFX_WideString csValue = GetOptionLabel(iOptIndex); 1008 if (GetType() == ListBox) { 1009 iRet = m_pForm->m_pFormNotify->BeforeSelectionChange(this, csValue); 1010 } 1011 if (GetType() == ComboBox) { 1012 iRet = m_pForm->m_pFormNotify->BeforeValueChange(this, csValue); 1013 } 1014 if (iRet < 0) { 1015 return FALSE; 1016 } 1017 } 1018 CPDF_Number* pNum = CPDF_Number::Create(iOptIndex); 1019 if (pNum == NULL) { 1020 return FALSE; 1021 } 1022 pArray->InsertAt(i, pNum); 1023 bReturn = TRUE; 1024 break; 1025 } 1026 } 1027 if (!bReturn) { 1028 if (bSelected) { 1029 pArray->AddInteger(iOptIndex); 1030 } 1031 if (pArray->GetCount() == 0) { 1032 m_pDict->RemoveAt("I"); 1033 } 1034 } 1035 if (bNotify && m_pForm->m_pFormNotify != NULL) { 1036 if (GetType() == ListBox) { 1037 m_pForm->m_pFormNotify->AfterSelectionChange(this); 1038 } 1039 if (GetType() == ComboBox) { 1040 m_pForm->m_pFormNotify->AfterValueChange(this); 1041 } 1042 } 1043 m_pForm->m_bUpdated = TRUE; 1044 return TRUE; 1045 } 1046 FX_BOOL CPDF_FormField::ClearSelectedOptions(FX_BOOL bNotify) 1047 { 1048 if (bNotify && m_pForm->m_pFormNotify != NULL) { 1049 int iRet = 0; 1050 CFX_WideString csValue; 1051 int iIndex = GetSelectedIndex(0); 1052 if (iIndex >= 0) { 1053 csValue = GetOptionLabel(iIndex); 1054 } 1055 if (GetType() == ListBox) { 1056 iRet = m_pForm->m_pFormNotify->BeforeSelectionChange(this, csValue); 1057 } 1058 if (GetType() == ComboBox) { 1059 iRet = m_pForm->m_pFormNotify->BeforeValueChange(this, csValue); 1060 } 1061 if (iRet < 0) { 1062 return FALSE; 1063 } 1064 } 1065 m_pDict->RemoveAt("I"); 1066 if (bNotify && m_pForm->m_pFormNotify != NULL) { 1067 if (GetType() == ListBox) { 1068 m_pForm->m_pFormNotify->AfterSelectionChange(this); 1069 } 1070 if (GetType() == ComboBox) { 1071 m_pForm->m_pFormNotify->AfterValueChange(this); 1072 } 1073 } 1074 m_pForm->m_bUpdated = TRUE; 1075 return TRUE; 1076 } 1077 void CPDF_FormField::LoadDA() 1078 { 1079 CFX_ByteString DA = FPDF_GetFieldAttr(m_pDict, "DA")->GetString(); 1080 if (DA.IsEmpty()) { 1081 DA = m_pForm->m_pFormDict->GetString("DA"); 1082 } 1083 if (DA.IsEmpty()) { 1084 return; 1085 } 1086 CPDF_SimpleParser syntax(DA); 1087 syntax.FindTagParam("Tf", 2); 1088 CFX_ByteString font_name = syntax.GetWord(); 1089 CPDF_Dictionary* pFontDict = m_pForm->m_pFormDict->GetDict("DR")->GetDict("Font")->GetDict(font_name); 1090 if (pFontDict == NULL) { 1091 return; 1092 } 1093 m_pFont = m_pForm->m_pDocument->LoadFont(pFontDict); 1094 m_FontSize = FX_atof(syntax.GetWord()); 1095 } 1096