| Index: core/fpdfdoc/cpdf_formfield.cpp
|
| diff --git a/core/fpdfdoc/doc_formfield.cpp b/core/fpdfdoc/cpdf_formfield.cpp
|
| similarity index 92%
|
| rename from core/fpdfdoc/doc_formfield.cpp
|
| rename to core/fpdfdoc/cpdf_formfield.cpp
|
| index cb1b0a4566001ce067a9f03667bfb57f2c5db678..81d217882097e0202aa3ddddc2dde8fe8c60600f 100644
|
| --- a/core/fpdfdoc/doc_formfield.cpp
|
| +++ b/core/fpdfdoc/cpdf_formfield.cpp
|
| @@ -14,12 +14,13 @@
|
| #include "core/fpdfapi/fpdf_parser/include/cpdf_string.h"
|
| #include "core/fpdfapi/fpdf_parser/include/fpdf_parser_decode.h"
|
| #include "core/fpdfdoc/cpvt_generateap.h"
|
| -#include "core/fpdfdoc/doc_utils.h"
|
| #include "core/fpdfdoc/include/cpdf_formcontrol.h"
|
| #include "core/fpdfdoc/include/cpdf_interform.h"
|
|
|
| namespace {
|
|
|
| +const int kMaxRecursion = 32;
|
| +
|
| const int kFormListMultiSelect = 0x100;
|
|
|
| const int kFormComboEdit = 0x100;
|
| @@ -36,15 +37,48 @@ const int kFormTextPassword = 0x200;
|
| const int kFormTextNoScroll = 0x400;
|
| const int kFormTextComb = 0x800;
|
|
|
| -bool PDF_FormField_IsUnison(CPDF_FormField* pField) {
|
| +bool IsUnison(CPDF_FormField* pField) {
|
| if (pField->GetType() == CPDF_FormField::CheckBox)
|
| return true;
|
| -
|
| return (pField->GetFieldFlags() & 0x2000000) != 0;
|
| }
|
|
|
| } // namespace
|
|
|
| +CPDF_Object* FPDF_GetFieldAttr(CPDF_Dictionary* pFieldDict,
|
| + const FX_CHAR* name,
|
| + int nLevel) {
|
| + if (nLevel > kMaxRecursion)
|
| + return nullptr;
|
| + if (!pFieldDict)
|
| + return nullptr;
|
| +
|
| + CPDF_Object* pAttr = pFieldDict->GetDirectObjectBy(name);
|
| + if (pAttr)
|
| + return pAttr;
|
| +
|
| + CPDF_Dictionary* pParent = pFieldDict->GetDictBy("Parent");
|
| + if (!pParent)
|
| + return nullptr;
|
| + return FPDF_GetFieldAttr(pParent, name, nLevel + 1);
|
| +}
|
| +
|
| +CFX_WideString FPDF_GetFullName(CPDF_Dictionary* pFieldDict) {
|
| + CFX_WideString full_name;
|
| + CPDF_Dictionary* pLevel = pFieldDict;
|
| + while (pLevel) {
|
| + CFX_WideString short_name = pLevel->GetUnicodeTextBy("T");
|
| + if (short_name != L"") {
|
| + if (full_name == L"")
|
| + full_name = short_name;
|
| + else
|
| + full_name = short_name + L"." + full_name;
|
| + }
|
| + pLevel = pLevel->GetDictBy("Parent");
|
| + }
|
| + return full_name;
|
| +}
|
| +
|
| CPDF_FormField::CPDF_FormField(CPDF_InterForm* pForm, CPDF_Dictionary* pDict)
|
| : m_Type(Unknown),
|
| m_pForm(pForm),
|
| @@ -64,24 +98,20 @@ void CPDF_FormField::SyncFieldFlags() {
|
| ? FPDF_GetFieldAttr(m_pDict, "Ff")->GetInteger()
|
| : 0;
|
| m_Flags = 0;
|
| - if (flags & 1) {
|
| + if (flags & 1)
|
| m_Flags |= kFormFieldReadOnly;
|
| - }
|
| - if (flags & 2) {
|
| + if (flags & 2)
|
| m_Flags |= kFormFieldRequired;
|
| - }
|
| - if (flags & 4) {
|
| + if (flags & 4)
|
| m_Flags |= kFormFieldNoExport;
|
| - }
|
| +
|
| if (type_name == "Btn") {
|
| if (flags & 0x8000) {
|
| m_Type = RadioButton;
|
| - if (flags & 0x4000) {
|
| + if (flags & 0x4000)
|
| m_Flags |= kFormRadioNoToggleOff;
|
| - }
|
| - if (flags & 0x2000000) {
|
| + if (flags & 0x2000000)
|
| m_Flags |= kFormRadioUnison;
|
| - }
|
| } else if (flags & 0x10000) {
|
| m_Type = PushButton;
|
| } else {
|
| @@ -94,39 +124,34 @@ void CPDF_FormField::SyncFieldFlags() {
|
| m_Type = RichText;
|
| } else {
|
| m_Type = Text;
|
| - if (flags & 0x1000) {
|
| + if (flags & 0x1000)
|
| m_Flags |= kFormTextMultiLine;
|
| - }
|
| - if (flags & 0x2000) {
|
| + if (flags & 0x2000)
|
| m_Flags |= kFormTextPassword;
|
| - }
|
| - if (flags & 0x800000) {
|
| + if (flags & 0x800000)
|
| m_Flags |= kFormTextNoScroll;
|
| - }
|
| - if (flags & 0x100000) {
|
| + if (flags & 0x100000)
|
| m_Flags |= kFormTextComb;
|
| - }
|
| }
|
| LoadDA();
|
| } else if (type_name == "Ch") {
|
| if (flags & 0x20000) {
|
| m_Type = ComboBox;
|
| - if (flags & 0x40000) {
|
| + if (flags & 0x40000)
|
| m_Flags |= kFormComboEdit;
|
| - }
|
| } else {
|
| m_Type = ListBox;
|
| - if (flags & 0x200000) {
|
| + if (flags & 0x200000)
|
| m_Flags |= kFormListMultiSelect;
|
| - }
|
| }
|
| LoadDA();
|
| } else if (type_name == "Sig") {
|
| m_Type = Sign;
|
| }
|
| }
|
| +
|
| CFX_WideString CPDF_FormField::GetFullName() const {
|
| - return ::GetFullName(m_pDict);
|
| + return FPDF_GetFullName(m_pDict);
|
| }
|
|
|
| FX_BOOL CPDF_FormField::ResetField(FX_BOOL bNotify) {
|
| @@ -137,20 +162,18 @@ FX_BOOL CPDF_FormField::ResetField(FX_BOOL bNotify) {
|
| if (iCount) {
|
| // TODO(weili): Check whether anything special needs to be done for
|
| // unison field. Otherwise, merge these branches.
|
| - if (PDF_FormField_IsUnison(this)) {
|
| - for (int i = 0; i < iCount; i++) {
|
| + if (IsUnison(this)) {
|
| + for (int i = 0; i < iCount; i++)
|
| CheckControl(i, GetControl(i)->IsDefaultChecked(), FALSE);
|
| - }
|
| } else {
|
| - for (int i = 0; i < iCount; i++) {
|
| + for (int i = 0; i < iCount; i++)
|
| CheckControl(i, GetControl(i)->IsDefaultChecked(), FALSE);
|
| - }
|
| }
|
| }
|
| - if (bNotify && m_pForm->m_pFormNotify) {
|
| + if (bNotify && m_pForm->m_pFormNotify)
|
| m_pForm->m_pFormNotify->AfterCheckedStatusChange(this);
|
| - }
|
| - } break;
|
| + break;
|
| + }
|
| case CPDF_FormField::ComboBox:
|
| case CPDF_FormField::ListBox: {
|
| CFX_WideString csValue;
|
| @@ -165,7 +188,8 @@ FX_BOOL CPDF_FormField::ResetField(FX_BOOL bNotify) {
|
| SetItemSelection(iIndex, TRUE);
|
| if (bNotify)
|
| NotifyListOrComboBoxAfterChange();
|
| - } break;
|
| + break;
|
| + }
|
| case CPDF_FormField::Text:
|
| case CPDF_FormField::RichText:
|
| case CPDF_FormField::File:
|
| @@ -203,7 +227,8 @@ FX_BOOL CPDF_FormField::ResetField(FX_BOOL bNotify) {
|
| }
|
| if (bNotify)
|
| NotifyAfterValueChange();
|
| - } break;
|
| + break;
|
| + }
|
| }
|
| return TRUE;
|
| }
|
| @@ -250,39 +275,29 @@ CPDF_AAction CPDF_FormField::GetAdditionalAction() const {
|
|
|
| CFX_WideString CPDF_FormField::GetAlternateName() const {
|
| CPDF_Object* pObj = FPDF_GetFieldAttr(m_pDict, "TU");
|
| - if (!pObj) {
|
| - return L"";
|
| - }
|
| - return pObj->GetUnicodeText();
|
| + return pObj ? pObj->GetUnicodeText() : L"";
|
| }
|
| +
|
| CFX_WideString CPDF_FormField::GetMappingName() const {
|
| CPDF_Object* pObj = FPDF_GetFieldAttr(m_pDict, "TM");
|
| - if (!pObj) {
|
| - return L"";
|
| - }
|
| - return pObj->GetUnicodeText();
|
| + return pObj ? pObj->GetUnicodeText() : L"";
|
| }
|
| +
|
| uint32_t CPDF_FormField::GetFieldFlags() const {
|
| CPDF_Object* pObj = FPDF_GetFieldAttr(m_pDict, "Ff");
|
| - if (!pObj) {
|
| - return 0;
|
| - }
|
| - return pObj->GetInteger();
|
| + return pObj ? pObj->GetInteger() : 0;
|
| }
|
| +
|
| CFX_ByteString CPDF_FormField::GetDefaultStyle() const {
|
| CPDF_Object* pObj = FPDF_GetFieldAttr(m_pDict, "DS");
|
| - if (!pObj) {
|
| - return "";
|
| - }
|
| - return pObj->GetString();
|
| + return pObj ? pObj->GetString() : "";
|
| }
|
| +
|
| CFX_WideString CPDF_FormField::GetRichTextString() const {
|
| CPDF_Object* pObj = FPDF_GetFieldAttr(m_pDict, "RV");
|
| - if (!pObj) {
|
| - return L"";
|
| - }
|
| - return pObj->GetUnicodeText();
|
| + return pObj ? pObj->GetUnicodeText() : L"";
|
| }
|
| +
|
| CFX_WideString CPDF_FormField::GetValue(FX_BOOL bDefault) const {
|
| if (GetType() == CheckBox || GetType() == RadioButton)
|
| return GetCheckValue(bDefault);
|
| @@ -290,16 +305,15 @@ CFX_WideString CPDF_FormField::GetValue(FX_BOOL bDefault) const {
|
| CPDF_Object* pValue = FPDF_GetFieldAttr(m_pDict, bDefault ? "DV" : "V");
|
| if (!pValue) {
|
| if (!bDefault) {
|
| - if (m_Type == RichText) {
|
| + if (m_Type == RichText)
|
| pValue = FPDF_GetFieldAttr(m_pDict, "V");
|
| - }
|
| - if (!pValue && m_Type != Text) {
|
| + if (!pValue && m_Type != Text)
|
| pValue = FPDF_GetFieldAttr(m_pDict, "DV");
|
| - }
|
| }
|
| if (!pValue)
|
| return CFX_WideString();
|
| }
|
| +
|
| switch (pValue->GetType()) {
|
| case CPDF_Object::STRING:
|
| case CPDF_Object::STREAM:
|
| @@ -356,7 +370,8 @@ FX_BOOL CPDF_FormField::SetValue(const CFX_WideString& value,
|
| }
|
| if (bNotify)
|
| NotifyAfterValueChange();
|
| - } break;
|
| + break;
|
| + }
|
| case ListBox: {
|
| int iIndex = FindOptionValue(value);
|
| if (iIndex < 0)
|
| @@ -444,9 +459,8 @@ int CPDF_FormField::GetSelectedIndex(int index) const {
|
| if (index < CountSelectedOptions()) {
|
| int iOptIndex = GetSelectedOptionIndex(index);
|
| CFX_WideString csOpt = GetOptionValue(iOptIndex);
|
| - if (csOpt == sel_value) {
|
| + if (csOpt == sel_value)
|
| return iOptIndex;
|
| - }
|
| }
|
| for (int i = 0; i < CountOptions(); i++) {
|
| if (sel_value == GetOptionValue(i))
|
| @@ -474,19 +488,17 @@ FX_BOOL CPDF_FormField::ClearSelection(FX_BOOL bNotify) {
|
|
|
| FX_BOOL CPDF_FormField::IsItemSelected(int index) const {
|
| ASSERT(GetType() == ComboBox || GetType() == ListBox);
|
| - if (index < 0 || index >= CountOptions()) {
|
| + if (index < 0 || index >= CountOptions())
|
| return FALSE;
|
| - }
|
| - if (IsOptionSelected(index)) {
|
| + if (IsOptionSelected(index))
|
| return TRUE;
|
| - }
|
| +
|
| CFX_WideString opt_value = GetOptionValue(index);
|
| CPDF_Object* pValue = FPDF_GetFieldAttr(m_pDict, "V");
|
| if (!pValue) {
|
| pValue = FPDF_GetFieldAttr(m_pDict, "I");
|
| - if (!pValue) {
|
| + if (!pValue)
|
| return FALSE;
|
| - }
|
| }
|
|
|
| if (pValue->IsString())
|
| @@ -623,9 +635,11 @@ CFX_WideString CPDF_FormField::GetOptionText(int index, int sub_index) const {
|
| CPDF_String* pString = ToString(pOption);
|
| return pString ? pString->GetUnicodeText() : CFX_WideString();
|
| }
|
| +
|
| CFX_WideString CPDF_FormField::GetOptionLabel(int index) const {
|
| return GetOptionText(index, 1);
|
| }
|
| +
|
| CFX_WideString CPDF_FormField::GetOptionValue(int index) const {
|
| return GetOptionText(index, 0);
|
| }
|
| @@ -707,37 +721,35 @@ FX_BOOL CPDF_FormField::CheckControl(int iControlIndex,
|
| bool bNotify) {
|
| ASSERT(GetType() == CheckBox || GetType() == RadioButton);
|
| CPDF_FormControl* pControl = GetControl(iControlIndex);
|
| - if (!pControl) {
|
| + if (!pControl)
|
| return FALSE;
|
| - }
|
| - if (!bChecked && pControl->IsChecked() == bChecked) {
|
| + if (!bChecked && pControl->IsChecked() == bChecked)
|
| return FALSE;
|
| - }
|
| +
|
| CFX_WideString csWExport = pControl->GetExportValue();
|
| CFX_ByteString csBExport = PDF_EncodeText(csWExport);
|
| int iCount = CountControls();
|
| - bool bUnison = PDF_FormField_IsUnison(this);
|
| + bool bUnison = IsUnison(this);
|
| for (int i = 0; i < iCount; i++) {
|
| CPDF_FormControl* pCtrl = GetControl(i);
|
| if (bUnison) {
|
| CFX_WideString csEValue = pCtrl->GetExportValue();
|
| if (csEValue == csWExport) {
|
| - if (pCtrl->GetOnStateName() == pControl->GetOnStateName()) {
|
| + if (pCtrl->GetOnStateName() == pControl->GetOnStateName())
|
| pCtrl->CheckControl(bChecked);
|
| - } else if (bChecked) {
|
| + else if (bChecked)
|
| pCtrl->CheckControl(FALSE);
|
| - }
|
| } else if (bChecked) {
|
| pCtrl->CheckControl(FALSE);
|
| }
|
| } else {
|
| - if (i == iControlIndex) {
|
| + if (i == iControlIndex)
|
| pCtrl->CheckControl(bChecked);
|
| - } else if (bChecked) {
|
| + else if (bChecked)
|
| pCtrl->CheckControl(FALSE);
|
| - }
|
| }
|
| }
|
| +
|
| CPDF_Object* pOpt = FPDF_GetFieldAttr(m_pDict, "Opt");
|
| if (!ToArray(pOpt)) {
|
| if (bChecked) {
|
| @@ -745,12 +757,10 @@ FX_BOOL CPDF_FormField::CheckControl(int iControlIndex,
|
| } else {
|
| CFX_ByteString csV;
|
| CPDF_Object* pV = FPDF_GetFieldAttr(m_pDict, "V");
|
| - if (pV) {
|
| + if (pV)
|
| csV = pV->GetString();
|
| - }
|
| - if (csV == csBExport) {
|
| + if (csV == csBExport)
|
| m_pDict->SetAtName("V", "Off");
|
| - }
|
| }
|
| } else if (bChecked) {
|
| CFX_ByteString csIndex;
|
|
|