summaryrefslogtreecommitdiff
path: root/xfa/fxfa/cxfa_widgetacc.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'xfa/fxfa/cxfa_widgetacc.cpp')
-rw-r--r--xfa/fxfa/cxfa_widgetacc.cpp1764
1 files changed, 1758 insertions, 6 deletions
diff --git a/xfa/fxfa/cxfa_widgetacc.cpp b/xfa/fxfa/cxfa_widgetacc.cpp
index 2e2807b1f0..47a9c942b0 100644
--- a/xfa/fxfa/cxfa_widgetacc.cpp
+++ b/xfa/fxfa/cxfa_widgetacc.cpp
@@ -9,6 +9,8 @@
#include <algorithm>
#include <vector>
+#include "core/fxcrt/cfx_decimal.h"
+#include "core/fxcrt/fx_extension.h"
#include "core/fxcrt/xml/cfx_xmlelement.h"
#include "core/fxcrt/xml/cfx_xmlnode.h"
#include "fxjs/cfxjse_engine.h"
@@ -17,22 +19,33 @@
#include "xfa/fxfa/cxfa_ffapp.h"
#include "xfa/fxfa/cxfa_ffdoc.h"
#include "xfa/fxfa/cxfa_ffdocview.h"
+#include "xfa/fxfa/cxfa_ffnotify.h"
#include "xfa/fxfa/cxfa_ffwidget.h"
#include "xfa/fxfa/cxfa_fontmgr.h"
#include "xfa/fxfa/cxfa_textlayout.h"
#include "xfa/fxfa/cxfa_textprovider.h"
+#include "xfa/fxfa/parser/cxfa_bind.h"
+#include "xfa/fxfa/parser/cxfa_border.h"
#include "xfa/fxfa/parser/cxfa_calculate.h"
#include "xfa/fxfa/parser/cxfa_caption.h"
+#include "xfa/fxfa/parser/cxfa_comb.h"
+#include "xfa/fxfa/parser/cxfa_decimal.h"
+#include "xfa/fxfa/parser/cxfa_document.h"
#include "xfa/fxfa/parser/cxfa_event.h"
#include "xfa/fxfa/parser/cxfa_font.h"
+#include "xfa/fxfa/parser/cxfa_format.h"
#include "xfa/fxfa/parser/cxfa_image.h"
#include "xfa/fxfa/parser/cxfa_items.h"
#include "xfa/fxfa/parser/cxfa_layoutprocessor.h"
#include "xfa/fxfa/parser/cxfa_localevalue.h"
#include "xfa/fxfa/parser/cxfa_margin.h"
+#include "xfa/fxfa/parser/cxfa_measurement.h"
#include "xfa/fxfa/parser/cxfa_node.h"
#include "xfa/fxfa/parser/cxfa_para.h"
+#include "xfa/fxfa/parser/cxfa_picture.h"
#include "xfa/fxfa/parser/cxfa_script.h"
+#include "xfa/fxfa/parser/cxfa_stroke.h"
+#include "xfa/fxfa/parser/cxfa_ui.h"
#include "xfa/fxfa/parser/cxfa_validate.h"
#include "xfa/fxfa/parser/cxfa_value.h"
#include "xfa/fxfa/parser/xfa_utils.h"
@@ -157,12 +170,203 @@ class CXFA_ImageEditData : public CXFA_FieldLayoutData {
int32_t m_iImageYDpi;
};
+float GetEdgeThickness(const std::vector<CXFA_Stroke*>& strokes,
+ bool b3DStyle,
+ int32_t nIndex) {
+ float fThickness = 0;
+
+ CXFA_Stroke* stroke = strokes[nIndex * 2 + 1];
+ if (stroke->IsVisible()) {
+ if (nIndex == 0)
+ fThickness += 2.5f;
+
+ fThickness += stroke->GetThickness() * (b3DStyle ? 4 : 2);
+ }
+ return fThickness;
+}
+
+bool SplitDateTime(const WideString& wsDateTime,
+ WideString& wsDate,
+ WideString& wsTime) {
+ wsDate = L"";
+ wsTime = L"";
+ if (wsDateTime.IsEmpty())
+ return false;
+
+ auto nSplitIndex = wsDateTime.Find('T');
+ if (!nSplitIndex.has_value())
+ nSplitIndex = wsDateTime.Find(' ');
+ if (!nSplitIndex.has_value())
+ return false;
+
+ wsDate = wsDateTime.Left(nSplitIndex.value());
+ if (!wsDate.IsEmpty()) {
+ if (!std::any_of(wsDate.begin(), wsDate.end(), std::iswdigit))
+ return false;
+ }
+ wsTime = wsDateTime.Right(wsDateTime.GetLength() - nSplitIndex.value() - 1);
+ if (!wsTime.IsEmpty()) {
+ if (!std::any_of(wsTime.begin(), wsTime.end(), std::iswdigit))
+ return false;
+ }
+ return true;
+}
+
+CXFA_Node* CreateUIChild(CXFA_Node* pNode, XFA_Element& eWidgetType) {
+ XFA_Element eType = pNode->GetElementType();
+ eWidgetType = eType;
+ if (eType != XFA_Element::Field && eType != XFA_Element::Draw)
+ return nullptr;
+
+ eWidgetType = XFA_Element::Unknown;
+ XFA_Element eUIType = XFA_Element::Unknown;
+ auto* defValue =
+ pNode->JSObject()->GetProperty<CXFA_Value>(0, XFA_Element::Value, true);
+ XFA_Element eValueType =
+ defValue ? defValue->GetChildValueClassID() : XFA_Element::Unknown;
+ switch (eValueType) {
+ case XFA_Element::Boolean:
+ eUIType = XFA_Element::CheckButton;
+ break;
+ case XFA_Element::Integer:
+ case XFA_Element::Decimal:
+ case XFA_Element::Float:
+ eUIType = XFA_Element::NumericEdit;
+ break;
+ case XFA_Element::ExData:
+ case XFA_Element::Text:
+ eUIType = XFA_Element::TextEdit;
+ eWidgetType = XFA_Element::Text;
+ break;
+ case XFA_Element::Date:
+ case XFA_Element::Time:
+ case XFA_Element::DateTime:
+ eUIType = XFA_Element::DateTimeEdit;
+ break;
+ case XFA_Element::Image:
+ eUIType = XFA_Element::ImageEdit;
+ eWidgetType = XFA_Element::Image;
+ break;
+ case XFA_Element::Arc:
+ case XFA_Element::Line:
+ case XFA_Element::Rectangle:
+ eUIType = XFA_Element::DefaultUi;
+ eWidgetType = eValueType;
+ break;
+ default:
+ break;
+ }
+
+ CXFA_Node* pUIChild = nullptr;
+ CXFA_Ui* pUI =
+ pNode->JSObject()->GetProperty<CXFA_Ui>(0, XFA_Element::Ui, true);
+ CXFA_Node* pChild = pUI->GetNodeItem(XFA_NODEITEM_FirstChild);
+ for (; pChild; pChild = pChild->GetNodeItem(XFA_NODEITEM_NextSibling)) {
+ XFA_Element eChildType = pChild->GetElementType();
+ if (eChildType == XFA_Element::Extras ||
+ eChildType == XFA_Element::Picture) {
+ continue;
+ }
+
+ auto node = CXFA_Node::Create(pChild->GetDocument(), XFA_Element::Ui,
+ XFA_PacketType::Form);
+ if (node && node->HasPropertyFlags(eChildType, XFA_PROPERTYFLAG_OneOf)) {
+ pUIChild = pChild;
+ break;
+ }
+ }
+
+ if (eType == XFA_Element::Draw) {
+ XFA_Element eDraw =
+ pUIChild ? pUIChild->GetElementType() : XFA_Element::Unknown;
+ switch (eDraw) {
+ case XFA_Element::TextEdit:
+ eWidgetType = XFA_Element::Text;
+ break;
+ case XFA_Element::ImageEdit:
+ eWidgetType = XFA_Element::Image;
+ break;
+ default:
+ eWidgetType = eWidgetType == XFA_Element::Unknown ? XFA_Element::Text
+ : eWidgetType;
+ break;
+ }
+ } else {
+ if (pUIChild && pUIChild->GetElementType() == XFA_Element::DefaultUi) {
+ eWidgetType = XFA_Element::TextEdit;
+ } else {
+ eWidgetType =
+ pUIChild ? pUIChild->GetElementType()
+ : (eUIType == XFA_Element::Unknown ? XFA_Element::TextEdit
+ : eUIType);
+ }
+ }
+
+ if (!pUIChild) {
+ if (eUIType == XFA_Element::Unknown) {
+ eUIType = XFA_Element::TextEdit;
+ defValue->JSObject()->GetProperty<CXFA_Text>(0, XFA_Element::Text, true);
+ }
+ return pUI->JSObject()->GetProperty<CXFA_Node>(0, eUIType, true);
+ }
+
+ if (eUIType != XFA_Element::Unknown)
+ return pUIChild;
+
+ switch (pUIChild->GetElementType()) {
+ case XFA_Element::CheckButton: {
+ eValueType = XFA_Element::Text;
+ if (CXFA_Items* pItems =
+ pNode->GetChild<CXFA_Items>(0, XFA_Element::Items, false)) {
+ if (CXFA_Node* pItem =
+ pItems->GetChild<CXFA_Node>(0, XFA_Element::Unknown, false)) {
+ eValueType = pItem->GetElementType();
+ }
+ }
+ break;
+ }
+ case XFA_Element::DateTimeEdit:
+ eValueType = XFA_Element::DateTime;
+ break;
+ case XFA_Element::ImageEdit:
+ eValueType = XFA_Element::Image;
+ break;
+ case XFA_Element::NumericEdit:
+ eValueType = XFA_Element::Float;
+ break;
+ case XFA_Element::ChoiceList: {
+ eValueType = (pUIChild->JSObject()->GetEnum(XFA_Attribute::Open) ==
+ XFA_AttributeEnum::MultiSelect)
+ ? XFA_Element::ExData
+ : XFA_Element::Text;
+ break;
+ }
+ case XFA_Element::Barcode:
+ case XFA_Element::Button:
+ case XFA_Element::PasswordEdit:
+ case XFA_Element::Signature:
+ case XFA_Element::TextEdit:
+ default:
+ eValueType = XFA_Element::Text;
+ break;
+ }
+ defValue->JSObject()->GetProperty<CXFA_Node>(0, eValueType, true);
+
+ return pUIChild;
+}
+
} // namespace
CXFA_WidgetAcc::CXFA_WidgetAcc(CXFA_FFDocView* pDocView, CXFA_Node* pNode)
- : CXFA_WidgetData(pNode), m_pDocView(pDocView), m_nRecursionDepth(0) {}
+ : m_pDocView(pDocView),
+ m_nRecursionDepth(0),
+ m_bIsNull(true),
+ m_bPreNull(true),
+ m_pUiChildNode(nullptr),
+ m_eUIType(XFA_Element::Unknown),
+ m_pNode(pNode) {}
-CXFA_WidgetAcc::~CXFA_WidgetAcc() {}
+CXFA_WidgetAcc::~CXFA_WidgetAcc() = default;
XFA_Element CXFA_WidgetAcc::GetElementType() const {
return m_pNode ? m_pNode->GetElementType() : XFA_Element::Unknown;
@@ -201,8 +405,7 @@ void CXFA_WidgetAcc::ResetData() {
XFA_NODEITEM_FirstChild, XFA_ObjectType::ContainerNode);
while (pNextChild) {
CXFA_Node* pChild = pNextChild;
- CXFA_WidgetAcc* pAcc =
- static_cast<CXFA_WidgetAcc*>(pChild->GetWidgetData());
+ CXFA_WidgetAcc* pAcc = pChild->GetWidgetAcc();
if (!pAcc)
continue;
@@ -282,7 +485,7 @@ CXFA_WidgetAcc* CXFA_WidgetAcc::GetExclGroup() {
CXFA_Node* pExcl = m_pNode->GetNodeItem(XFA_NODEITEM_Parent);
if (!pExcl || pExcl->GetElementType() != XFA_Element::ExclGroup)
return nullptr;
- return static_cast<CXFA_WidgetAcc*>(pExcl->GetWidgetData());
+ return pExcl->GetWidgetAcc();
}
CXFA_FFDoc* CXFA_WidgetAcc::GetDoc() {
@@ -649,7 +852,7 @@ std::pair<int32_t, bool> CXFA_WidgetAcc::ExecuteBoolScript(
}
}
for (CXFA_Node* pRefNode : refNodes) {
- if (static_cast<CXFA_WidgetAcc*>(pRefNode->GetWidgetData()) == this)
+ if (pRefNode->GetWidgetAcc() == this)
continue;
CXFA_CalcData* pGlobalData = pRefNode->JSObject()->GetCalcData();
@@ -1524,3 +1727,1552 @@ FX_ARGB CXFA_WidgetAcc::GetTextColor() {
CXFA_Font* font = GetFont(false);
return font ? font->GetColor() : 0xFF000000;
}
+
+CXFA_Node* CXFA_WidgetAcc::GetUIChild() {
+ if (m_eUIType == XFA_Element::Unknown)
+ m_pUiChildNode = CreateUIChild(m_pNode, m_eUIType);
+
+ return m_pUiChildNode;
+}
+
+XFA_Element CXFA_WidgetAcc::GetUIType() {
+ GetUIChild();
+ return m_eUIType;
+}
+
+WideString CXFA_WidgetAcc::GetRawValue() const {
+ return m_pNode->JSObject()->GetContent(false);
+}
+
+bool CXFA_WidgetAcc::IsOpenAccess() const {
+ for (CXFA_Node* pNode = m_pNode; pNode;
+ pNode = pNode->GetNodeItem(XFA_NODEITEM_Parent,
+ XFA_ObjectType::ContainerNode)) {
+ XFA_AttributeEnum iAcc = pNode->JSObject()->GetEnum(XFA_Attribute::Access);
+ if (iAcc != XFA_AttributeEnum::Open)
+ return false;
+ }
+ return true;
+}
+
+int32_t CXFA_WidgetAcc::GetRotate() const {
+ pdfium::Optional<int32_t> degrees =
+ m_pNode->JSObject()->TryInteger(XFA_Attribute::Rotate, false);
+ return degrees ? XFA_MapRotation(*degrees) / 90 * 90 : 0;
+}
+
+CXFA_Border* CXFA_WidgetAcc::GetBorder(bool bModified) {
+ return m_pNode->JSObject()->GetProperty<CXFA_Border>(0, XFA_Element::Border,
+ bModified);
+}
+
+CXFA_Caption* CXFA_WidgetAcc::GetCaption() {
+ return m_pNode->JSObject()->GetProperty<CXFA_Caption>(0, XFA_Element::Caption,
+ false);
+}
+
+CXFA_Font* CXFA_WidgetAcc::GetFont(bool bModified) {
+ return m_pNode->JSObject()->GetProperty<CXFA_Font>(0, XFA_Element::Font,
+ bModified);
+}
+
+CXFA_Margin* CXFA_WidgetAcc::GetMargin() {
+ return m_pNode->JSObject()->GetProperty<CXFA_Margin>(0, XFA_Element::Margin,
+ false);
+}
+
+CXFA_Para* CXFA_WidgetAcc::GetPara() {
+ return m_pNode->JSObject()->GetProperty<CXFA_Para>(0, XFA_Element::Para,
+ false);
+}
+
+std::vector<CXFA_Event*> CXFA_WidgetAcc::GetEventByActivity(
+ XFA_AttributeEnum iActivity,
+ bool bIsFormReady) {
+ std::vector<CXFA_Event*> events;
+ for (CXFA_Node* node : m_pNode->GetNodeList(0, XFA_Element::Event)) {
+ auto* event = static_cast<CXFA_Event*>(node);
+ if (event->GetActivity() == iActivity) {
+ if (iActivity == XFA_AttributeEnum::Ready) {
+ WideString wsRef = event->GetRef();
+ if (bIsFormReady) {
+ if (wsRef == WideStringView(L"$form"))
+ events.push_back(event);
+ } else {
+ if (wsRef == WideStringView(L"$layout"))
+ events.push_back(event);
+ }
+ } else {
+ events.push_back(event);
+ }
+ }
+ }
+ return events;
+}
+
+CXFA_Value* CXFA_WidgetAcc::GetDefaultValue() {
+ CXFA_Node* pTemNode = m_pNode->GetTemplateNode();
+ return pTemNode->JSObject()->GetProperty<CXFA_Value>(0, XFA_Element::Value,
+ false);
+}
+
+CXFA_Value* CXFA_WidgetAcc::GetFormValue() {
+ return m_pNode->JSObject()->GetProperty<CXFA_Value>(0, XFA_Element::Value,
+ false);
+}
+
+CXFA_Calculate* CXFA_WidgetAcc::GetCalculate() {
+ return m_pNode->JSObject()->GetProperty<CXFA_Calculate>(
+ 0, XFA_Element::Calculate, false);
+}
+
+CXFA_Validate* CXFA_WidgetAcc::GetValidate(bool bModified) {
+ return m_pNode->JSObject()->GetProperty<CXFA_Validate>(
+ 0, XFA_Element::Validate, bModified);
+}
+
+CXFA_Bind* CXFA_WidgetAcc::GetBind() {
+ return m_pNode->JSObject()->GetProperty<CXFA_Bind>(0, XFA_Element::Bind,
+ false);
+}
+
+pdfium::Optional<float> CXFA_WidgetAcc::TryWidth() {
+ return m_pNode->JSObject()->TryMeasureAsFloat(XFA_Attribute::W);
+}
+
+pdfium::Optional<float> CXFA_WidgetAcc::TryHeight() {
+ return m_pNode->JSObject()->TryMeasureAsFloat(XFA_Attribute::H);
+}
+
+pdfium::Optional<float> CXFA_WidgetAcc::TryMinWidth() {
+ return m_pNode->JSObject()->TryMeasureAsFloat(XFA_Attribute::MinW);
+}
+
+pdfium::Optional<float> CXFA_WidgetAcc::TryMinHeight() {
+ return m_pNode->JSObject()->TryMeasureAsFloat(XFA_Attribute::MinH);
+}
+
+pdfium::Optional<float> CXFA_WidgetAcc::TryMaxWidth() {
+ return m_pNode->JSObject()->TryMeasureAsFloat(XFA_Attribute::MaxW);
+}
+
+pdfium::Optional<float> CXFA_WidgetAcc::TryMaxHeight() {
+ return m_pNode->JSObject()->TryMeasureAsFloat(XFA_Attribute::MaxH);
+}
+
+CXFA_Border* CXFA_WidgetAcc::GetUIBorder() {
+ CXFA_Node* pUIChild = GetUIChild();
+ return pUIChild ? pUIChild->JSObject()->GetProperty<CXFA_Border>(
+ 0, XFA_Element::Border, false)
+ : nullptr;
+}
+
+CFX_RectF CXFA_WidgetAcc::GetUIMargin() {
+ CXFA_Node* pUIChild = GetUIChild();
+ CXFA_Margin* mgUI = nullptr;
+ if (pUIChild) {
+ mgUI = pUIChild->JSObject()->GetProperty<CXFA_Margin>(
+ 0, XFA_Element::Margin, false);
+ }
+
+ if (!mgUI)
+ return CFX_RectF();
+
+ CXFA_Border* border = GetUIBorder();
+ if (border && border->GetPresence() != XFA_AttributeEnum::Visible)
+ return CFX_RectF();
+
+ pdfium::Optional<float> left = mgUI->TryLeftInset();
+ pdfium::Optional<float> top = mgUI->TryTopInset();
+ pdfium::Optional<float> right = mgUI->TryRightInset();
+ pdfium::Optional<float> bottom = mgUI->TryBottomInset();
+ if (border) {
+ bool bVisible = false;
+ float fThickness = 0;
+ XFA_AttributeEnum iType = XFA_AttributeEnum::Unknown;
+ std::tie(iType, bVisible, fThickness) = border->Get3DStyle();
+ if (!left || !top || !right || !bottom) {
+ std::vector<CXFA_Stroke*> strokes = border->GetStrokes();
+ if (!top)
+ top = GetEdgeThickness(strokes, bVisible, 0);
+ if (!right)
+ right = GetEdgeThickness(strokes, bVisible, 1);
+ if (!bottom)
+ bottom = GetEdgeThickness(strokes, bVisible, 2);
+ if (!left)
+ left = GetEdgeThickness(strokes, bVisible, 3);
+ }
+ }
+ return CFX_RectF(left.value_or(0.0), top.value_or(0.0), right.value_or(0.0),
+ bottom.value_or(0.0));
+}
+
+XFA_AttributeEnum CXFA_WidgetAcc::GetButtonHighlight() {
+ CXFA_Node* pUIChild = GetUIChild();
+ if (pUIChild)
+ return pUIChild->JSObject()->GetEnum(XFA_Attribute::Highlight);
+ return XFA_AttributeEnum::Inverted;
+}
+
+bool CXFA_WidgetAcc::HasButtonRollover() const {
+ CXFA_Items* pItems =
+ m_pNode->GetChild<CXFA_Items>(0, XFA_Element::Items, false);
+ if (!pItems)
+ return false;
+
+ for (CXFA_Node* pText = pItems->GetNodeItem(XFA_NODEITEM_FirstChild); pText;
+ pText = pText->GetNodeItem(XFA_NODEITEM_NextSibling)) {
+ if (pText->JSObject()->GetCData(XFA_Attribute::Name) == L"rollover")
+ return !pText->JSObject()->GetContent(false).IsEmpty();
+ }
+ return false;
+}
+
+bool CXFA_WidgetAcc::HasButtonDown() const {
+ CXFA_Items* pItems =
+ m_pNode->GetChild<CXFA_Items>(0, XFA_Element::Items, false);
+ if (!pItems)
+ return false;
+
+ for (CXFA_Node* pText = pItems->GetNodeItem(XFA_NODEITEM_FirstChild); pText;
+ pText = pText->GetNodeItem(XFA_NODEITEM_NextSibling)) {
+ if (pText->JSObject()->GetCData(XFA_Attribute::Name) == L"down")
+ return !pText->JSObject()->GetContent(false).IsEmpty();
+ }
+ return false;
+}
+
+bool CXFA_WidgetAcc::IsCheckButtonRound() {
+ CXFA_Node* pUIChild = GetUIChild();
+ if (pUIChild)
+ return pUIChild->JSObject()->GetEnum(XFA_Attribute::Shape) ==
+ XFA_AttributeEnum::Round;
+ return false;
+}
+
+XFA_AttributeEnum CXFA_WidgetAcc::GetCheckButtonMark() {
+ CXFA_Node* pUIChild = GetUIChild();
+ if (pUIChild)
+ return pUIChild->JSObject()->GetEnum(XFA_Attribute::Mark);
+ return XFA_AttributeEnum::Default;
+}
+
+bool CXFA_WidgetAcc::IsRadioButton() {
+ CXFA_Node* pParent = m_pNode->GetNodeItem(XFA_NODEITEM_Parent);
+ return pParent && pParent->GetElementType() == XFA_Element::ExclGroup;
+}
+
+float CXFA_WidgetAcc::GetCheckButtonSize() {
+ CXFA_Node* pUIChild = GetUIChild();
+ if (pUIChild) {
+ return pUIChild->JSObject()
+ ->GetMeasure(XFA_Attribute::Size)
+ .ToUnit(XFA_Unit::Pt);
+ }
+ return CXFA_Measurement(10, XFA_Unit::Pt).ToUnit(XFA_Unit::Pt);
+}
+
+bool CXFA_WidgetAcc::IsAllowNeutral() {
+ CXFA_Node* pUIChild = GetUIChild();
+ return pUIChild &&
+ pUIChild->JSObject()->GetBoolean(XFA_Attribute::AllowNeutral);
+}
+
+XFA_CHECKSTATE CXFA_WidgetAcc::GetCheckState() {
+ WideString wsValue = GetRawValue();
+ if (wsValue.IsEmpty())
+ return XFA_CHECKSTATE_Off;
+
+ auto* pItems = m_pNode->GetChild<CXFA_Items>(0, XFA_Element::Items, false);
+ if (!pItems)
+ return XFA_CHECKSTATE_Off;
+
+ CXFA_Node* pText = pItems->GetNodeItem(XFA_NODEITEM_FirstChild);
+ int32_t i = 0;
+ while (pText) {
+ pdfium::Optional<WideString> wsContent =
+ pText->JSObject()->TryContent(false, true);
+ if (wsContent && *wsContent == wsValue)
+ return static_cast<XFA_CHECKSTATE>(i);
+
+ i++;
+ pText = pText->GetNodeItem(XFA_NODEITEM_NextSibling);
+ }
+ return XFA_CHECKSTATE_Off;
+}
+
+void CXFA_WidgetAcc::SetCheckState(XFA_CHECKSTATE eCheckState, bool bNotify) {
+ CXFA_Node* node = GetExclGroupNode();
+ if (!node) {
+ CXFA_Items* pItems =
+ m_pNode->GetChild<CXFA_Items>(0, XFA_Element::Items, false);
+ if (!pItems)
+ return;
+
+ int32_t i = -1;
+ CXFA_Node* pText = pItems->GetNodeItem(XFA_NODEITEM_FirstChild);
+ WideString wsContent;
+ while (pText) {
+ i++;
+ if (i == eCheckState) {
+ wsContent = pText->JSObject()->GetContent(false);
+ break;
+ }
+ pText = pText->GetNodeItem(XFA_NODEITEM_NextSibling);
+ }
+ if (m_pNode)
+ m_pNode->SyncValue(wsContent, bNotify);
+ return;
+ }
+
+ WideString wsValue;
+ if (eCheckState != XFA_CHECKSTATE_Off) {
+ if (CXFA_Items* pItems =
+ m_pNode->GetChild<CXFA_Items>(0, XFA_Element::Items, false)) {
+ CXFA_Node* pText = pItems->GetNodeItem(XFA_NODEITEM_FirstChild);
+ if (pText)
+ wsValue = pText->JSObject()->GetContent(false);
+ }
+ }
+ CXFA_Node* pChild = node->GetNodeItem(XFA_NODEITEM_FirstChild);
+ for (; pChild; pChild = pChild->GetNodeItem(XFA_NODEITEM_NextSibling)) {
+ if (pChild->GetElementType() != XFA_Element::Field)
+ continue;
+
+ CXFA_Items* pItem =
+ pChild->GetChild<CXFA_Items>(0, XFA_Element::Items, false);
+ if (!pItem)
+ continue;
+
+ CXFA_Node* pItemchild = pItem->GetNodeItem(XFA_NODEITEM_FirstChild);
+ if (!pItemchild)
+ continue;
+
+ WideString text = pItemchild->JSObject()->GetContent(false);
+ WideString wsChildValue = text;
+ if (wsValue != text) {
+ pItemchild = pItemchild->GetNodeItem(XFA_NODEITEM_NextSibling);
+ if (pItemchild)
+ wsChildValue = pItemchild->JSObject()->GetContent(false);
+ else
+ wsChildValue.clear();
+ }
+ pChild->SyncValue(wsChildValue, bNotify);
+ }
+ node->SyncValue(wsValue, bNotify);
+}
+
+CXFA_Node* CXFA_WidgetAcc::GetExclGroupNode() {
+ CXFA_Node* pExcl = ToNode(m_pNode->GetNodeItem(XFA_NODEITEM_Parent));
+ if (!pExcl || pExcl->GetElementType() != XFA_Element::ExclGroup)
+ return nullptr;
+ return pExcl;
+}
+
+CXFA_Node* CXFA_WidgetAcc::GetSelectedMember() {
+ CXFA_Node* pSelectedMember = nullptr;
+ WideString wsState = GetRawValue();
+ if (wsState.IsEmpty())
+ return pSelectedMember;
+
+ for (CXFA_Node* pNode = ToNode(m_pNode->GetNodeItem(XFA_NODEITEM_FirstChild));
+ pNode; pNode = pNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
+ CXFA_WidgetAcc widgetData(nullptr, pNode);
+ if (widgetData.GetCheckState() == XFA_CHECKSTATE_On) {
+ pSelectedMember = pNode;
+ break;
+ }
+ }
+ return pSelectedMember;
+}
+
+CXFA_Node* CXFA_WidgetAcc::SetSelectedMember(const WideStringView& wsName,
+ bool bNotify) {
+ uint32_t nameHash = FX_HashCode_GetW(wsName, false);
+ for (CXFA_Node* pNode = ToNode(m_pNode->GetNodeItem(XFA_NODEITEM_FirstChild));
+ pNode; pNode = pNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
+ if (pNode->GetNameHash() == nameHash) {
+ CXFA_WidgetAcc widgetData(nullptr, pNode);
+ widgetData.SetCheckState(XFA_CHECKSTATE_On, bNotify);
+ return pNode;
+ }
+ }
+ return nullptr;
+}
+
+void CXFA_WidgetAcc::SetSelectedMemberByValue(const WideStringView& wsValue,
+ bool bNotify,
+ bool bScriptModify,
+ bool bSyncData) {
+ WideString wsExclGroup;
+ for (CXFA_Node* pNode = m_pNode->GetNodeItem(XFA_NODEITEM_FirstChild); pNode;
+ pNode = pNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
+ if (pNode->GetElementType() != XFA_Element::Field)
+ continue;
+
+ CXFA_Items* pItem =
+ pNode->GetChild<CXFA_Items>(0, XFA_Element::Items, false);
+ if (!pItem)
+ continue;
+
+ CXFA_Node* pItemchild = pItem->GetNodeItem(XFA_NODEITEM_FirstChild);
+ if (!pItemchild)
+ continue;
+
+ WideString wsChildValue = pItemchild->JSObject()->GetContent(false);
+ if (wsValue != wsChildValue) {
+ pItemchild = pItemchild->GetNodeItem(XFA_NODEITEM_NextSibling);
+ if (pItemchild)
+ wsChildValue = pItemchild->JSObject()->GetContent(false);
+ else
+ wsChildValue.clear();
+ } else {
+ wsExclGroup = wsValue;
+ }
+ pNode->JSObject()->SetContent(wsChildValue, wsChildValue, bNotify,
+ bScriptModify, false);
+ }
+ if (m_pNode) {
+ m_pNode->JSObject()->SetContent(wsExclGroup, wsExclGroup, bNotify,
+ bScriptModify, bSyncData);
+ }
+}
+
+CXFA_Node* CXFA_WidgetAcc::GetExclGroupFirstMember() {
+ CXFA_Node* pExcl = GetNode();
+ if (!pExcl)
+ return nullptr;
+
+ CXFA_Node* pNode = pExcl->GetNodeItem(XFA_NODEITEM_FirstChild);
+ while (pNode) {
+ if (pNode->GetElementType() == XFA_Element::Field)
+ return pNode;
+
+ pNode = pNode->GetNodeItem(XFA_NODEITEM_NextSibling);
+ }
+ return nullptr;
+}
+CXFA_Node* CXFA_WidgetAcc::GetExclGroupNextMember(CXFA_Node* pNode) {
+ if (!pNode)
+ return nullptr;
+
+ CXFA_Node* pNodeField = pNode->GetNodeItem(XFA_NODEITEM_NextSibling);
+ while (pNodeField) {
+ if (pNodeField->GetElementType() == XFA_Element::Field)
+ return pNodeField;
+
+ pNodeField = pNodeField->GetNodeItem(XFA_NODEITEM_NextSibling);
+ }
+ return nullptr;
+}
+
+bool CXFA_WidgetAcc::IsChoiceListCommitOnSelect() {
+ CXFA_Node* pUIChild = GetUIChild();
+ if (pUIChild) {
+ return pUIChild->JSObject()->GetEnum(XFA_Attribute::CommitOn) ==
+ XFA_AttributeEnum::Select;
+ }
+ return true;
+}
+
+bool CXFA_WidgetAcc::IsChoiceListAllowTextEntry() {
+ CXFA_Node* pUIChild = GetUIChild();
+ return pUIChild && pUIChild->JSObject()->GetBoolean(XFA_Attribute::TextEntry);
+}
+
+bool CXFA_WidgetAcc::IsChoiceListMultiSelect() {
+ CXFA_Node* pUIChild = GetUIChild();
+ if (pUIChild) {
+ return pUIChild->JSObject()->GetEnum(XFA_Attribute::Open) ==
+ XFA_AttributeEnum::MultiSelect;
+ }
+ return false;
+}
+
+bool CXFA_WidgetAcc::IsListBox() {
+ CXFA_Node* pUIChild = GetUIChild();
+ if (!pUIChild)
+ return false;
+
+ XFA_AttributeEnum attr = pUIChild->JSObject()->GetEnum(XFA_Attribute::Open);
+ return attr == XFA_AttributeEnum::Always ||
+ attr == XFA_AttributeEnum::MultiSelect;
+}
+
+int32_t CXFA_WidgetAcc::CountChoiceListItems(bool bSaveValue) {
+ std::vector<CXFA_Node*> pItems;
+ int32_t iCount = 0;
+ for (CXFA_Node* pNode = m_pNode->GetNodeItem(XFA_NODEITEM_FirstChild); pNode;
+ pNode = pNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
+ if (pNode->GetElementType() != XFA_Element::Items)
+ continue;
+ iCount++;
+ pItems.push_back(pNode);
+ if (iCount == 2)
+ break;
+ }
+ if (iCount == 0)
+ return 0;
+
+ CXFA_Node* pItem = pItems[0];
+ if (iCount > 1) {
+ bool bItemOneHasSave =
+ pItems[0]->JSObject()->GetBoolean(XFA_Attribute::Save);
+ bool bItemTwoHasSave =
+ pItems[1]->JSObject()->GetBoolean(XFA_Attribute::Save);
+ if (bItemOneHasSave != bItemTwoHasSave && bSaveValue == bItemTwoHasSave)
+ pItem = pItems[1];
+ }
+ return pItem->CountChildren(XFA_Element::Unknown, false);
+}
+
+pdfium::Optional<WideString> CXFA_WidgetAcc::GetChoiceListItem(
+ int32_t nIndex,
+ bool bSaveValue) {
+ std::vector<CXFA_Node*> pItemsArray;
+ int32_t iCount = 0;
+ for (CXFA_Node* pNode = m_pNode->GetNodeItem(XFA_NODEITEM_FirstChild); pNode;
+ pNode = pNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
+ if (pNode->GetElementType() != XFA_Element::Items)
+ continue;
+
+ ++iCount;
+ pItemsArray.push_back(pNode);
+ if (iCount == 2)
+ break;
+ }
+ if (iCount == 0)
+ return {};
+
+ CXFA_Node* pItems = pItemsArray[0];
+ if (iCount > 1) {
+ bool bItemOneHasSave =
+ pItemsArray[0]->JSObject()->GetBoolean(XFA_Attribute::Save);
+ bool bItemTwoHasSave =
+ pItemsArray[1]->JSObject()->GetBoolean(XFA_Attribute::Save);
+ if (bItemOneHasSave != bItemTwoHasSave && bSaveValue == bItemTwoHasSave)
+ pItems = pItemsArray[1];
+ }
+ if (!pItems)
+ return {};
+
+ CXFA_Node* pItem =
+ pItems->GetChild<CXFA_Node>(nIndex, XFA_Element::Unknown, false);
+ if (pItem)
+ return {pItem->JSObject()->GetContent(false)};
+ return {};
+}
+
+std::vector<WideString> CXFA_WidgetAcc::GetChoiceListItems(bool bSaveValue) {
+ std::vector<CXFA_Node*> items;
+ for (CXFA_Node* pNode = m_pNode->GetNodeItem(XFA_NODEITEM_FirstChild);
+ pNode && items.size() < 2;
+ pNode = pNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
+ if (pNode->GetElementType() == XFA_Element::Items)
+ items.push_back(pNode);
+ }
+ if (items.empty())
+ return std::vector<WideString>();
+
+ CXFA_Node* pItem = items.front();
+ if (items.size() > 1) {
+ bool bItemOneHasSave =
+ items[0]->JSObject()->GetBoolean(XFA_Attribute::Save);
+ bool bItemTwoHasSave =
+ items[1]->JSObject()->GetBoolean(XFA_Attribute::Save);
+ if (bItemOneHasSave != bItemTwoHasSave && bSaveValue == bItemTwoHasSave)
+ pItem = items[1];
+ }
+
+ std::vector<WideString> wsTextArray;
+ for (CXFA_Node* pNode = pItem->GetNodeItem(XFA_NODEITEM_FirstChild); pNode;
+ pNode = pNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
+ wsTextArray.emplace_back(pNode->JSObject()->GetContent(false));
+ }
+ return wsTextArray;
+}
+
+int32_t CXFA_WidgetAcc::CountSelectedItems() {
+ std::vector<WideString> wsValueArray = GetSelectedItemsValue();
+ if (IsListBox() || !IsChoiceListAllowTextEntry())
+ return pdfium::CollectionSize<int32_t>(wsValueArray);
+
+ int32_t iSelected = 0;
+ std::vector<WideString> wsSaveTextArray = GetChoiceListItems(true);
+ for (const auto& value : wsValueArray) {
+ if (pdfium::ContainsValue(wsSaveTextArray, value))
+ iSelected++;
+ }
+ return iSelected;
+}
+
+int32_t CXFA_WidgetAcc::GetSelectedItem(int32_t nIndex) {
+ std::vector<WideString> wsValueArray = GetSelectedItemsValue();
+ if (!pdfium::IndexInBounds(wsValueArray, nIndex))
+ return -1;
+
+ std::vector<WideString> wsSaveTextArray = GetChoiceListItems(true);
+ auto it = std::find(wsSaveTextArray.begin(), wsSaveTextArray.end(),
+ wsValueArray[nIndex]);
+ return it != wsSaveTextArray.end() ? it - wsSaveTextArray.begin() : -1;
+}
+
+std::vector<int32_t> CXFA_WidgetAcc::GetSelectedItems() {
+ std::vector<int32_t> iSelArray;
+ std::vector<WideString> wsValueArray = GetSelectedItemsValue();
+ std::vector<WideString> wsSaveTextArray = GetChoiceListItems(true);
+ for (const auto& value : wsValueArray) {
+ auto it = std::find(wsSaveTextArray.begin(), wsSaveTextArray.end(), value);
+ if (it != wsSaveTextArray.end())
+ iSelArray.push_back(it - wsSaveTextArray.begin());
+ }
+ return iSelArray;
+}
+
+std::vector<WideString> CXFA_WidgetAcc::GetSelectedItemsValue() {
+ std::vector<WideString> wsSelTextArray;
+ WideString wsValue = GetRawValue();
+ if (IsChoiceListMultiSelect()) {
+ if (!wsValue.IsEmpty()) {
+ size_t iStart = 0;
+ size_t iLength = wsValue.GetLength();
+ auto iEnd = wsValue.Find(L'\n', iStart);
+ iEnd = (!iEnd.has_value()) ? iLength : iEnd;
+ while (iEnd >= iStart) {
+ wsSelTextArray.push_back(wsValue.Mid(iStart, iEnd.value() - iStart));
+ iStart = iEnd.value() + 1;
+ if (iStart >= iLength)
+ break;
+ iEnd = wsValue.Find(L'\n', iStart);
+ if (!iEnd.has_value())
+ wsSelTextArray.push_back(wsValue.Mid(iStart, iLength - iStart));
+ }
+ }
+ } else {
+ wsSelTextArray.push_back(wsValue);
+ }
+ return wsSelTextArray;
+}
+
+bool CXFA_WidgetAcc::GetItemState(int32_t nIndex) {
+ std::vector<WideString> wsSaveTextArray = GetChoiceListItems(true);
+ return pdfium::IndexInBounds(wsSaveTextArray, nIndex) &&
+ pdfium::ContainsValue(GetSelectedItemsValue(),
+ wsSaveTextArray[nIndex]);
+}
+
+void CXFA_WidgetAcc::SetItemState(int32_t nIndex,
+ bool bSelected,
+ bool bNotify,
+ bool bScriptModify,
+ bool bSyncData) {
+ std::vector<WideString> wsSaveTextArray = GetChoiceListItems(true);
+ if (!pdfium::IndexInBounds(wsSaveTextArray, nIndex))
+ return;
+
+ int32_t iSel = -1;
+ std::vector<WideString> wsValueArray = GetSelectedItemsValue();
+ auto it = std::find(wsValueArray.begin(), wsValueArray.end(),
+ wsSaveTextArray[nIndex]);
+ if (it != wsValueArray.end())
+ iSel = it - wsValueArray.begin();
+
+ if (IsChoiceListMultiSelect()) {
+ if (bSelected) {
+ if (iSel < 0) {
+ WideString wsValue = GetRawValue();
+ if (!wsValue.IsEmpty()) {
+ wsValue += L"\n";
+ }
+ wsValue += wsSaveTextArray[nIndex];
+ m_pNode->JSObject()->SetContent(wsValue, wsValue, bNotify,
+ bScriptModify, bSyncData);
+ }
+ } else if (iSel >= 0) {
+ std::vector<int32_t> iSelArray = GetSelectedItems();
+ auto it = std::find(iSelArray.begin(), iSelArray.end(), nIndex);
+ if (it != iSelArray.end())
+ iSelArray.erase(it);
+ SetSelectedItems(iSelArray, bNotify, bScriptModify, bSyncData);
+ }
+ } else {
+ if (bSelected) {
+ if (iSel < 0) {
+ WideString wsSaveText = wsSaveTextArray[nIndex];
+ m_pNode->JSObject()->SetContent(wsSaveText,
+ GetFormatDataValue(wsSaveText), bNotify,
+ bScriptModify, bSyncData);
+ }
+ } else if (iSel >= 0) {
+ m_pNode->JSObject()->SetContent(WideString(), WideString(), bNotify,
+ bScriptModify, bSyncData);
+ }
+ }
+}
+
+void CXFA_WidgetAcc::SetSelectedItems(const std::vector<int32_t>& iSelArray,
+ bool bNotify,
+ bool bScriptModify,
+ bool bSyncData) {
+ WideString wsValue;
+ int32_t iSize = pdfium::CollectionSize<int32_t>(iSelArray);
+ if (iSize >= 1) {
+ std::vector<WideString> wsSaveTextArray = GetChoiceListItems(true);
+ WideString wsItemValue;
+ for (int32_t i = 0; i < iSize; i++) {
+ wsItemValue = (iSize == 1) ? wsSaveTextArray[iSelArray[i]]
+ : wsSaveTextArray[iSelArray[i]] + L"\n";
+ wsValue += wsItemValue;
+ }
+ }
+ WideString wsFormat(wsValue);
+ if (!IsChoiceListMultiSelect())
+ wsFormat = GetFormatDataValue(wsValue);
+
+ m_pNode->JSObject()->SetContent(wsValue, wsFormat, bNotify, bScriptModify,
+ bSyncData);
+}
+
+void CXFA_WidgetAcc::ClearAllSelections() {
+ CXFA_Node* pBind = m_pNode->GetBindData();
+ if (!pBind || !IsChoiceListMultiSelect()) {
+ m_pNode->SyncValue(WideString(), false);
+ return;
+ }
+
+ while (CXFA_Node* pChildNode = pBind->GetNodeItem(XFA_NODEITEM_FirstChild))
+ pBind->RemoveChild(pChildNode, true);
+}
+
+void CXFA_WidgetAcc::InsertItem(const WideString& wsLabel,
+ const WideString& wsValue,
+ bool bNotify) {
+ int32_t nIndex = -1;
+ WideString wsNewValue(wsValue);
+ if (wsNewValue.IsEmpty())
+ wsNewValue = wsLabel;
+
+ std::vector<CXFA_Node*> listitems;
+ for (CXFA_Node* pItem = m_pNode->GetNodeItem(XFA_NODEITEM_FirstChild); pItem;
+ pItem = pItem->GetNodeItem(XFA_NODEITEM_NextSibling)) {
+ if (pItem->GetElementType() == XFA_Element::Items)
+ listitems.push_back(pItem);
+ }
+ if (listitems.empty()) {
+ CXFA_Node* pItems = m_pNode->CreateSamePacketNode(XFA_Element::Items);
+ m_pNode->InsertChild(-1, pItems);
+ InsertListTextItem(pItems, wsLabel, nIndex);
+ CXFA_Node* pSaveItems = m_pNode->CreateSamePacketNode(XFA_Element::Items);
+ m_pNode->InsertChild(-1, pSaveItems);
+ pSaveItems->JSObject()->SetBoolean(XFA_Attribute::Save, true, false);
+ InsertListTextItem(pSaveItems, wsNewValue, nIndex);
+ } else if (listitems.size() > 1) {
+ for (int32_t i = 0; i < 2; i++) {
+ CXFA_Node* pNode = listitems[i];
+ bool bHasSave = pNode->JSObject()->GetBoolean(XFA_Attribute::Save);
+ if (bHasSave)
+ InsertListTextItem(pNode, wsNewValue, nIndex);
+ else
+ InsertListTextItem(pNode, wsLabel, nIndex);
+ }
+ } else {
+ CXFA_Node* pNode = listitems[0];
+ pNode->JSObject()->SetBoolean(XFA_Attribute::Save, false, false);
+ pNode->JSObject()->SetEnum(XFA_Attribute::Presence,
+ XFA_AttributeEnum::Visible, false);
+ CXFA_Node* pSaveItems = m_pNode->CreateSamePacketNode(XFA_Element::Items);
+ m_pNode->InsertChild(-1, pSaveItems);
+ pSaveItems->JSObject()->SetBoolean(XFA_Attribute::Save, true, false);
+ pSaveItems->JSObject()->SetEnum(XFA_Attribute::Presence,
+ XFA_AttributeEnum::Hidden, false);
+ CXFA_Node* pListNode = pNode->GetNodeItem(XFA_NODEITEM_FirstChild);
+ int32_t i = 0;
+ while (pListNode) {
+ InsertListTextItem(pSaveItems, pListNode->JSObject()->GetContent(false),
+ i);
+ ++i;
+
+ pListNode = pListNode->GetNodeItem(XFA_NODEITEM_NextSibling);
+ }
+ InsertListTextItem(pNode, wsLabel, nIndex);
+ InsertListTextItem(pSaveItems, wsNewValue, nIndex);
+ }
+ if (!bNotify)
+ return;
+
+ m_pNode->GetDocument()->GetNotify()->OnWidgetListItemAdded(
+ this, wsLabel.c_str(), wsValue.c_str(), nIndex);
+}
+
+void CXFA_WidgetAcc::GetItemLabel(const WideStringView& wsValue,
+ WideString& wsLabel) {
+ int32_t iCount = 0;
+ std::vector<CXFA_Node*> listitems;
+ CXFA_Node* pItems = m_pNode->GetNodeItem(XFA_NODEITEM_FirstChild);
+ for (; pItems; pItems = pItems->GetNodeItem(XFA_NODEITEM_NextSibling)) {
+ if (pItems->GetElementType() != XFA_Element::Items)
+ continue;
+ iCount++;
+ listitems.push_back(pItems);
+ }
+
+ if (iCount <= 1) {
+ wsLabel = wsValue;
+ return;
+ }
+
+ CXFA_Node* pLabelItems = listitems[0];
+ bool bSave = pLabelItems->JSObject()->GetBoolean(XFA_Attribute::Save);
+ CXFA_Node* pSaveItems = nullptr;
+ if (bSave) {
+ pSaveItems = pLabelItems;
+ pLabelItems = listitems[1];
+ } else {
+ pSaveItems = listitems[1];
+ }
+ iCount = 0;
+
+ int32_t iSearch = -1;
+ for (CXFA_Node* pChildItem = pSaveItems->GetNodeItem(XFA_NODEITEM_FirstChild);
+ pChildItem;
+ pChildItem = pChildItem->GetNodeItem(XFA_NODEITEM_NextSibling)) {
+ if (pChildItem->JSObject()->GetContent(false) == wsValue) {
+ iSearch = iCount;
+ break;
+ }
+ iCount++;
+ }
+ if (iSearch < 0)
+ return;
+
+ CXFA_Node* pText =
+ pLabelItems->GetChild<CXFA_Node>(iSearch, XFA_Element::Unknown, false);
+ if (pText)
+ wsLabel = pText->JSObject()->GetContent(false);
+}
+
+WideString CXFA_WidgetAcc::GetItemValue(const WideStringView& wsLabel) {
+ int32_t iCount = 0;
+ std::vector<CXFA_Node*> listitems;
+ for (CXFA_Node* pItems = m_pNode->GetNodeItem(XFA_NODEITEM_FirstChild);
+ pItems; pItems = pItems->GetNodeItem(XFA_NODEITEM_NextSibling)) {
+ if (pItems->GetElementType() != XFA_Element::Items)
+ continue;
+ iCount++;
+ listitems.push_back(pItems);
+ }
+ if (iCount <= 1)
+ return WideString(wsLabel);
+
+ CXFA_Node* pLabelItems = listitems[0];
+ bool bSave = pLabelItems->JSObject()->GetBoolean(XFA_Attribute::Save);
+ CXFA_Node* pSaveItems = nullptr;
+ if (bSave) {
+ pSaveItems = pLabelItems;
+ pLabelItems = listitems[1];
+ } else {
+ pSaveItems = listitems[1];
+ }
+ iCount = 0;
+
+ int32_t iSearch = -1;
+ WideString wsContent;
+ CXFA_Node* pChildItem = pLabelItems->GetNodeItem(XFA_NODEITEM_FirstChild);
+ for (; pChildItem;
+ pChildItem = pChildItem->GetNodeItem(XFA_NODEITEM_NextSibling)) {
+ if (pChildItem->JSObject()->GetContent(false) == wsLabel) {
+ iSearch = iCount;
+ break;
+ }
+ iCount++;
+ }
+ if (iSearch < 0)
+ return L"";
+
+ CXFA_Node* pText =
+ pSaveItems->GetChild<CXFA_Node>(iSearch, XFA_Element::Unknown, false);
+ return pText ? pText->JSObject()->GetContent(false) : L"";
+}
+
+bool CXFA_WidgetAcc::DeleteItem(int32_t nIndex,
+ bool bNotify,
+ bool bScriptModify) {
+ bool bSetValue = false;
+ CXFA_Node* pItems = m_pNode->GetNodeItem(XFA_NODEITEM_FirstChild);
+ for (; pItems; pItems = pItems->GetNodeItem(XFA_NODEITEM_NextSibling)) {
+ if (pItems->GetElementType() != XFA_Element::Items)
+ continue;
+
+ if (nIndex < 0) {
+ while (CXFA_Node* pNode = pItems->GetNodeItem(XFA_NODEITEM_FirstChild)) {
+ pItems->RemoveChild(pNode, true);
+ }
+ } else {
+ if (!bSetValue && pItems->JSObject()->GetBoolean(XFA_Attribute::Save)) {
+ SetItemState(nIndex, false, true, bScriptModify, true);
+ bSetValue = true;
+ }
+ int32_t i = 0;
+ CXFA_Node* pNode = pItems->GetNodeItem(XFA_NODEITEM_FirstChild);
+ while (pNode) {
+ if (i == nIndex) {
+ pItems->RemoveChild(pNode, true);
+ break;
+ }
+ i++;
+ pNode = pNode->GetNodeItem(XFA_NODEITEM_NextSibling);
+ }
+ }
+ }
+ if (bNotify)
+ m_pNode->GetDocument()->GetNotify()->OnWidgetListItemRemoved(this, nIndex);
+ return true;
+}
+
+bool CXFA_WidgetAcc::IsHorizontalScrollPolicyOff() {
+ CXFA_Node* pUIChild = GetUIChild();
+ if (pUIChild) {
+ return pUIChild->JSObject()->GetEnum(XFA_Attribute::HScrollPolicy) ==
+ XFA_AttributeEnum::Off;
+ }
+ return false;
+}
+
+bool CXFA_WidgetAcc::IsVerticalScrollPolicyOff() {
+ CXFA_Node* pUIChild = GetUIChild();
+ if (pUIChild) {
+ return pUIChild->JSObject()->GetEnum(XFA_Attribute::VScrollPolicy) ==
+ XFA_AttributeEnum::Off;
+ }
+ return false;
+}
+
+pdfium::Optional<int32_t> CXFA_WidgetAcc::GetNumberOfCells() {
+ CXFA_Node* pUIChild = GetUIChild();
+ if (!pUIChild)
+ return {};
+ if (CXFA_Comb* pNode =
+ pUIChild->GetChild<CXFA_Comb>(0, XFA_Element::Comb, false))
+ return {pNode->JSObject()->GetInteger(XFA_Attribute::NumberOfCells)};
+ return {};
+}
+
+WideString CXFA_WidgetAcc::GetBarcodeType() {
+ CXFA_Node* pUIChild = GetUIChild();
+ return pUIChild
+ ? WideString(pUIChild->JSObject()->GetCData(XFA_Attribute::Type))
+ : WideString();
+}
+
+pdfium::Optional<BC_CHAR_ENCODING>
+CXFA_WidgetAcc::GetBarcodeAttribute_CharEncoding() {
+ pdfium::Optional<WideString> wsCharEncoding =
+ GetUIChild()->JSObject()->TryCData(XFA_Attribute::CharEncoding, true);
+ if (!wsCharEncoding)
+ return {};
+ if (wsCharEncoding->CompareNoCase(L"UTF-16"))
+ return {CHAR_ENCODING_UNICODE};
+ if (wsCharEncoding->CompareNoCase(L"UTF-8"))
+ return {CHAR_ENCODING_UTF8};
+ return {};
+}
+
+pdfium::Optional<bool> CXFA_WidgetAcc::GetBarcodeAttribute_Checksum() {
+ pdfium::Optional<XFA_AttributeEnum> checksum =
+ GetUIChild()->JSObject()->TryEnum(XFA_Attribute::Checksum, true);
+ if (!checksum)
+ return {};
+
+ switch (*checksum) {
+ case XFA_AttributeEnum::None:
+ return {false};
+ case XFA_AttributeEnum::Auto:
+ return {true};
+ case XFA_AttributeEnum::Checksum_1mod10:
+ case XFA_AttributeEnum::Checksum_1mod10_1mod11:
+ case XFA_AttributeEnum::Checksum_2mod10:
+ default:
+ break;
+ }
+ return {};
+}
+
+pdfium::Optional<int32_t> CXFA_WidgetAcc::GetBarcodeAttribute_DataLength() {
+ pdfium::Optional<WideString> wsDataLength =
+ GetUIChild()->JSObject()->TryCData(XFA_Attribute::DataLength, true);
+ if (!wsDataLength)
+ return {};
+
+ return {FXSYS_wtoi(wsDataLength->c_str())};
+}
+
+pdfium::Optional<char> CXFA_WidgetAcc::GetBarcodeAttribute_StartChar() {
+ pdfium::Optional<WideString> wsStartEndChar =
+ GetUIChild()->JSObject()->TryCData(XFA_Attribute::StartChar, true);
+ if (!wsStartEndChar || wsStartEndChar->IsEmpty())
+ return {};
+
+ return {static_cast<char>((*wsStartEndChar)[0])};
+}
+
+pdfium::Optional<char> CXFA_WidgetAcc::GetBarcodeAttribute_EndChar() {
+ pdfium::Optional<WideString> wsStartEndChar =
+ GetUIChild()->JSObject()->TryCData(XFA_Attribute::EndChar, true);
+ if (!wsStartEndChar || wsStartEndChar->IsEmpty())
+ return {};
+
+ return {static_cast<char>((*wsStartEndChar)[0])};
+}
+
+pdfium::Optional<int32_t> CXFA_WidgetAcc::GetBarcodeAttribute_ECLevel() {
+ pdfium::Optional<WideString> wsECLevel = GetUIChild()->JSObject()->TryCData(
+ XFA_Attribute::ErrorCorrectionLevel, true);
+ if (!wsECLevel)
+ return {};
+ return {FXSYS_wtoi(wsECLevel->c_str())};
+}
+
+pdfium::Optional<int32_t> CXFA_WidgetAcc::GetBarcodeAttribute_ModuleWidth() {
+ pdfium::Optional<CXFA_Measurement> moduleWidthHeight =
+ GetUIChild()->JSObject()->TryMeasure(XFA_Attribute::ModuleWidth, true);
+ if (!moduleWidthHeight)
+ return {};
+
+ return {static_cast<int32_t>(moduleWidthHeight->ToUnit(XFA_Unit::Pt))};
+}
+
+pdfium::Optional<int32_t> CXFA_WidgetAcc::GetBarcodeAttribute_ModuleHeight() {
+ pdfium::Optional<CXFA_Measurement> moduleWidthHeight =
+ GetUIChild()->JSObject()->TryMeasure(XFA_Attribute::ModuleHeight, true);
+ if (!moduleWidthHeight)
+ return {};
+
+ return {static_cast<int32_t>(moduleWidthHeight->ToUnit(XFA_Unit::Pt))};
+}
+
+pdfium::Optional<bool> CXFA_WidgetAcc::GetBarcodeAttribute_PrintChecksum() {
+ return GetUIChild()->JSObject()->TryBoolean(XFA_Attribute::PrintCheckDigit,
+ true);
+}
+
+pdfium::Optional<BC_TEXT_LOC>
+CXFA_WidgetAcc::GetBarcodeAttribute_TextLocation() {
+ pdfium::Optional<XFA_AttributeEnum> textLocation =
+ GetUIChild()->JSObject()->TryEnum(XFA_Attribute::TextLocation, true);
+ if (!textLocation)
+ return {};
+
+ switch (*textLocation) {
+ case XFA_AttributeEnum::None:
+ return {BC_TEXT_LOC_NONE};
+ case XFA_AttributeEnum::Above:
+ return {BC_TEXT_LOC_ABOVE};
+ case XFA_AttributeEnum::Below:
+ return {BC_TEXT_LOC_BELOW};
+ case XFA_AttributeEnum::AboveEmbedded:
+ return {BC_TEXT_LOC_ABOVEEMBED};
+ case XFA_AttributeEnum::BelowEmbedded:
+ return {BC_TEXT_LOC_BELOWEMBED};
+ default:
+ break;
+ }
+ return {};
+}
+
+pdfium::Optional<bool> CXFA_WidgetAcc::GetBarcodeAttribute_Truncate() {
+ return GetUIChild()->JSObject()->TryBoolean(XFA_Attribute::Truncate, true);
+}
+
+pdfium::Optional<int8_t> CXFA_WidgetAcc::GetBarcodeAttribute_WideNarrowRatio() {
+ pdfium::Optional<WideString> wsWideNarrowRatio =
+ GetUIChild()->JSObject()->TryCData(XFA_Attribute::WideNarrowRatio, true);
+ if (!wsWideNarrowRatio)
+ return {};
+
+ pdfium::Optional<size_t> ptPos = wsWideNarrowRatio->Find(':');
+ if (!ptPos)
+ return {static_cast<int8_t>(FXSYS_wtoi(wsWideNarrowRatio->c_str()))};
+
+ int32_t fB = FXSYS_wtoi(
+ wsWideNarrowRatio->Right(wsWideNarrowRatio->GetLength() - (*ptPos + 1))
+ .c_str());
+ if (!fB)
+ return {0};
+
+ int32_t fA = FXSYS_wtoi(wsWideNarrowRatio->Left(*ptPos).c_str());
+ float result = static_cast<float>(fA) / static_cast<float>(fB);
+ return {static_cast<int8_t>(result)};
+}
+
+WideString CXFA_WidgetAcc::GetPasswordChar() {
+ CXFA_Node* pUIChild = GetUIChild();
+ return pUIChild ? pUIChild->JSObject()->GetCData(XFA_Attribute::PasswordChar)
+ : L"*";
+}
+
+bool CXFA_WidgetAcc::IsMultiLine() {
+ CXFA_Node* pUIChild = GetUIChild();
+ return pUIChild && pUIChild->JSObject()->GetBoolean(XFA_Attribute::MultiLine);
+}
+
+std::pair<XFA_Element, int32_t> CXFA_WidgetAcc::GetMaxChars() {
+ if (CXFA_Value* pNode =
+ m_pNode->GetChild<CXFA_Value>(0, XFA_Element::Value, false)) {
+ if (CXFA_Node* pChild = pNode->GetNodeItem(XFA_NODEITEM_FirstChild)) {
+ switch (pChild->GetElementType()) {
+ case XFA_Element::Text:
+ return {XFA_Element::Text,
+ pChild->JSObject()->GetInteger(XFA_Attribute::MaxChars)};
+ case XFA_Element::ExData: {
+ int32_t iMax =
+ pChild->JSObject()->GetInteger(XFA_Attribute::MaxLength);
+ return {XFA_Element::ExData, iMax < 0 ? 0 : iMax};
+ }
+ default:
+ break;
+ }
+ }
+ }
+ return {XFA_Element::Unknown, 0};
+}
+
+int32_t CXFA_WidgetAcc::GetFracDigits() {
+ CXFA_Value* pNode =
+ m_pNode->GetChild<CXFA_Value>(0, XFA_Element::Value, false);
+ if (!pNode)
+ return -1;
+
+ CXFA_Decimal* pChild =
+ pNode->GetChild<CXFA_Decimal>(0, XFA_Element::Decimal, false);
+ if (!pChild)
+ return -1;
+
+ return pChild->JSObject()
+ ->TryInteger(XFA_Attribute::FracDigits, true)
+ .value_or(-1);
+}
+
+int32_t CXFA_WidgetAcc::GetLeadDigits() {
+ CXFA_Value* pNode =
+ m_pNode->GetChild<CXFA_Value>(0, XFA_Element::Value, false);
+ if (!pNode)
+ return -1;
+
+ CXFA_Decimal* pChild =
+ pNode->GetChild<CXFA_Decimal>(0, XFA_Element::Decimal, false);
+ if (!pChild)
+ return -1;
+
+ return pChild->JSObject()
+ ->TryInteger(XFA_Attribute::LeadDigits, true)
+ .value_or(-1);
+}
+
+bool CXFA_WidgetAcc::SetValue(XFA_VALUEPICTURE eValueType,
+ const WideString& wsValue) {
+ if (wsValue.IsEmpty()) {
+ if (m_pNode)
+ m_pNode->SyncValue(wsValue, true);
+ return true;
+ }
+
+ m_bPreNull = m_bIsNull;
+ m_bIsNull = false;
+ WideString wsNewText(wsValue);
+ WideString wsPicture = GetPictureContent(eValueType);
+ bool bValidate = true;
+ bool bSyncData = false;
+ CXFA_Node* pNode = GetUIChild();
+ if (!pNode)
+ return true;
+
+ XFA_Element eType = pNode->GetElementType();
+ if (!wsPicture.IsEmpty()) {
+ CXFA_LocaleMgr* pLocalMgr = m_pNode->GetDocument()->GetLocalMgr();
+ IFX_Locale* pLocale = GetLocale();
+ CXFA_LocaleValue widgetValue = XFA_GetLocaleValue(this);
+ bValidate =
+ widgetValue.ValidateValue(wsValue, wsPicture, pLocale, &wsPicture);
+ if (bValidate) {
+ widgetValue = CXFA_LocaleValue(widgetValue.GetType(), wsNewText,
+ wsPicture, pLocale, pLocalMgr);
+ wsNewText = widgetValue.GetValue();
+ if (eType == XFA_Element::NumericEdit)
+ wsNewText = NumericLimit(wsNewText, GetLeadDigits(), GetFracDigits());
+
+ bSyncData = true;
+ }
+ } else {
+ if (eType == XFA_Element::NumericEdit) {
+ if (wsNewText != L"0")
+ wsNewText = NumericLimit(wsNewText, GetLeadDigits(), GetFracDigits());
+
+ bSyncData = true;
+ }
+ }
+ if (eType != XFA_Element::NumericEdit || bSyncData) {
+ if (m_pNode)
+ m_pNode->SyncValue(wsNewText, true);
+ }
+
+ return bValidate;
+}
+
+WideString CXFA_WidgetAcc::GetPictureContent(XFA_VALUEPICTURE ePicture) {
+ if (ePicture == XFA_VALUEPICTURE_Raw)
+ return L"";
+
+ CXFA_LocaleValue widgetValue = XFA_GetLocaleValue(this);
+ switch (ePicture) {
+ case XFA_VALUEPICTURE_Display: {
+ if (CXFA_Format* pFormat =
+ m_pNode->GetChild<CXFA_Format>(0, XFA_Element::Format, false)) {
+ if (CXFA_Picture* pPicture = pFormat->GetChild<CXFA_Picture>(
+ 0, XFA_Element::Picture, false)) {
+ pdfium::Optional<WideString> picture =
+ pPicture->JSObject()->TryContent(false, true);
+ if (picture)
+ return *picture;
+ }
+ }
+
+ IFX_Locale* pLocale = GetLocale();
+ if (!pLocale)
+ return L"";
+
+ uint32_t dwType = widgetValue.GetType();
+ switch (dwType) {
+ case XFA_VT_DATE:
+ return pLocale->GetDatePattern(FX_LOCALEDATETIMESUBCATEGORY_Medium);
+ case XFA_VT_TIME:
+ return pLocale->GetTimePattern(FX_LOCALEDATETIMESUBCATEGORY_Medium);
+ case XFA_VT_DATETIME:
+ return pLocale->GetDatePattern(FX_LOCALEDATETIMESUBCATEGORY_Medium) +
+ L"T" +
+ pLocale->GetTimePattern(FX_LOCALEDATETIMESUBCATEGORY_Medium);
+ case XFA_VT_DECIMAL:
+ case XFA_VT_FLOAT:
+ default:
+ return L"";
+ }
+ }
+ case XFA_VALUEPICTURE_Edit: {
+ CXFA_Ui* pUI = m_pNode->GetChild<CXFA_Ui>(0, XFA_Element::Ui, false);
+ if (pUI) {
+ if (CXFA_Picture* pPicture =
+ pUI->GetChild<CXFA_Picture>(0, XFA_Element::Picture, false)) {
+ pdfium::Optional<WideString> picture =
+ pPicture->JSObject()->TryContent(false, true);
+ if (picture)
+ return *picture;
+ }
+ }
+
+ IFX_Locale* pLocale = GetLocale();
+ if (!pLocale)
+ return L"";
+
+ uint32_t dwType = widgetValue.GetType();
+ switch (dwType) {
+ case XFA_VT_DATE:
+ return pLocale->GetDatePattern(FX_LOCALEDATETIMESUBCATEGORY_Short);
+ case XFA_VT_TIME:
+ return pLocale->GetTimePattern(FX_LOCALEDATETIMESUBCATEGORY_Short);
+ case XFA_VT_DATETIME:
+ return pLocale->GetDatePattern(FX_LOCALEDATETIMESUBCATEGORY_Short) +
+ L"T" +
+ pLocale->GetTimePattern(FX_LOCALEDATETIMESUBCATEGORY_Short);
+ default:
+ return L"";
+ }
+ }
+ case XFA_VALUEPICTURE_DataBind: {
+ CXFA_Bind* bind = GetBind();
+ if (bind)
+ return bind->GetPicture();
+ break;
+ }
+ default:
+ break;
+ }
+ return L"";
+}
+
+IFX_Locale* CXFA_WidgetAcc::GetLocale() {
+ return m_pNode ? m_pNode->GetLocale() : nullptr;
+}
+
+WideString CXFA_WidgetAcc::GetValue(XFA_VALUEPICTURE eValueType) {
+ WideString wsValue = m_pNode->JSObject()->GetContent(false);
+
+ if (eValueType == XFA_VALUEPICTURE_Display)
+ GetItemLabel(wsValue.AsStringView(), wsValue);
+
+ WideString wsPicture = GetPictureContent(eValueType);
+ CXFA_Node* pNode = GetUIChild();
+ if (!pNode)
+ return wsValue;
+
+ switch (GetUIChild()->GetElementType()) {
+ case XFA_Element::ChoiceList: {
+ if (eValueType == XFA_VALUEPICTURE_Display) {
+ int32_t iSelItemIndex = GetSelectedItem(0);
+ if (iSelItemIndex >= 0) {
+ wsValue = GetChoiceListItem(iSelItemIndex, false).value_or(L"");
+ wsPicture.clear();
+ }
+ }
+ } break;
+ case XFA_Element::NumericEdit:
+ if (eValueType != XFA_VALUEPICTURE_Raw && wsPicture.IsEmpty()) {
+ IFX_Locale* pLocale = GetLocale();
+ if (eValueType == XFA_VALUEPICTURE_Display && pLocale)
+ wsValue = FormatNumStr(NormalizeNumStr(wsValue), pLocale);
+ }
+ break;
+ default:
+ break;
+ }
+ if (wsPicture.IsEmpty())
+ return wsValue;
+
+ if (IFX_Locale* pLocale = GetLocale()) {
+ CXFA_LocaleValue widgetValue = XFA_GetLocaleValue(this);
+ CXFA_LocaleMgr* pLocalMgr = m_pNode->GetDocument()->GetLocalMgr();
+ switch (widgetValue.GetType()) {
+ case XFA_VT_DATE: {
+ WideString wsDate, wsTime;
+ if (SplitDateTime(wsValue, wsDate, wsTime)) {
+ CXFA_LocaleValue date(XFA_VT_DATE, wsDate, pLocalMgr);
+ if (date.FormatPatterns(wsValue, wsPicture, pLocale, eValueType))
+ return wsValue;
+ }
+ break;
+ }
+ case XFA_VT_TIME: {
+ WideString wsDate, wsTime;
+ if (SplitDateTime(wsValue, wsDate, wsTime)) {
+ CXFA_LocaleValue time(XFA_VT_TIME, wsTime, pLocalMgr);
+ if (time.FormatPatterns(wsValue, wsPicture, pLocale, eValueType))
+ return wsValue;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ widgetValue.FormatPatterns(wsValue, wsPicture, pLocale, eValueType);
+ }
+ return wsValue;
+}
+
+WideString CXFA_WidgetAcc::GetNormalizeDataValue(const WideString& wsValue) {
+ if (wsValue.IsEmpty())
+ return L"";
+
+ WideString wsPicture = GetPictureContent(XFA_VALUEPICTURE_DataBind);
+ if (wsPicture.IsEmpty())
+ return wsValue;
+
+ ASSERT(GetNode());
+ CXFA_LocaleMgr* pLocalMgr = GetNode()->GetDocument()->GetLocalMgr();
+ IFX_Locale* pLocale = GetLocale();
+ CXFA_LocaleValue widgetValue = XFA_GetLocaleValue(this);
+ if (widgetValue.ValidateValue(wsValue, wsPicture, pLocale, &wsPicture)) {
+ widgetValue = CXFA_LocaleValue(widgetValue.GetType(), wsValue, wsPicture,
+ pLocale, pLocalMgr);
+ return widgetValue.GetValue();
+ }
+ return wsValue;
+}
+
+WideString CXFA_WidgetAcc::GetFormatDataValue(const WideString& wsValue) {
+ if (wsValue.IsEmpty())
+ return L"";
+
+ WideString wsPicture = GetPictureContent(XFA_VALUEPICTURE_DataBind);
+ if (wsPicture.IsEmpty())
+ return wsValue;
+
+ WideString wsFormattedValue = wsValue;
+ if (IFX_Locale* pLocale = GetLocale()) {
+ ASSERT(GetNode());
+ CXFA_Value* pNodeValue =
+ GetNode()->GetChild<CXFA_Value>(0, XFA_Element::Value, false);
+ if (!pNodeValue)
+ return wsValue;
+
+ CXFA_Node* pValueChild = pNodeValue->GetNodeItem(XFA_NODEITEM_FirstChild);
+ if (!pValueChild)
+ return wsValue;
+
+ int32_t iVTType = XFA_VT_NULL;
+ switch (pValueChild->GetElementType()) {
+ case XFA_Element::Decimal:
+ iVTType = XFA_VT_DECIMAL;
+ break;
+ case XFA_Element::Float:
+ iVTType = XFA_VT_FLOAT;
+ break;
+ case XFA_Element::Date:
+ iVTType = XFA_VT_DATE;
+ break;
+ case XFA_Element::Time:
+ iVTType = XFA_VT_TIME;
+ break;
+ case XFA_Element::DateTime:
+ iVTType = XFA_VT_DATETIME;
+ break;
+ case XFA_Element::Boolean:
+ iVTType = XFA_VT_BOOLEAN;
+ break;
+ case XFA_Element::Integer:
+ iVTType = XFA_VT_INTEGER;
+ break;
+ case XFA_Element::Text:
+ iVTType = XFA_VT_TEXT;
+ break;
+ default:
+ iVTType = XFA_VT_NULL;
+ break;
+ }
+ CXFA_LocaleMgr* pLocalMgr = GetNode()->GetDocument()->GetLocalMgr();
+ CXFA_LocaleValue widgetValue(iVTType, wsValue, pLocalMgr);
+ switch (widgetValue.GetType()) {
+ case XFA_VT_DATE: {
+ WideString wsDate, wsTime;
+ if (SplitDateTime(wsValue, wsDate, wsTime)) {
+ CXFA_LocaleValue date(XFA_VT_DATE, wsDate, pLocalMgr);
+ if (date.FormatPatterns(wsFormattedValue, wsPicture, pLocale,
+ XFA_VALUEPICTURE_DataBind)) {
+ return wsFormattedValue;
+ }
+ }
+ break;
+ }
+ case XFA_VT_TIME: {
+ WideString wsDate, wsTime;
+ if (SplitDateTime(wsValue, wsDate, wsTime)) {
+ CXFA_LocaleValue time(XFA_VT_TIME, wsTime, pLocalMgr);
+ if (time.FormatPatterns(wsFormattedValue, wsPicture, pLocale,
+ XFA_VALUEPICTURE_DataBind)) {
+ return wsFormattedValue;
+ }
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ widgetValue.FormatPatterns(wsFormattedValue, wsPicture, pLocale,
+ XFA_VALUEPICTURE_DataBind);
+ }
+ return wsFormattedValue;
+}
+
+WideString CXFA_WidgetAcc::NormalizeNumStr(const WideString& wsValue) {
+ if (wsValue.IsEmpty())
+ return L"";
+
+ WideString wsOutput = wsValue;
+ wsOutput.TrimLeft('0');
+
+ if (!wsOutput.IsEmpty() && wsOutput.Contains('.') && GetFracDigits() != -1) {
+ wsOutput.TrimRight(L"0");
+ wsOutput.TrimRight(L".");
+ }
+ if (wsOutput.IsEmpty() || wsOutput[0] == '.')
+ wsOutput.InsertAtFront('0');
+
+ return wsOutput;
+}
+
+WideString CXFA_WidgetAcc::FormatNumStr(const WideString& wsValue,
+ IFX_Locale* pLocale) {
+ if (wsValue.IsEmpty())
+ return L"";
+
+ WideString wsSrcNum = wsValue;
+ WideString wsGroupSymbol =
+ pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_Grouping);
+ bool bNeg = false;
+ if (wsSrcNum[0] == '-') {
+ bNeg = true;
+ wsSrcNum.Delete(0, 1);
+ }
+
+ auto dot_index = wsSrcNum.Find('.');
+ dot_index = !dot_index.has_value() ? wsSrcNum.GetLength() : dot_index;
+
+ if (dot_index.value() < 1)
+ return L"";
+
+ size_t nPos = dot_index.value() % 3;
+ WideString wsOutput;
+ for (size_t i = 0; i < dot_index.value(); i++) {
+ if (i % 3 == nPos && i != 0)
+ wsOutput += wsGroupSymbol;
+
+ wsOutput += wsSrcNum[i];
+ }
+ if (dot_index.value() < wsSrcNum.GetLength()) {
+ wsOutput += pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_Decimal);
+ wsOutput += wsSrcNum.Right(wsSrcNum.GetLength() - dot_index.value() - 1);
+ }
+ if (bNeg)
+ return pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_Minus) + wsOutput;
+
+ return wsOutput;
+}
+
+void CXFA_WidgetAcc::InsertListTextItem(CXFA_Node* pItems,
+ const WideString& wsText,
+ int32_t nIndex) {
+ CXFA_Node* pText = pItems->CreateSamePacketNode(XFA_Element::Text);
+ pItems->InsertChild(nIndex, pText);
+ pText->JSObject()->SetContent(wsText, wsText, false, false, false);
+}
+
+WideString CXFA_WidgetAcc::NumericLimit(const WideString& wsValue,
+ int32_t iLead,
+ int32_t iTread) const {
+ if ((iLead == -1) && (iTread == -1))
+ return wsValue;
+
+ WideString wsRet;
+ int32_t iLead_ = 0, iTread_ = -1;
+ int32_t iCount = wsValue.GetLength();
+ if (iCount == 0)
+ return wsValue;
+
+ int32_t i = 0;
+ if (wsValue[i] == L'-') {
+ wsRet += L'-';
+ i++;
+ }
+ for (; i < iCount; i++) {
+ wchar_t wc = wsValue[i];
+ if (FXSYS_isDecimalDigit(wc)) {
+ if (iLead >= 0) {
+ iLead_++;
+ if (iLead_ > iLead)
+ return L"0";
+ } else if (iTread_ >= 0) {
+ iTread_++;
+ if (iTread_ > iTread) {
+ if (iTread != -1) {
+ CFX_Decimal wsDeci = CFX_Decimal(wsValue.AsStringView());
+ wsDeci.SetScale(iTread);
+ wsRet = wsDeci;
+ }
+ return wsRet;
+ }
+ }
+ } else if (wc == L'.') {
+ iTread_ = 0;
+ iLead = -1;
+ }
+ wsRet += wc;
+ }
+ return wsRet;
+}