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 #include "doc_utils.h" 9 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") ? FPDF_GetFieldAttr(m_pDict, "FT")->GetString() : CFX_ByteString(); 36 FX_DWORD flags = FPDF_GetFieldAttr(m_pDict, "Ff")? FPDF_GetFieldAttr(m_pDict, "Ff")->GetInteger() : 0; 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 if (pValue) { 328 return pValue->GetUnicodeText(); 329 } 330 break; 331 } 332 return CFX_WideString(); 333 } 334 CFX_WideString CPDF_FormField::GetValue() 335 { 336 return GetValue(FALSE); 337 } 338 CFX_WideString CPDF_FormField::GetDefaultValue() 339 { 340 return GetValue(TRUE); 341 } 342 FX_BOOL CPDF_FormField::SetValue(const CFX_WideString& value, FX_BOOL bDefault, FX_BOOL bNotify) 343 { 344 switch (m_Type) { 345 case CheckBox: 346 case RadioButton: { 347 SetCheckValue(value, bDefault, bNotify); 348 return TRUE; 349 } 350 case File: 351 case RichText: 352 case Text: 353 case ComboBox: { 354 CFX_WideString csValue = value; 355 if (bNotify && m_pForm->m_pFormNotify != NULL) { 356 int iRet = m_pForm->m_pFormNotify->BeforeValueChange(this, csValue); 357 if (iRet < 0) { 358 return FALSE; 359 } 360 } 361 int iIndex = FindOptionValue(csValue); 362 if (iIndex < 0) { 363 CFX_ByteString bsEncodeText = PDF_EncodeText(csValue); 364 m_pDict->SetAtString(bDefault ? "DV" : "V", bsEncodeText); 365 if (m_Type == RichText && !bDefault) { 366 m_pDict->SetAtString("RV", bsEncodeText); 367 } 368 m_pDict->RemoveAt("I"); 369 } else { 370 m_pDict->SetAtString(bDefault ? "DV" : "V", PDF_EncodeText(csValue)); 371 if (bDefault) { 372 } else { 373 ClearSelection(); 374 SetItemSelection(iIndex, TRUE); 375 } 376 } 377 if (bNotify && m_pForm->m_pFormNotify != NULL) { 378 m_pForm->m_pFormNotify->AfterValueChange(this); 379 } 380 m_pForm->m_bUpdated = TRUE; 381 } 382 break; 383 case ListBox: { 384 int iIndex = FindOptionValue(value); 385 if (iIndex < 0) { 386 return FALSE; 387 } 388 if (bDefault && iIndex == GetDefaultSelectedItem()) { 389 return FALSE; 390 } 391 if (bNotify && m_pForm->m_pFormNotify != NULL) { 392 CFX_WideString csValue = value; 393 int iRet = m_pForm->m_pFormNotify->BeforeSelectionChange(this, csValue); 394 if (iRet < 0) { 395 return FALSE; 396 } 397 } 398 if (bDefault) { 399 } else { 400 ClearSelection(); 401 SetItemSelection(iIndex, TRUE); 402 } 403 if (bNotify && m_pForm->m_pFormNotify != NULL) { 404 m_pForm->m_pFormNotify->AfterSelectionChange(this); 405 } 406 m_pForm->m_bUpdated = TRUE; 407 break; 408 } 409 default: 410 break; 411 } 412 if (CPDF_InterForm::m_bUpdateAP) { 413 UpdateAP(NULL); 414 } 415 return TRUE; 416 } 417 FX_BOOL CPDF_FormField::SetValue(const CFX_WideString& value, FX_BOOL bNotify) 418 { 419 return SetValue(value, FALSE, bNotify); 420 } 421 int CPDF_FormField::GetMaxLen() 422 { 423 CPDF_Object* pObj = FPDF_GetFieldAttr(m_pDict, "MaxLen"); 424 if (pObj == NULL) { 425 int iCount = m_ControlList.GetSize(); 426 for (int i = 0; i < iCount; i ++) { 427 CPDF_FormControl* pControl = (CPDF_FormControl*)m_ControlList.GetAt(i); 428 if (pControl == NULL) { 429 continue; 430 } 431 CPDF_Dictionary* pWidgetDict = pControl->m_pWidgetDict; 432 if (pWidgetDict->KeyExist("MaxLen")) { 433 return pWidgetDict->GetInteger("MaxLen"); 434 } 435 } 436 return 0; 437 } 438 return pObj->GetInteger(); 439 } 440 int CPDF_FormField::CountSelectedItems() 441 { 442 CPDF_Object* pValue = FPDF_GetFieldAttr(m_pDict, "V"); 443 if (pValue == NULL) { 444 pValue = FPDF_GetFieldAttr(m_pDict, "I"); 445 if (pValue == NULL) { 446 return 0; 447 } 448 } 449 if (pValue->GetType() == PDFOBJ_STRING) { 450 if (pValue->GetString().IsEmpty()) { 451 return 0; 452 } 453 return 1; 454 } 455 if (pValue->GetType() == PDFOBJ_NUMBER) { 456 if (pValue->GetString().IsEmpty()) { 457 return 0; 458 } 459 return 1; 460 } 461 if (pValue->GetType() != PDFOBJ_ARRAY) { 462 return 0; 463 } 464 return ((CPDF_Array*)pValue)->GetCount(); 465 } 466 int CPDF_FormField::GetSelectedIndex(int index) 467 { 468 CPDF_Object* pValue = FPDF_GetFieldAttr(m_pDict, "V"); 469 if (pValue == NULL) { 470 pValue = FPDF_GetFieldAttr(m_pDict, "I"); 471 if (pValue == NULL) { 472 return -1; 473 } 474 } 475 CFX_WideString sel_value; 476 if (pValue->GetType() == PDFOBJ_STRING) { 477 if (index != 0) { 478 return -1; 479 } 480 sel_value = pValue->GetUnicodeText(); 481 } else if (pValue->GetType() == PDFOBJ_NUMBER) { 482 return pValue->GetInteger(); 483 } else { 484 if (pValue->GetType() != PDFOBJ_ARRAY) { 485 return -1; 486 } 487 if (index < 0) { 488 return -1; 489 } 490 CPDF_Object* elementValue = ((CPDF_Array*)pValue)->GetElementValue(index); 491 sel_value = elementValue ? elementValue->GetUnicodeText() : CFX_WideString(); 492 } 493 if (index < CountSelectedOptions()) { 494 int iOptIndex = GetSelectedOptionIndex(index); 495 CFX_WideString csOpt = GetOptionValue(iOptIndex); 496 if (csOpt == sel_value) { 497 return iOptIndex; 498 } 499 } 500 int nOpts = CountOptions(); 501 for (int i = 0; i < nOpts; i ++) { 502 if (sel_value == GetOptionValue(i)) { 503 return i; 504 } 505 } 506 return -1; 507 } 508 FX_BOOL CPDF_FormField::ClearSelection(FX_BOOL bNotify) 509 { 510 if (bNotify && m_pForm->m_pFormNotify != NULL) { 511 int iRet = 0; 512 CFX_WideString csValue; 513 int iIndex = GetSelectedIndex(0); 514 if (iIndex >= 0) { 515 csValue = GetOptionLabel(iIndex); 516 } 517 if (GetType() == ListBox) { 518 iRet = m_pForm->m_pFormNotify->BeforeSelectionChange(this, csValue); 519 } 520 if (GetType() == ComboBox) { 521 iRet = m_pForm->m_pFormNotify->BeforeValueChange(this, csValue); 522 } 523 if (iRet < 0) { 524 return FALSE; 525 } 526 } 527 m_pDict->RemoveAt("V"); 528 m_pDict->RemoveAt("I"); 529 if (bNotify && m_pForm->m_pFormNotify != NULL) { 530 if (GetType() == ListBox) { 531 m_pForm->m_pFormNotify->AfterSelectionChange(this); 532 } 533 if (GetType() == ComboBox) { 534 m_pForm->m_pFormNotify->AfterValueChange(this); 535 } 536 } 537 if (CPDF_InterForm::m_bUpdateAP) { 538 UpdateAP(NULL); 539 } 540 m_pForm->m_bUpdated = TRUE; 541 return TRUE; 542 } 543 FX_BOOL CPDF_FormField::IsItemSelected(int index) 544 { 545 ASSERT(GetType() == ComboBox || GetType() == ListBox); 546 if (index < 0 || index >= CountOptions()) { 547 return FALSE; 548 } 549 if (IsOptionSelected(index)) { 550 return TRUE; 551 } 552 CFX_WideString opt_value = GetOptionValue(index); 553 CPDF_Object* pValue = FPDF_GetFieldAttr(m_pDict, "V"); 554 if (pValue == NULL) { 555 pValue = FPDF_GetFieldAttr(m_pDict, "I"); 556 if (pValue == NULL) { 557 return FALSE; 558 } 559 } 560 if (pValue->GetType() == PDFOBJ_STRING) { 561 if (pValue->GetUnicodeText() == opt_value) { 562 return TRUE; 563 } 564 return FALSE; 565 } 566 if (pValue->GetType() == PDFOBJ_NUMBER) { 567 if (pValue->GetString().IsEmpty()) { 568 return FALSE; 569 } 570 if (pValue->GetInteger() == index) { 571 return TRUE; 572 } 573 return FALSE; 574 } 575 if (pValue->GetType() != PDFOBJ_ARRAY) { 576 return FALSE; 577 } 578 CPDF_Array* pArray = (CPDF_Array*)pValue; 579 int iPos = -1; 580 for (int j = 0; j < CountSelectedOptions(); j ++) { 581 if (GetSelectedOptionIndex(j) == index) { 582 iPos = j; 583 break; 584 } 585 } 586 for (FX_DWORD i = 0; i < pArray->GetCount(); i ++) 587 if (pArray->GetElementValue(i)->GetUnicodeText() == opt_value && (int)i == iPos) { 588 return TRUE; 589 } 590 return FALSE; 591 } 592 FX_BOOL CPDF_FormField::SetItemSelection(int index, FX_BOOL bSelected, FX_BOOL bNotify) 593 { 594 ASSERT(GetType() == ComboBox || GetType() == ListBox); 595 if (index < 0 || index >= CountOptions()) { 596 return FALSE; 597 } 598 CFX_WideString opt_value = GetOptionValue(index); 599 if (bNotify && m_pForm->m_pFormNotify != NULL) { 600 int iRet = 0; 601 if (GetType() == ListBox) { 602 iRet = m_pForm->m_pFormNotify->BeforeSelectionChange(this, opt_value); 603 } 604 if (GetType() == ComboBox) { 605 iRet = m_pForm->m_pFormNotify->BeforeValueChange(this, opt_value); 606 } 607 if (iRet < 0) { 608 return FALSE; 609 } 610 } 611 if (!bSelected) { 612 CPDF_Object* pValue = FPDF_GetFieldAttr(m_pDict, "V"); 613 if (pValue != NULL) { 614 if (m_Type == ListBox) { 615 SelectOption(index, FALSE); 616 if (pValue->GetType() == PDFOBJ_STRING) { 617 if (pValue->GetUnicodeText() == opt_value) { 618 m_pDict->RemoveAt("V"); 619 } 620 } else if (pValue->GetType() == PDFOBJ_ARRAY) { 621 CPDF_Array* pArray = CPDF_Array::Create(); 622 if (pArray == NULL) { 623 return FALSE; 624 } 625 int iCount = CountOptions(); 626 for (int i = 0; i < iCount; i ++) { 627 if (i != index) { 628 if (IsItemSelected(i)) { 629 opt_value = GetOptionValue(i); 630 pArray->AddString(PDF_EncodeText(opt_value)); 631 } 632 } 633 } 634 if (pArray->GetCount() < 1) { 635 pArray->Release(); 636 } else { 637 m_pDict->SetAt("V", pArray); 638 } 639 } 640 } else if (m_Type == ComboBox) { 641 m_pDict->RemoveAt("V"); 642 m_pDict->RemoveAt("I"); 643 } 644 } 645 } else { 646 if (m_Type == ListBox) { 647 SelectOption(index, TRUE); 648 if (!(m_Flags & FORMLIST_MULTISELECT)) { 649 m_pDict->SetAtString("V", PDF_EncodeText(opt_value)); 650 } else { 651 CPDF_Array* pArray = CPDF_Array::Create(); 652 if (pArray == NULL) { 653 return FALSE; 654 } 655 FX_BOOL bSelected; 656 int iCount = CountOptions(); 657 for (int i = 0; i < iCount; i ++) { 658 if (i != index) { 659 bSelected = IsItemSelected(i); 660 } else { 661 bSelected = TRUE; 662 } 663 if (bSelected) { 664 opt_value = GetOptionValue(i); 665 pArray->AddString(PDF_EncodeText(opt_value)); 666 } 667 } 668 m_pDict->SetAt("V", pArray); 669 } 670 } else if (m_Type == ComboBox) { 671 m_pDict->SetAtString("V", PDF_EncodeText(opt_value)); 672 CPDF_Array* pI = CPDF_Array::Create(); 673 if (pI == NULL) { 674 return FALSE; 675 } 676 pI->AddInteger(index); 677 m_pDict->SetAt("I", pI); 678 } 679 } 680 if (bNotify && m_pForm->m_pFormNotify != NULL) { 681 if (GetType() == ListBox) { 682 m_pForm->m_pFormNotify->AfterSelectionChange(this); 683 } 684 if (GetType() == ComboBox) { 685 m_pForm->m_pFormNotify->AfterValueChange(this); 686 } 687 } 688 if (CPDF_InterForm::m_bUpdateAP) { 689 UpdateAP(NULL); 690 } 691 m_pForm->m_bUpdated = TRUE; 692 return TRUE; 693 } 694 FX_BOOL CPDF_FormField::IsItemDefaultSelected(int index) 695 { 696 ASSERT(GetType() == ComboBox || GetType() == ListBox); 697 if (index < 0 || index >= CountOptions()) { 698 return FALSE; 699 } 700 int iDVIndex = GetDefaultSelectedItem(); 701 if (iDVIndex < 0) { 702 return FALSE; 703 } 704 return (iDVIndex == index); 705 } 706 int CPDF_FormField::GetDefaultSelectedItem() 707 { 708 ASSERT(GetType() == ComboBox || GetType() == ListBox); 709 CPDF_Object* pValue = FPDF_GetFieldAttr(m_pDict, "DV"); 710 if (pValue == NULL) { 711 return -1; 712 } 713 CFX_WideString csDV = pValue->GetUnicodeText(); 714 if (csDV.IsEmpty()) { 715 return -1; 716 } 717 int iCount = CountOptions(); 718 for (int i = 0; i < iCount; i ++) { 719 if (csDV == GetOptionValue(i)) { 720 return i; 721 } 722 } 723 return -1; 724 } 725 void CPDF_FormField::UpdateAP(CPDF_FormControl* pControl) 726 { 727 if (m_Type == PushButton) { 728 return; 729 } 730 if (m_Type == RadioButton || m_Type == CheckBox) { 731 return; 732 } 733 if (!m_pForm->m_bGenerateAP) { 734 return; 735 } 736 for (int i = 0; i < CountControls(); i ++) { 737 CPDF_FormControl* pControl = GetControl(i); 738 FPDF_GenerateAP(m_pForm->m_pDocument, pControl->m_pWidgetDict); 739 } 740 } 741 int CPDF_FormField::CountOptions() 742 { 743 CPDF_Object* pValue = FPDF_GetFieldAttr(m_pDict, "Opt"); 744 if (pValue == NULL || pValue->GetType() != PDFOBJ_ARRAY) { 745 return 0; 746 } 747 return ((CPDF_Array*)pValue)->GetCount(); 748 } 749 CFX_WideString CPDF_FormField::GetOptionText(int index, int sub_index) 750 { 751 CPDF_Object* pValue = FPDF_GetFieldAttr(m_pDict, "Opt"); 752 if (pValue == NULL || pValue->GetType() != PDFOBJ_ARRAY) { 753 return CFX_WideString(); 754 } 755 CPDF_Object* pOption = ((CPDF_Array*)pValue)->GetElementValue(index); 756 if (pOption == NULL) { 757 return CFX_WideString(); 758 } 759 if (pOption->GetType() == PDFOBJ_ARRAY) { 760 pOption = ((CPDF_Array*)pOption)->GetElementValue(sub_index); 761 } 762 if (pOption == NULL || pOption->GetType() != PDFOBJ_STRING) { 763 return CFX_WideString(); 764 } 765 return ((CPDF_String*)pOption)->GetUnicodeText(); 766 } 767 CFX_WideString CPDF_FormField::GetOptionLabel(int index) 768 { 769 return GetOptionText(index, 1); 770 } 771 CFX_WideString CPDF_FormField::GetOptionValue(int index) 772 { 773 return GetOptionText(index, 0); 774 } 775 int CPDF_FormField::FindOption(CFX_WideString csOptLabel) 776 { 777 int iCount = CountOptions(); 778 for (int i = 0; i < iCount; i ++) { 779 CFX_WideString csValue = GetOptionValue(i); 780 if (csValue == csOptLabel) { 781 return i; 782 } 783 } 784 return -1; 785 } 786 int CPDF_FormField::FindOptionValue(const CFX_WideString& csOptValue, int iStartIndex) 787 { 788 if (iStartIndex < 0) { 789 iStartIndex = 0; 790 } 791 int iCount = CountOptions(); 792 for (; iStartIndex < iCount; iStartIndex ++) { 793 CFX_WideString csValue = GetOptionValue(iStartIndex); 794 if (csValue == csOptValue) { 795 return iStartIndex; 796 } 797 } 798 return -1; 799 } 800 FX_BOOL CPDF_FormField::CheckControl(int iControlIndex, FX_BOOL bChecked, FX_BOOL bNotify) 801 { 802 ASSERT(GetType() == CheckBox || GetType() == RadioButton); 803 CPDF_FormControl* pControl = GetControl(iControlIndex); 804 if (pControl == NULL) { 805 return FALSE; 806 } 807 if (!bChecked && pControl->IsChecked() == bChecked) { 808 return FALSE; 809 } 810 CFX_ByteArray statusArray; 811 if (bNotify && m_pForm->m_pFormNotify != NULL) { 812 SaveCheckedFieldStatus(this, statusArray); 813 } 814 CFX_WideString csWExport = pControl->GetExportValue(); 815 CFX_ByteString csBExport = PDF_EncodeText(csWExport); 816 int iCount = CountControls(); 817 FX_BOOL bUnison = PDF_FormField_IsUnison(this); 818 for (int i = 0; i < iCount; i ++) { 819 CPDF_FormControl* pCtrl = GetControl(i); 820 if (bUnison) { 821 CFX_WideString csEValue = pCtrl->GetExportValue(); 822 if (csEValue == csWExport) { 823 if (pCtrl->GetOnStateName() == pControl->GetOnStateName()) { 824 pCtrl->CheckControl(bChecked); 825 } else if (bChecked) { 826 pCtrl->CheckControl(FALSE); 827 } 828 } else if (bChecked) { 829 pCtrl->CheckControl(FALSE); 830 } 831 } else { 832 if (i == iControlIndex) { 833 pCtrl->CheckControl(bChecked); 834 } else if (bChecked) { 835 pCtrl->CheckControl(FALSE); 836 } 837 } 838 } 839 CPDF_Object* pOpt = FPDF_GetFieldAttr(m_pDict, "Opt"); 840 if (pOpt == NULL || pOpt->GetType() != PDFOBJ_ARRAY) { 841 if (bChecked) { 842 m_pDict->SetAtName("V", csBExport); 843 } else { 844 CFX_ByteString csV; 845 CPDF_Object* pV = FPDF_GetFieldAttr(m_pDict, "V"); 846 if (pV != NULL) { 847 csV = pV->GetString(); 848 } 849 if (csV == csBExport) { 850 m_pDict->SetAtName("V", "Off"); 851 } 852 } 853 } else if (bChecked) { 854 CFX_ByteString csIndex; 855 csIndex.Format("%d", iControlIndex); 856 m_pDict->SetAtName("V", csIndex); 857 } 858 if (bNotify && m_pForm->m_pFormNotify != NULL) { 859 m_pForm->m_pFormNotify->AfterCheckedStatusChange(this, statusArray); 860 } 861 m_pForm->m_bUpdated = TRUE; 862 return TRUE; 863 } 864 CFX_WideString CPDF_FormField::GetCheckValue(FX_BOOL bDefault) 865 { 866 ASSERT(GetType() == CheckBox || GetType() == RadioButton); 867 CFX_WideString csExport = L"Off"; 868 FX_BOOL bChecked; 869 int iCount = CountControls(); 870 for (int i = 0; i < iCount; i ++) { 871 CPDF_FormControl* pControl = GetControl(i); 872 if (bDefault) { 873 bChecked = pControl->IsDefaultChecked(); 874 } else { 875 bChecked = pControl->IsChecked(); 876 } 877 if (bChecked) { 878 csExport = pControl->GetExportValue(); 879 break; 880 } 881 } 882 return csExport; 883 } 884 FX_BOOL CPDF_FormField::SetCheckValue(const CFX_WideString& value, FX_BOOL bDefault, FX_BOOL bNotify) 885 { 886 ASSERT(GetType() == CheckBox || GetType() == RadioButton); 887 CFX_ByteArray statusArray; 888 if (bNotify && m_pForm->m_pFormNotify != NULL) { 889 SaveCheckedFieldStatus(this, statusArray); 890 } 891 int iCount = CountControls(); 892 for (int i = 0; i < iCount; i ++) { 893 CPDF_FormControl* pControl = GetControl(i); 894 CFX_WideString csExport = pControl->GetExportValue(); 895 if (csExport == value) { 896 if (bDefault) { 897 } else { 898 CheckControl(GetControlIndex(pControl), TRUE); 899 } 900 break; 901 } else { 902 if (bDefault) { 903 } else { 904 CheckControl(GetControlIndex(pControl), FALSE); 905 } 906 } 907 } 908 if (bNotify && m_pForm->m_pFormNotify != NULL) { 909 m_pForm->m_pFormNotify->AfterCheckedStatusChange(this, statusArray); 910 } 911 m_pForm->m_bUpdated = TRUE; 912 return TRUE; 913 } 914 int CPDF_FormField::GetTopVisibleIndex() 915 { 916 CPDF_Object* pObj = FPDF_GetFieldAttr(m_pDict, "TI"); 917 if (pObj == NULL) { 918 return 0; 919 } 920 return pObj->GetInteger(); 921 } 922 int CPDF_FormField::CountSelectedOptions() 923 { 924 CPDF_Object* pObj = FPDF_GetFieldAttr(m_pDict, "I"); 925 if (pObj == NULL) { 926 return 0; 927 } 928 CPDF_Array* pArray = pObj->GetArray(); 929 if (pArray == NULL) { 930 return 0; 931 } 932 return (int)pArray->GetCount(); 933 } 934 int CPDF_FormField::GetSelectedOptionIndex(int index) 935 { 936 CPDF_Object* pObj = FPDF_GetFieldAttr(m_pDict, "I"); 937 if (pObj == NULL) { 938 return -1; 939 } 940 CPDF_Array* pArray = pObj->GetArray(); 941 if (pArray == NULL) { 942 return -1; 943 } 944 int iCount = (int)pArray->GetCount(); 945 if (iCount > 0 && index < iCount) { 946 return pArray->GetInteger(index); 947 } 948 return -1; 949 } 950 FX_BOOL CPDF_FormField::IsOptionSelected(int iOptIndex) 951 { 952 CPDF_Object* pObj = FPDF_GetFieldAttr(m_pDict, "I"); 953 if (pObj == NULL) { 954 return FALSE; 955 } 956 CPDF_Array* pArray = pObj->GetArray(); 957 if (pArray == NULL) { 958 return FALSE; 959 } 960 int iCount = (int)pArray->GetCount(); 961 for (int i = 0; i < iCount; i ++) { 962 if (pArray->GetInteger(i) == iOptIndex) { 963 return TRUE; 964 } 965 } 966 return FALSE; 967 } 968 FX_BOOL CPDF_FormField::SelectOption(int iOptIndex, FX_BOOL bSelected, FX_BOOL bNotify) 969 { 970 CPDF_Array* pArray = m_pDict->GetArray("I"); 971 if (pArray == NULL) { 972 if (!bSelected) { 973 return TRUE; 974 } 975 pArray = CPDF_Array::Create(); 976 if (pArray == NULL) { 977 return FALSE; 978 } 979 m_pDict->SetAt("I", pArray); 980 } 981 FX_BOOL bReturn = FALSE; 982 for (int i = 0; i < (int)pArray->GetCount(); i ++) { 983 int iFind = pArray->GetInteger(i); 984 if (iFind == iOptIndex) { 985 if (bSelected) { 986 return TRUE; 987 } 988 if (bNotify && m_pForm->m_pFormNotify != NULL) { 989 int iRet = 0; 990 CFX_WideString csValue = GetOptionLabel(iOptIndex); 991 if (GetType() == ListBox) { 992 iRet = m_pForm->m_pFormNotify->BeforeSelectionChange(this, csValue); 993 } 994 if (GetType() == ComboBox) { 995 iRet = m_pForm->m_pFormNotify->BeforeValueChange(this, csValue); 996 } 997 if (iRet < 0) { 998 return FALSE; 999 } 1000 } 1001 pArray->RemoveAt(i); 1002 bReturn = TRUE; 1003 break; 1004 } else if (iFind > iOptIndex) { 1005 if (!bSelected) { 1006 continue; 1007 } 1008 if (bNotify && m_pForm->m_pFormNotify != NULL) { 1009 int iRet = 0; 1010 CFX_WideString csValue = GetOptionLabel(iOptIndex); 1011 if (GetType() == ListBox) { 1012 iRet = m_pForm->m_pFormNotify->BeforeSelectionChange(this, csValue); 1013 } 1014 if (GetType() == ComboBox) { 1015 iRet = m_pForm->m_pFormNotify->BeforeValueChange(this, csValue); 1016 } 1017 if (iRet < 0) { 1018 return FALSE; 1019 } 1020 } 1021 CPDF_Number* pNum = CPDF_Number::Create(iOptIndex); 1022 if (pNum == NULL) { 1023 return FALSE; 1024 } 1025 pArray->InsertAt(i, pNum); 1026 bReturn = TRUE; 1027 break; 1028 } 1029 } 1030 if (!bReturn) { 1031 if (bSelected) { 1032 pArray->AddInteger(iOptIndex); 1033 } 1034 if (pArray->GetCount() == 0) { 1035 m_pDict->RemoveAt("I"); 1036 } 1037 } 1038 if (bNotify && m_pForm->m_pFormNotify != NULL) { 1039 if (GetType() == ListBox) { 1040 m_pForm->m_pFormNotify->AfterSelectionChange(this); 1041 } 1042 if (GetType() == ComboBox) { 1043 m_pForm->m_pFormNotify->AfterValueChange(this); 1044 } 1045 } 1046 m_pForm->m_bUpdated = TRUE; 1047 return TRUE; 1048 } 1049 FX_BOOL CPDF_FormField::ClearSelectedOptions(FX_BOOL bNotify) 1050 { 1051 if (bNotify && m_pForm->m_pFormNotify != NULL) { 1052 int iRet = 0; 1053 CFX_WideString csValue; 1054 int iIndex = GetSelectedIndex(0); 1055 if (iIndex >= 0) { 1056 csValue = GetOptionLabel(iIndex); 1057 } 1058 if (GetType() == ListBox) { 1059 iRet = m_pForm->m_pFormNotify->BeforeSelectionChange(this, csValue); 1060 } 1061 if (GetType() == ComboBox) { 1062 iRet = m_pForm->m_pFormNotify->BeforeValueChange(this, csValue); 1063 } 1064 if (iRet < 0) { 1065 return FALSE; 1066 } 1067 } 1068 m_pDict->RemoveAt("I"); 1069 if (bNotify && m_pForm->m_pFormNotify != NULL) { 1070 if (GetType() == ListBox) { 1071 m_pForm->m_pFormNotify->AfterSelectionChange(this); 1072 } 1073 if (GetType() == ComboBox) { 1074 m_pForm->m_pFormNotify->AfterValueChange(this); 1075 } 1076 } 1077 m_pForm->m_bUpdated = TRUE; 1078 return TRUE; 1079 } 1080 void CPDF_FormField::LoadDA() 1081 { 1082 CFX_ByteString DA; 1083 if (CPDF_Object* pObj_t = FPDF_GetFieldAttr(m_pDict, "DA")) { 1084 DA = pObj_t->GetString(); 1085 } 1086 if (DA.IsEmpty() && m_pForm->m_pFormDict) { 1087 DA = m_pForm->m_pFormDict->GetString("DA"); 1088 } 1089 if (DA.IsEmpty()) { 1090 return; 1091 } 1092 CPDF_SimpleParser syntax(DA); 1093 syntax.FindTagParam("Tf", 2); 1094 CFX_ByteString font_name = syntax.GetWord(); 1095 CPDF_Dictionary* pFontDict = NULL; 1096 if (m_pForm->m_pFormDict && m_pForm->m_pFormDict->GetDict("DR") && 1097 m_pForm->m_pFormDict->GetDict("DR")->GetDict("Font") ) 1098 pFontDict = m_pForm->m_pFormDict->GetDict("DR")->GetDict("Font")->GetDict(font_name); 1099 1100 if (pFontDict == NULL) { 1101 return; 1102 } 1103 m_pFont = m_pForm->m_pDocument->LoadFont(pFontDict); 1104 m_FontSize = FX_atof(syntax.GetWord()); 1105 } 1106