Test radiobutton и checkbox annots

This commit is contained in:
Svetlana Kulikova
2023-12-11 18:07:13 +03:00
parent 99d72986d8
commit ac711129e3
10 changed files with 114 additions and 37 deletions

View File

@ -675,7 +675,9 @@ void CAnnotFieldInfo::CWidgetAnnotPr::Read(NSOnlineOfficeBinToPdf::CBufferReader
for (int i = 0; i < n; ++i)
m_arrTC.push_back(pReader->ReadDouble());
m_nQ = pReader->ReadByte();
m_nQ = 0;
if (nType != 29 && nType != 28)
m_nQ = pReader->ReadByte();
int nWidgetFlag = pReader->ReadInt();
m_nFlag = nWidgetFlag;
@ -730,6 +732,8 @@ void CAnnotFieldInfo::CWidgetAnnotPr::Read(NSOnlineOfficeBinToPdf::CBufferReader
}
void CAnnotFieldInfo::CWidgetAnnotPr::CButtonWidgetPr::Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, BYTE nType, int nFlags)
{
if (nFlags & (1 << 9))
m_wsV = pReader->ReadString();
int nIFFlags = pReader->ReadInt();
m_nIFFlag = nIFFlags;
if (nType == 27)

View File

@ -63,6 +63,7 @@ public:
BYTE GetStyle() const { return m_nStyle; }
int GetIFFlag() const { return m_nIFFlag; }
void GetA(double& dA1, double& dA2) const { dA1 = m_dA1; dA2 = m_dA2; }
const std::wstring& GetV() const { return m_wsV; }
const std::wstring& GetCA() const { return m_wsCA; }
const std::wstring& GetRC() const { return m_wsRC; }
const std::wstring& GetAC() const { return m_wsAC; }
@ -77,6 +78,7 @@ public:
BYTE m_nStyle;
int m_nIFFlag;
double m_dA1, m_dA2;
std::wstring m_wsV;
std::wstring m_wsCA;
std::wstring m_wsRC;
std::wstring m_wsAC;

View File

@ -791,7 +791,8 @@
// Widget types
if (rec["type"] == 29 || rec["type"] == 28 || rec["type"] == 27)
{
rec["value"] = (flags & (1 << 9)) ? "Yes" : "Off";
if (flags & (1 << 9))
rec["value"] = reader.readString();
let IFflags = reader.readInt();
// MK
if (rec["type"] == 27)
@ -834,11 +835,7 @@
rec["IF"]["FB"] = (IFflags >> 4) & 1;
}
if (flags & (1 << 14))
{
rec["ExportValue"] = reader.readString();
if (flags & (1 << 9))
rec["value"] = rec["ExportValue"];
}
// 12.7.4.2.1
rec["NoToggleToOff"] = (rec["flag"] >> 14) & 1; // NoToggleToOff
rec["radiosInUnison"] = (rec["flag"] >> 25) & 1; // RadiosInUnison

View File

@ -493,7 +493,13 @@ void ReadInteractiveForms(BYTE* pWidgets, int& i)
if (sType == "checkbox" || sType == "radiobutton" || sType == "button")
{
std::cout << (nFlags & (1 << 9) ? "Yes" : "Off") << ", ";
if (nFlags & (1 << 9))
{
nPathLength = READ_INT(pWidgets + i);
i += 4;
std::cout << "Value " << std::string((char*)(pWidgets + i), nPathLength) << ", ";
i += nPathLength;
}
int nIFFlag = READ_INT(pWidgets + i);
i += 4;

View File

@ -120,7 +120,7 @@ void DictToCDictObject(Object* obj, PdfWriter::CObjectBase* pObj, bool bBinary,
PdfWriter::CArrayObject* pArray = new PdfWriter::CArrayObject();
AddToObject(pArray)
for (int nIndex = 0; nIndex < obj->arrayGetLength(); ++nIndex)
for (int nIndex = 0; nIndex < obj->arrayGetLength(); ++nIndex)
{
obj->arrayGetNF(nIndex, &oTemp);
DictToCDictObject(&oTemp, pArray, bBinary, "");
@ -923,8 +923,6 @@ bool CPdfFile::EditAnnot(int nPageIndex, int nID)
for (int nIndex = 0; nIndex < oAnnot.dictGetLength(); ++nIndex)
{
char* chKey = oAnnot.dictGetKey(nIndex);
if (strcmp("AP", chKey) == 0)
continue;
if (strcmp("Popup", chKey) == 0)
{
Object oPopupRef;
@ -945,12 +943,29 @@ bool CPdfFile::EditAnnot(int nPageIndex, int nID)
oAnnot.dictGetValNF(nIndex, &oParentRef);
PdfWriter::CDictObject* pParent = GetWidgetParent(pPDFDocument, pDoc, &oParentRef);
if (pParent)
if (!pParent)
{
((PdfWriter::CWidgetAnnotation*)pAnnot)->SetParent(pParent);
oParentRef.free();
continue;
}
((PdfWriter::CWidgetAnnotation*)pAnnot)->SetParent(pParent);
PdfWriter::CArrayObject* pKids = dynamic_cast<PdfWriter::CArrayObject*>(pParent->Get("Kids"));
if (!pKids)
{
oParentRef.free();
continue;
}
for (int i = 0; i < pKids->GetCount(); ++i)
{
PdfWriter::CObjectBase* pKid = pKids->Get(i);
if (pKid->GetObjId() == oAnnotRef.getRefNum())
{
pKids->Insert(pKid, pAnnot, true);
break;
}
}
oParentRef.free();
}
Object oTemp;
@ -1032,11 +1047,15 @@ bool CPdfFile::EditWidgets(IAdvancedCommand* pCommand)
std::vector<CWidgetsInfo::CParent*> arrParents = pFieldInfo->GetParents();
for (CWidgetsInfo::CParent* pParent : arrParents)
{
PdfWriter::CDictObject* pDParent = pDoc->GetParent(pParent->nID);
if (pDParent)
continue;
Object oParentRef;
// TODO узнать gen родителя
oParentRef.initRef(pParent->nID, 0);
GetWidgetParent(pPDFDocument, pDoc, &oParentRef);
// TODO перевыставить детей
oParentRef.free();
}

View File

@ -2031,7 +2031,8 @@ HRESULT CPdfWriter::AddAnnotField(NSFonts::IApplicationFonts* pAppFonts, CAnnotF
pWidgetAnnot->SetDA(pFontTT, pPr->GetFontSize(), dFontSize, pPr->GetTC());
BYTE nAlign = pPr->GetQ();
pWidgetAnnot->SetQ(nAlign);
if (nWidgetType != 28 && nWidgetType != 29)
pWidgetAnnot->SetQ(nAlign);
int nWidgetFlag = pPr->GetFlag();
pWidgetAnnot->SetFlag(nWidgetFlag);
@ -2155,7 +2156,12 @@ HRESULT CPdfWriter::AddAnnotField(NSFonts::IApplicationFonts* pAppFonts, CAnnotF
if (nFlags & (1 << 14))
pButtonWidget->SetAP_N_Yes(pPr->GetAP_N_Yes());
pButtonWidget->SetV(((bool)(nFlags >> 9) & 1));
std::wstring wsValue;
if (nFlags & (1 << 9))
{
wsValue = pPr->GetV();
pButtonWidget->SetV(wsValue);
}
if (nWidgetType == 27) // button
{
@ -2190,11 +2196,9 @@ HRESULT CPdfWriter::AddAnnotField(NSFonts::IApplicationFonts* pAppFonts, CAnnotF
std::wstring wsValue = pButtonWidget->SetStyle(pPr->GetStyle());
// ВНЕШНИЙ ВИД
// TODO сейчас редактирование внешних видов форм не происходит
bool bSwitch = true;
if (bSwitch && pButtonWidget->Get("AP"))
if (pButtonWidget->Get("AP") && !wsValue.empty())
{
pButtonWidget->SwitchAP();
pButtonWidget->SwitchAP(U_TO_UTF8(wsValue));
return S_OK;
}
@ -2485,7 +2489,22 @@ HRESULT CPdfWriter::EditWidgetParents(CWidgetsInfo* pFieldInfo)
if (nFlags & (1 << 0))
pParentObj->Add("T", new PdfWriter::CStringObject((U_TO_UTF8(pParent->sName)).c_str()));
if (nFlags & (1 << 1))
pParentObj->Add("V", new PdfWriter::CStringObject((U_TO_UTF8(pParent->sV)).c_str()));
{
std::string sV = U_TO_UTF8(pParent->sV);
pParentObj->Add("V", new PdfWriter::CStringObject(sV.c_str()));
PdfWriter::CObjectBase* pKids = pParentObj->Get("Kids");
if (pKids && pKids->GetType() == PdfWriter::object_type_ARRAY)
{
PdfWriter::CArrayObject* pAKids = (PdfWriter::CArrayObject*)pKids;
for (int i = 0; i < pAKids->GetCount(); ++i)
{
PdfWriter::CButtonWidget* pKid = dynamic_cast<PdfWriter::CButtonWidget*>(pAKids->Get(i));
if (pKid)
pKid->SwitchAP(sV);
}
}
}
if (nFlags & (1 << 2))
pParentObj->Add("DV", new PdfWriter::CStringObject((U_TO_UTF8(pParent->sDV)).c_str()));
if (nFlags & (1 << 3))

View File

@ -454,21 +454,25 @@ CAnnotWidgetBtn::CAnnotWidgetBtn(PDFDoc* pdfDoc, AcroFormField* pField) : CAnnot
m_unIFFlag = 0;
Object oObj;
Object oFieldRef, oField;
pField->getFieldRef(&oFieldRef);
oFieldRef.fetch(pdfDoc->getXRef(), &oField);
oFieldRef.free();
// Значение поля - V
int nValueLength;
Unicode* pValue = pField->getValue(&nValueLength);
std::string sValue = NSStringExt::CConverter::GetUtf8FromUTF32(pValue, nValueLength);
gfree(pValue);
if (oField.dictLookup("V", &oObj))
{
m_sV = getValue(&oObj);
if (!m_sV.empty())
m_unFlags |= (1 << 9);
}
oObj.free();
oField.free();
if (pField->fieldLookup("AS", &oObj)->isName())
sValue = oObj.getName();
m_sV = oObj.getName();
oObj.free();
// 10 - Включено
if (sValue != "Off")
m_unFlags |= (1 << 9);
Object oMK;
AcroFormFieldType oType = pField->getAcroFormFieldType();
m_nStyle = (oType == acroFormFieldRadioButton ? 3 : 0);
@ -2667,6 +2671,8 @@ void CAnnotWidgetBtn::ToWASM(NSWasm::CData& oRes)
{
CAnnotWidget::ToWASM(oRes);
if (m_unFlags & (1 << 9))
oRes.WriteString(m_sV);
oRes.AddInt(m_unIFFlag);
if (m_nType == 27)
{

View File

@ -254,6 +254,7 @@ private:
BYTE m_nSW;
BYTE m_nS;
unsigned int m_unIFFlag;
std::string m_sV;
std::string m_sCA;
std::string m_sRC;
std::string m_sAC;

View File

@ -851,6 +851,25 @@ namespace PdfWriter
}
return NULL;
}
CObjectBase* CWidgetAnnotation::GetObjValue(const std::string& sV)
{
CObjectBase* pRes = Get(sV);
if (pRes)
return pRes;
CDictObject* pParent = m_pParent;
while (pParent)
{
pRes = pParent->Get(sV);
if (pRes)
return pRes;
CObjectBase* pParent2 = pParent->Get("Parent");
if (pParent2 && pParent2->GetType() == object_type_DICT)
pParent = (CDictObject*)pParent2;
else
return NULL;
}
return NULL;
}
void CWidgetAnnotation::CheckMK()
{
if (!m_pMK)
@ -1001,12 +1020,15 @@ namespace PdfWriter
m_pMK->Add("IF", m_pIF);
}
}
void CButtonWidget::SetV(bool bV)
void CButtonWidget::SetV(const std::wstring& wsV)
{
if (m_pParent && bV)
m_pParent->Add("V", m_sAP_N_Yes.c_str());
Add("V", (bV ? m_sAP_N_Yes.c_str() : "Off"));
std::string sV = U_TO_UTF8(wsV);
CDictObject* pOwner = GetObjOwnValue("V");
if (!pOwner)
pOwner = GetObjOwnValue("FT");
if (!pOwner)
pOwner = this;
pOwner->Add("V", new CStringObject(sV.c_str(), true));
}
void CButtonWidget::SetDV(const std::wstring& wsDV)
{
@ -1124,9 +1146,9 @@ namespace PdfWriter
std::string sValue = U_TO_UTF8(wsAP_N_Yes);
m_sAP_N_Yes = sValue;
}
void CButtonWidget::SwitchAP()
void CButtonWidget::SwitchAP(const std::string& sV)
{
Add("AS", Get("V"));
Add("AS", sV == m_sAP_N_Yes ? sV.c_str() : "Off");
}
void CButtonWidget::SetAP(const std::wstring& wsValue, CFontDict* pFont, const TRgb& oColor, double dFontSize, double dX, double dY)
{

View File

@ -357,6 +357,7 @@ namespace PdfWriter
void SetDA(CFontDict* pFont, const double& dFontSize, const double& dFontSizeAP, const std::vector<double>& arrTC);
CDictObject* GetObjOwnValue(const std::string& sV);
CObjectBase* GetObjValue(const std::string& sV);
void SetQ(const BYTE& nQ);
void SetH(const BYTE& nH);
@ -391,7 +392,7 @@ namespace PdfWriter
return m_nSubtype;
}
void SetV(bool bV);
void SetV(const std::wstring& wsV);
void SetDV(const std::wstring& wsDV) override;
void SetS(const BYTE& nS);
void SetTP(const BYTE& nTP);
@ -404,7 +405,7 @@ namespace PdfWriter
void SetAC(const std::wstring& wsAC);
void SetAP_N_Yes(const std::wstring& wsAP_N_Yes);
void SwitchAP();
void SwitchAP(const std::string& sV);
void SetAP(const std::wstring& wsValue, CFontDict* pFont, const TRgb& oColor, double dFontSize, double dX, double dY);
};
class CTextWidget : public CWidgetAnnotation