// Copyright 2014 PDFium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com

#include "core/fxcrt/include/fx_ext.h"
#include "xfa/fxbarcode/include/BC_Library.h"
#include "xfa/fxfa/app/xfa_ffnotify.h"
#include "xfa/fxfa/fm2js/xfa_fm2jsapi.h"
#include "xfa/fxfa/parser/xfa_docdata.h"
#include "xfa/fxfa/parser/xfa_doclayout.h"
#include "xfa/fxfa/parser/xfa_document.h"
#include "xfa/fxfa/parser/xfa_localemgr.h"
#include "xfa/fxfa/parser/xfa_localevalue.h"
#include "xfa/fxfa/parser/xfa_object.h"
#include "xfa/fxfa/parser/xfa_parser.h"
#include "xfa/fxfa/parser/xfa_script.h"
#include "xfa/fxfa/parser/xfa_utils.h"

static FX_ARGB XFA_WStringToColor(const CFX_WideStringC& wsValue) {
  uint8_t r = 0, g = 0, b = 0;
  if (wsValue.GetLength() == 0) {
    return 0xff000000;
  }
  int cc = 0;
  const FX_WCHAR* str = wsValue.raw_str();
  int len = wsValue.GetLength();
  while (XFA_IsSpace(str[cc]) && cc < len) {
    cc++;
  }
  if (cc >= len) {
    return 0xff000000;
  }
  while (cc < len) {
    if (str[cc] == ',' || !XFA_IsDigit(str[cc])) {
      break;
    }
    r = r * 10 + str[cc] - '0';
    cc++;
  }
  if (cc < len && str[cc] == ',') {
    cc++;
    while (XFA_IsSpace(str[cc]) && cc < len) {
      cc++;
    }
    while (cc < len) {
      if (str[cc] == ',' || !XFA_IsDigit(str[cc])) {
        break;
      }
      g = g * 10 + str[cc] - '0';
      cc++;
    }
    if (cc < len && str[cc] == ',') {
      cc++;
      while (XFA_IsSpace(str[cc]) && cc < len) {
        cc++;
      }
      while (cc < len) {
        if (str[cc] == ',' || !XFA_IsDigit(str[cc])) {
          break;
        }
        b = b * 10 + str[cc] - '0';
        cc++;
      }
    }
  }
  return (0xff << 24) | (r << 16) | (g << 8) | b;
}
XFA_ELEMENT CXFA_Data::GetClassID() const {
  return m_pNode ? m_pNode->GetClassID() : XFA_ELEMENT_UNKNOWN;
}
FX_BOOL CXFA_Data::TryMeasure(XFA_ATTRIBUTE eAttr,
                              FX_FLOAT& fValue,
                              FX_BOOL bUseDefault) const {
  CXFA_Measurement ms;
  if (m_pNode->TryMeasure(eAttr, ms, bUseDefault)) {
    fValue = ms.ToUnit(XFA_UNIT_Pt);
    return TRUE;
  }
  return FALSE;
}
FX_BOOL CXFA_Data::SetMeasure(XFA_ATTRIBUTE eAttr, FX_FLOAT fValue) {
  CXFA_Measurement ms(fValue, XFA_UNIT_Pt);
  return m_pNode->SetMeasure(eAttr, ms);
}
CXFA_Fill::CXFA_Fill(CXFA_Node* pNode) : CXFA_Data(pNode) {}
CXFA_Fill::~CXFA_Fill() {}
int32_t CXFA_Fill::GetPresence() {
  return m_pNode->GetEnum(XFA_ATTRIBUTE_Presence);
}
void CXFA_Fill::SetColor(FX_ARGB color) {
  CXFA_Node* pNode = m_pNode->GetProperty(0, XFA_ELEMENT_Color);
  CFX_WideString wsColor;
  int a, r, g, b;
  ArgbDecode(color, a, r, g, b);
  wsColor.Format(L"%d,%d,%d", r, g, b);
  pNode->SetCData(XFA_ATTRIBUTE_Value, wsColor);
}
FX_ARGB CXFA_Fill::GetColor(FX_BOOL bText) {
  if (CXFA_Node* pNode = m_pNode->GetChild(0, XFA_ELEMENT_Color)) {
    CFX_WideStringC wsColor;
    if (pNode->TryCData(XFA_ATTRIBUTE_Value, wsColor, FALSE)) {
      return XFA_WStringToColor(wsColor);
    }
  }
  if (bText) {
    return 0xFF000000;
  }
  return 0xFFFFFFFF;
}
int32_t CXFA_Fill::GetFillType() {
  CXFA_Node* pChild = m_pNode->GetNodeItem(XFA_NODEITEM_FirstChild);
  while (pChild) {
    int32_t eType = pChild->GetClassID();
    if (eType != XFA_ELEMENT_Color && eType != XFA_ELEMENT_Extras) {
      return eType;
    }
    pChild = pChild->GetNodeItem(XFA_NODEITEM_NextSibling);
  }
  return XFA_ELEMENT_Solid;
}
int32_t CXFA_Fill::GetPattern(FX_ARGB& foreColor) {
  CXFA_Node* pNode = m_pNode->GetProperty(0, XFA_ELEMENT_Pattern);
  if (CXFA_Node* pColor = pNode->GetChild(0, XFA_ELEMENT_Color)) {
    CFX_WideStringC wsColor;
    pColor->TryCData(XFA_ATTRIBUTE_Value, wsColor, FALSE);
    foreColor = XFA_WStringToColor(wsColor);
  } else {
    foreColor = 0xFF000000;
  }
  return pNode->GetEnum(XFA_ATTRIBUTE_Type);
}
int32_t CXFA_Fill::GetStipple(FX_ARGB& stippleColor) {
  CXFA_Node* pNode = m_pNode->GetProperty(0, XFA_ELEMENT_Stipple);
  int32_t eAttr = 50;
  pNode->TryInteger(XFA_ATTRIBUTE_Rate, eAttr);
  if (CXFA_Node* pColor = pNode->GetChild(0, XFA_ELEMENT_Color)) {
    CFX_WideStringC wsColor;
    pColor->TryCData(XFA_ATTRIBUTE_Value, wsColor, FALSE);
    stippleColor = XFA_WStringToColor(wsColor);
  } else {
    stippleColor = 0xFF000000;
  }
  return eAttr;
}
int32_t CXFA_Fill::GetLinear(FX_ARGB& endColor) {
  CXFA_Node* pNode = m_pNode->GetProperty(0, XFA_ELEMENT_Linear);
  XFA_ATTRIBUTEENUM eAttr = XFA_ATTRIBUTEENUM_ToRight;
  pNode->TryEnum(XFA_ATTRIBUTE_Type, eAttr);
  if (CXFA_Node* pColor = pNode->GetChild(0, XFA_ELEMENT_Color)) {
    CFX_WideStringC wsColor;
    pColor->TryCData(XFA_ATTRIBUTE_Value, wsColor, FALSE);
    endColor = XFA_WStringToColor(wsColor);
  } else {
    endColor = 0xFF000000;
  }
  return eAttr;
}
int32_t CXFA_Fill::GetRadial(FX_ARGB& endColor) {
  CXFA_Node* pNode = m_pNode->GetProperty(0, XFA_ELEMENT_Radial);
  XFA_ATTRIBUTEENUM eAttr = XFA_ATTRIBUTEENUM_ToEdge;
  pNode->TryEnum(XFA_ATTRIBUTE_Type, eAttr);
  if (CXFA_Node* pColor = pNode->GetChild(0, XFA_ELEMENT_Color)) {
    CFX_WideStringC wsColor;
    pColor->TryCData(XFA_ATTRIBUTE_Value, wsColor, FALSE);
    endColor = XFA_WStringToColor(wsColor);
  } else {
    endColor = 0xFF000000;
  }
  return eAttr;
}
CXFA_Margin::CXFA_Margin(CXFA_Node* pNode) : CXFA_Data(pNode) {}
FX_BOOL CXFA_Margin::GetLeftInset(FX_FLOAT& fInset, FX_FLOAT fDefInset) const {
  fInset = fDefInset;
  return TryMeasure(XFA_ATTRIBUTE_LeftInset, fInset);
}
FX_BOOL CXFA_Margin::GetTopInset(FX_FLOAT& fInset, FX_FLOAT fDefInset) const {
  fInset = fDefInset;
  return TryMeasure(XFA_ATTRIBUTE_TopInset, fInset);
}
FX_BOOL CXFA_Margin::GetRightInset(FX_FLOAT& fInset, FX_FLOAT fDefInset) const {
  fInset = fDefInset;
  return TryMeasure(XFA_ATTRIBUTE_RightInset, fInset);
}
FX_BOOL CXFA_Margin::GetBottomInset(FX_FLOAT& fInset,
                                    FX_FLOAT fDefInset) const {
  fInset = fDefInset;
  return TryMeasure(XFA_ATTRIBUTE_BottomInset, fInset);
}
CXFA_Font::CXFA_Font(CXFA_Node* pNode) : CXFA_Data(pNode) {}
FX_FLOAT CXFA_Font::GetBaselineShift() {
  return m_pNode->GetMeasure(XFA_ATTRIBUTE_BaselineShift).ToUnit(XFA_UNIT_Pt);
}
FX_FLOAT CXFA_Font::GetHorizontalScale() {
  CFX_WideString wsValue;
  m_pNode->TryCData(XFA_ATTRIBUTE_FontHorizontalScale, wsValue);
  int32_t iScale = FXSYS_wtoi((const FX_WCHAR*)wsValue);
  return iScale > 0 ? (FX_FLOAT)iScale : 100.0f;
}
FX_FLOAT CXFA_Font::GetVerticalScale() {
  CFX_WideString wsValue;
  m_pNode->TryCData(XFA_ATTRIBUTE_FontVerticalScale, wsValue);
  int32_t iScale = FXSYS_wtoi((const FX_WCHAR*)wsValue);
  return iScale > 0 ? (FX_FLOAT)iScale : 100.0f;
}
FX_FLOAT CXFA_Font::GetLetterSpacing() {
  CFX_WideStringC wsValue;
  if (!m_pNode->TryCData(XFA_ATTRIBUTE_LetterSpacing, wsValue)) {
    return 0;
  }
  CXFA_Measurement ms(wsValue);
  if (ms.GetUnit() == XFA_UNIT_Em) {
    return ms.GetValue() * GetFontSize();
  }
  return ms.ToUnit(XFA_UNIT_Pt);
}
int32_t CXFA_Font::GetLineThrough() {
  int32_t iValue = 0;
  m_pNode->TryInteger(XFA_ATTRIBUTE_LineThrough, iValue);
  return iValue;
}
int32_t CXFA_Font::GetUnderline() {
  int32_t iValue = 0;
  m_pNode->TryInteger(XFA_ATTRIBUTE_Underline, iValue);
  return iValue;
}
int32_t CXFA_Font::GetUnderlinePeriod() {
  XFA_ATTRIBUTEENUM eAttr = XFA_ATTRIBUTEENUM_All;
  m_pNode->TryEnum(XFA_ATTRIBUTE_UnderlinePeriod, eAttr);
  return eAttr;
}
FX_FLOAT CXFA_Font::GetFontSize() {
  CXFA_Measurement ms;
  m_pNode->TryMeasure(XFA_ATTRIBUTE_Size, ms);
  return ms.ToUnit(XFA_UNIT_Pt);
}
void CXFA_Font::GetTypeface(CFX_WideStringC& wsTypeFace) {
  m_pNode->TryCData(XFA_ATTRIBUTE_Typeface, wsTypeFace);
}
FX_BOOL CXFA_Font::IsBold() {
  XFA_ATTRIBUTEENUM eAttr = XFA_ATTRIBUTEENUM_Normal;
  m_pNode->TryEnum(XFA_ATTRIBUTE_Weight, eAttr);
  return eAttr == XFA_ATTRIBUTEENUM_Bold;
}
FX_BOOL CXFA_Font::IsItalic() {
  XFA_ATTRIBUTEENUM eAttr = XFA_ATTRIBUTEENUM_Normal;
  m_pNode->TryEnum(XFA_ATTRIBUTE_Posture, eAttr);
  return eAttr == XFA_ATTRIBUTEENUM_Italic;
}
void CXFA_Font::SetColor(FX_ARGB color) {
  CXFA_Fill fill(m_pNode->GetProperty(0, XFA_ELEMENT_Fill));
  fill.SetColor(color);
}
FX_ARGB CXFA_Font::GetColor() {
  CXFA_Fill fill(m_pNode->GetChild(0, XFA_ELEMENT_Fill));
  return fill ? fill.GetColor(TRUE) : 0xFF000000;
}
CXFA_Caption::CXFA_Caption(CXFA_Node* pNode) : CXFA_Data(pNode) {}
int32_t CXFA_Caption::GetPresence() {
  XFA_ATTRIBUTEENUM eAttr = XFA_ATTRIBUTEENUM_Visible;
  m_pNode->TryEnum(XFA_ATTRIBUTE_Presence, eAttr);
  return eAttr;
}
int32_t CXFA_Caption::GetPlacementType() {
  XFA_ATTRIBUTEENUM eAttr = XFA_ATTRIBUTEENUM_Left;
  m_pNode->TryEnum(XFA_ATTRIBUTE_Placement, eAttr);
  return eAttr;
}
FX_FLOAT CXFA_Caption::GetReserve() {
  CXFA_Measurement ms;
  m_pNode->TryMeasure(XFA_ATTRIBUTE_Reserve, ms);
  return ms.ToUnit(XFA_UNIT_Pt);
}
CXFA_Margin CXFA_Caption::GetMargin() {
  return CXFA_Margin(m_pNode ? m_pNode->GetChild(0, XFA_ELEMENT_Margin) : NULL);
}
CXFA_Font CXFA_Caption::GetFont() {
  return CXFA_Font(m_pNode ? m_pNode->GetChild(0, XFA_ELEMENT_Font) : NULL);
}
CXFA_Value CXFA_Caption::GetValue() {
  return CXFA_Value(m_pNode ? m_pNode->GetChild(0, XFA_ELEMENT_Value) : NULL);
}
CXFA_Para::CXFA_Para(CXFA_Node* pNode) : CXFA_Data(pNode) {}
int32_t CXFA_Para::GetHorizontalAlign() {
  XFA_ATTRIBUTEENUM eAttr = XFA_ATTRIBUTEENUM_Left;
  m_pNode->TryEnum(XFA_ATTRIBUTE_HAlign, eAttr);
  return eAttr;
}
int32_t CXFA_Para::GetVerticalAlign() {
  XFA_ATTRIBUTEENUM eAttr = XFA_ATTRIBUTEENUM_Top;
  m_pNode->TryEnum(XFA_ATTRIBUTE_VAlign, eAttr);
  return eAttr;
}
FX_FLOAT CXFA_Para::GetLineHeight() {
  CXFA_Measurement ms;
  m_pNode->TryMeasure(XFA_ATTRIBUTE_LineHeight, ms);
  return ms.ToUnit(XFA_UNIT_Pt);
}
FX_FLOAT CXFA_Para::GetMarginLeft() {
  CXFA_Measurement ms;
  m_pNode->TryMeasure(XFA_ATTRIBUTE_MarginLeft, ms);
  return ms.ToUnit(XFA_UNIT_Pt);
}
FX_FLOAT CXFA_Para::GetMarginRight() {
  CXFA_Measurement ms;
  m_pNode->TryMeasure(XFA_ATTRIBUTE_MarginRight, ms);
  return ms.ToUnit(XFA_UNIT_Pt);
}
FX_FLOAT CXFA_Para::GetSpaceAbove() {
  CXFA_Measurement ms;
  m_pNode->TryMeasure(XFA_ATTRIBUTE_SpaceAbove, ms);
  return ms.ToUnit(XFA_UNIT_Pt);
}
FX_FLOAT CXFA_Para::GetSpaceBelow() {
  CXFA_Measurement ms;
  m_pNode->TryMeasure(XFA_ATTRIBUTE_SpaceBelow, ms);
  return ms.ToUnit(XFA_UNIT_Pt);
}
FX_FLOAT CXFA_Para::GetTextIndent() {
  CXFA_Measurement ms;
  m_pNode->TryMeasure(XFA_ATTRIBUTE_TextIndent, ms);
  return ms.ToUnit(XFA_UNIT_Pt);
}
CXFA_Event::CXFA_Event(CXFA_Node* pNode) : CXFA_Data(pNode) {}
int32_t CXFA_Event::GetActivity() {
  return m_pNode->GetEnum(XFA_ATTRIBUTE_Activity);
}
int32_t CXFA_Event::GetEventType() {
  CXFA_Node* pChild = m_pNode->GetNodeItem(XFA_NODEITEM_FirstChild);
  while (pChild) {
    int32_t eType = pChild->GetClassID();
    if (eType != XFA_ELEMENT_Extras) {
      return eType;
    }
    pChild = pChild->GetNodeItem(XFA_NODEITEM_NextSibling);
  }
  return XFA_ELEMENT_UNKNOWN;
}
void CXFA_Event::GetRef(CFX_WideStringC& wsRef) {
  m_pNode->TryCData(XFA_ATTRIBUTE_Ref, wsRef);
}
CXFA_Script CXFA_Event::GetScript() {
  return CXFA_Script(m_pNode->GetChild(0, XFA_ELEMENT_Script));
}
CXFA_Submit CXFA_Event::GetSubmit() {
  return CXFA_Submit(m_pNode->GetChild(0, XFA_ELEMENT_Submit));
}
void CXFA_Event::GetSignDataTarget(CFX_WideString& wsTarget) {
  if (CXFA_Node* pNode = m_pNode->GetProperty(0, XFA_ELEMENT_SignData)) {
    CFX_WideStringC wsCData;
    pNode->TryCData(XFA_ATTRIBUTE_Target, wsCData);
    wsTarget = wsCData;
  }
}
CXFA_Script::CXFA_Script(CXFA_Node* pNode) : CXFA_Data(pNode) {}
XFA_SCRIPTTYPE CXFA_Script::GetContentType() {
  CFX_WideStringC cData;
  if (m_pNode->TryCData(XFA_ATTRIBUTE_ContentType, cData, FALSE)) {
    if (cData == FX_WSTRC(L"application/x-javascript")) {
      return XFA_SCRIPTTYPE_Javascript;
    } else if (cData == FX_WSTRC(L"application/x-formcalc")) {
      return XFA_SCRIPTTYPE_Formcalc;
    } else {
      return XFA_SCRIPTTYPE_Unkown;
    }
  }
  return XFA_SCRIPTTYPE_Formcalc;
}
int32_t CXFA_Script::GetRunAt() {
  return m_pNode->GetEnum(XFA_ATTRIBUTE_RunAt);
}
void CXFA_Script::GetExpression(CFX_WideString& wsExpression) {
  m_pNode->TryContent(wsExpression);
}
CXFA_Submit::CXFA_Submit(CXFA_Node* pNode) : CXFA_Data(pNode) {}
FX_BOOL CXFA_Submit::IsSubmitEmbedPDF() {
  return m_pNode->GetBoolean(XFA_ATTRIBUTE_EmbedPDF);
}
int32_t CXFA_Submit::GetSubmitFormat() {
  return m_pNode->GetEnum(XFA_ATTRIBUTE_Format);
}
void CXFA_Submit::GetSubmitTarget(CFX_WideStringC& wsTarget) {
  m_pNode->TryCData(XFA_ATTRIBUTE_Target, wsTarget);
}
void CXFA_Submit::GetSubmitXDPContent(CFX_WideStringC& wsContent) {
  m_pNode->TryCData(XFA_ATTRIBUTE_XdpContent, wsContent);
}
XFA_ELEMENT CXFA_Value::GetChildValueClassID() {
  if (!m_pNode) {
    return XFA_ELEMENT_UNKNOWN;
  }
  if (CXFA_Node* pNode = m_pNode->GetNodeItem(XFA_NODEITEM_FirstChild)) {
    return pNode->GetClassID();
  }
  return XFA_ELEMENT_UNKNOWN;
}
FX_BOOL CXFA_Value::GetChildValueContent(CFX_WideString& wsContent) {
  if (!m_pNode) {
    return FALSE;
  }
  if (CXFA_Node* pNode = m_pNode->GetNodeItem(XFA_NODEITEM_FirstChild)) {
    return pNode->TryContent(wsContent);
  }
  return FALSE;
}
CXFA_Arc CXFA_Value::GetArc() {
  return CXFA_Arc(m_pNode ? m_pNode->GetNodeItem(XFA_NODEITEM_FirstChild)
                          : nullptr);
}
CXFA_Line CXFA_Value::GetLine() {
  return CXFA_Line(m_pNode ? m_pNode->GetNodeItem(XFA_NODEITEM_FirstChild)
                           : nullptr);
}
CXFA_Rectangle CXFA_Value::GetRectangle() {
  return CXFA_Rectangle(m_pNode ? m_pNode->GetNodeItem(XFA_NODEITEM_FirstChild)
                                : nullptr);
}
CXFA_Text CXFA_Value::GetText() {
  return CXFA_Text(m_pNode ? m_pNode->GetNodeItem(XFA_NODEITEM_FirstChild)
                           : nullptr);
}
CXFA_ExData CXFA_Value::GetExData() {
  return CXFA_ExData(m_pNode ? m_pNode->GetNodeItem(XFA_NODEITEM_FirstChild)
                             : nullptr);
}
CXFA_Image CXFA_Value::GetImage() {
  return CXFA_Image(
      m_pNode ? (m_pNode->GetNodeItem(XFA_NODEITEM_FirstChild)) : nullptr,
      TRUE);
}
int32_t CXFA_Line::GetHand() {
  return m_pNode->GetEnum(XFA_ATTRIBUTE_Hand);
}
FX_BOOL CXFA_Line::GetSlop() {
  XFA_ATTRIBUTEENUM eSlop = m_pNode->GetEnum(XFA_ATTRIBUTE_Slope);
  return eSlop == XFA_ATTRIBUTEENUM_Slash;
}
CXFA_Edge CXFA_Line::GetEdge() {
  return CXFA_Edge(m_pNode->GetChild(0, XFA_ELEMENT_Edge));
}
CXFA_Text::CXFA_Text(CXFA_Node* pNode) : CXFA_Data(pNode) {}
void CXFA_Text::GetContent(CFX_WideString& wsText) {
  m_pNode->TryContent(wsText);
}
CXFA_ExData::CXFA_ExData(CXFA_Node* pNode) : CXFA_Data(pNode) {}
FX_BOOL CXFA_ExData::SetContentType(const CFX_WideString& wsContentType) {
  return m_pNode->SetCData(XFA_ATTRIBUTE_ContentType, wsContentType);
}
CXFA_Image::CXFA_Image(CXFA_Node* pNode, FX_BOOL bDefValue)
    : CXFA_Data(pNode), m_bDefValue(bDefValue) {}
int32_t CXFA_Image::GetAspect() {
  return m_pNode->GetEnum(XFA_ATTRIBUTE_Aspect);
}
FX_BOOL CXFA_Image::GetContentType(CFX_WideString& wsContentType) {
  return m_pNode->TryCData(XFA_ATTRIBUTE_ContentType, wsContentType);
}
FX_BOOL CXFA_Image::GetHref(CFX_WideString& wsHref) {
  if (m_bDefValue) {
    return m_pNode->TryCData(XFA_ATTRIBUTE_Href, wsHref);
  }
  return m_pNode->GetAttribute(FX_WSTRC(L"href"), wsHref);
}
int32_t CXFA_Image::GetTransferEncoding() {
  if (m_bDefValue) {
    return m_pNode->GetEnum(XFA_ATTRIBUTE_TransferEncoding);
  }
  return XFA_ATTRIBUTEENUM_Base64;
}
FX_BOOL CXFA_Image::GetContent(CFX_WideString& wsText) {
  return m_pNode->TryContent(wsText);
}
FX_BOOL CXFA_Image::SetContentType(const CFX_WideString& wsContentType) {
  return m_pNode->SetCData(XFA_ATTRIBUTE_ContentType, wsContentType);
}
FX_BOOL CXFA_Image::SetHref(const CFX_WideString& wsHref) {
  if (m_bDefValue) {
    return m_pNode->SetCData(XFA_ATTRIBUTE_Href, wsHref);
  }
  return m_pNode->SetAttribute(XFA_ATTRIBUTE_Href, wsHref);
}
FX_BOOL CXFA_Image::SetTransferEncoding(int32_t iTransferEncoding) {
  if (m_bDefValue) {
    return m_pNode->SetEnum(XFA_ATTRIBUTE_TransferEncoding,
                            (XFA_ATTRIBUTEENUM)iTransferEncoding);
  }
  return TRUE;
}
CXFA_Calculate::CXFA_Calculate(CXFA_Node* pNode) : CXFA_Data(pNode) {}
int32_t CXFA_Calculate::GetOverride() {
  XFA_ATTRIBUTEENUM eAtt = XFA_ATTRIBUTEENUM_Error;
  m_pNode->TryEnum(XFA_ATTRIBUTE_Override, eAtt, FALSE);
  return eAtt;
}
CXFA_Script CXFA_Calculate::GetScript() {
  return CXFA_Script(m_pNode->GetChild(0, XFA_ELEMENT_Script));
}
void CXFA_Calculate::GetMessageText(CFX_WideString& wsMessage) {
  if (CXFA_Node* pNode = m_pNode->GetChild(0, XFA_ELEMENT_Message)) {
    CXFA_Text text(pNode->GetChild(0, XFA_ELEMENT_Text));
    if (text) {
      text.GetContent(wsMessage);
    }
  }
}
CXFA_Validate::CXFA_Validate(CXFA_Node* pNode) : CXFA_Data(pNode) {}
int32_t CXFA_Validate::GetFormatTest() {
  return m_pNode->GetEnum(XFA_ATTRIBUTE_FormatTest);
}
FX_BOOL CXFA_Validate::SetTestValue(int32_t iType,
                                    CFX_WideString& wsValue,
                                    XFA_ATTRIBUTEENUM eName) {
  const XFA_ATTRIBUTEENUMINFO* pInfo = XFA_GetAttributeEnumByName(wsValue);
  if (pInfo) {
    eName = pInfo->eName;
  }
  m_pNode->SetEnum((XFA_ATTRIBUTE)iType, eName, FALSE);
  return TRUE;
}
FX_BOOL CXFA_Validate::SetNullTest(CFX_WideString wsValue) {
  return SetTestValue(XFA_ATTRIBUTE_NullTest, wsValue,
                      XFA_ATTRIBUTEENUM_Disabled);
}
int32_t CXFA_Validate::GetNullTest() {
  return m_pNode->GetEnum(XFA_ATTRIBUTE_NullTest);
}
int32_t CXFA_Validate::GetScriptTest() {
  return m_pNode->GetEnum(XFA_ATTRIBUTE_ScriptTest);
}
void CXFA_Validate::GetMessageText(CFX_WideString& wsMessage,
                                   const CFX_WideStringC& wsMessageType) {
  if (CXFA_Node* pNode = m_pNode->GetProperty(0, XFA_ELEMENT_Message, FALSE)) {
    CXFA_Node* pItemNode = pNode->GetNodeItem(XFA_NODEITEM_FirstChild);
    for (; pItemNode;
         pItemNode = pItemNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
      if (pItemNode->GetClassID() != XFA_ELEMENT_Text) {
        continue;
      }
      CFX_WideStringC wsName;
      pItemNode->TryCData(XFA_ATTRIBUTE_Name, wsName);
      if (wsName.IsEmpty() || wsName == wsMessageType) {
        pItemNode->TryContent(wsMessage);
        return;
      }
    }
  }
}
void CXFA_Validate::SetFormatMessageText(CFX_WideString wsMessage) {
  SetMessageText(wsMessage, FX_WSTRC(L"formatTest"));
}
void CXFA_Validate::GetFormatMessageText(CFX_WideString& wsMessage) {
  GetMessageText(wsMessage, FX_WSTRC(L"formatTest"));
}
void CXFA_Validate::SetNullMessageText(CFX_WideString wsMessage) {
  SetMessageText(wsMessage, FX_WSTRC(L"nullTest"));
}
void CXFA_Validate::GetNullMessageText(CFX_WideString& wsMessage) {
  GetMessageText(wsMessage, FX_WSTRC(L"nullTest"));
}
void CXFA_Validate::SetMessageText(CFX_WideString& wsMessage,
                                   const CFX_WideStringC& wsMessageType) {
  if (CXFA_Node* pNode = m_pNode->GetProperty(0, XFA_ELEMENT_Message, TRUE)) {
    CXFA_Node* pItemNode = pNode->GetNodeItem(XFA_NODEITEM_FirstChild);
    for (; pItemNode;
         pItemNode = pItemNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
      if (pItemNode->GetClassID() != XFA_ELEMENT_Text) {
        continue;
      }
      CFX_WideStringC wsName;
      pItemNode->TryCData(XFA_ATTRIBUTE_Name, wsName);
      if (wsName.IsEmpty() || wsName == wsMessageType) {
        pItemNode->SetContent(wsMessage, wsMessage, FALSE);
        return;
      }
    }
    CXFA_Node* pTextNode = pNode->CreateSamePacketNode(XFA_ELEMENT_Text);
    pNode->InsertChild(pTextNode);
    pTextNode->SetCData(XFA_ATTRIBUTE_Name, wsMessageType, FALSE);
    pTextNode->SetContent(wsMessage, wsMessage, FALSE);
  }
}
void CXFA_Validate::GetScriptMessageText(CFX_WideString& wsMessage) {
  GetMessageText(wsMessage, FX_WSTRC(L"scriptTest"));
}
void CXFA_Validate::SetScriptMessageText(CFX_WideString wsMessage) {
  SetMessageText(wsMessage, FX_WSTRC(L"scriptTest"));
}
void CXFA_Validate::GetPicture(CFX_WideString& wsPicture) {
  if (CXFA_Node* pNode = m_pNode->GetChild(0, XFA_ELEMENT_Picture)) {
    pNode->TryContent(wsPicture);
  }
}
CXFA_Script CXFA_Validate::GetScript() {
  return CXFA_Script(m_pNode->GetChild(0, XFA_ELEMENT_Script));
}
CXFA_Bind::CXFA_Bind(CXFA_Node* pNode) : CXFA_Data(pNode) {}
void CXFA_Bind::GetPicture(CFX_WideString& wsPicture) {
  if (CXFA_Node* pPicture = m_pNode->GetChild(0, XFA_ELEMENT_Picture)) {
    pPicture->TryContent(wsPicture);
  }
}
CXFA_Assist::CXFA_Assist(CXFA_Node* pNode) : CXFA_Data(pNode) {}
CXFA_ToolTip CXFA_Assist::GetToolTip() {
  return CXFA_ToolTip(m_pNode->GetChild(0, XFA_ELEMENT_ToolTip));
}
CXFA_ToolTip::CXFA_ToolTip(CXFA_Node* pNode) : CXFA_Data(pNode) {}
FX_BOOL CXFA_ToolTip::GetTip(CFX_WideString& wsTip) {
  return m_pNode->TryContent(wsTip);
}
CXFA_BindItems::CXFA_BindItems(CXFA_Node* pNode) : CXFA_Data(pNode) {}
void CXFA_BindItems::GetLabelRef(CFX_WideStringC& wsLabelRef) {
  m_pNode->TryCData(XFA_ATTRIBUTE_LabelRef, wsLabelRef);
}
void CXFA_BindItems::GetValueRef(CFX_WideStringC& wsValueRef) {
  m_pNode->TryCData(XFA_ATTRIBUTE_ValueRef, wsValueRef);
}
void CXFA_BindItems::GetRef(CFX_WideStringC& wsRef) {
  m_pNode->TryCData(XFA_ATTRIBUTE_Ref, wsRef);
}
FX_BOOL CXFA_BindItems::SetConnection(const CFX_WideString& wsConnection) {
  return m_pNode->SetCData(XFA_ATTRIBUTE_Connection, wsConnection);
}
int32_t CXFA_Box::GetHand() const {
  if (!m_pNode) {
    return XFA_ATTRIBUTEENUM_Even;
  }
  return m_pNode->GetEnum(XFA_ATTRIBUTE_Hand);
}
int32_t CXFA_Box::GetPresence() const {
  if (!m_pNode) {
    return XFA_ATTRIBUTEENUM_Hidden;
  }
  return m_pNode->GetEnum(XFA_ATTRIBUTE_Presence);
}
int32_t CXFA_Box::CountEdges() const {
  if (!m_pNode) {
    return 0;
  }
  return m_pNode->CountChildren(XFA_ELEMENT_Edge);
}
CXFA_Edge CXFA_Box::GetEdge(int32_t nIndex) const {
  return CXFA_Edge(
      m_pNode ? m_pNode->GetProperty(nIndex, XFA_ELEMENT_Edge, nIndex == 0)
              : nullptr);
}
static void XFA_BOX_GetStrokes(CXFA_Node* pNode,
                               CXFA_StrokeArray& strokes,
                               FX_BOOL bNULL) {
  strokes.RemoveAll();
  if (!pNode) {
    return;
  }
  strokes.SetSize(8);
  int32_t i, j;
  for (i = 0, j = 0; i < 4; i++) {
    CXFA_Corner corner =
        CXFA_Corner(pNode->GetProperty(i, XFA_ELEMENT_Corner, i == 0));
    if (corner || i == 0) {
      strokes.SetAt(j, corner);
    } else if (bNULL) {
      strokes.SetAt(j, CXFA_Stroke(nullptr));
    } else if (i == 1) {
      strokes.SetAt(j, strokes[0]);
    } else if (i == 2) {
      strokes.SetAt(j, strokes[0]);
    } else {
      strokes.SetAt(j, strokes[2]);
    }
    j++;
    CXFA_Edge edge = CXFA_Edge(pNode->GetProperty(i, XFA_ELEMENT_Edge, i == 0));
    if (edge || i == 0) {
      strokes.SetAt(j, edge);
    } else if (bNULL) {
      strokes.SetAt(j, CXFA_Stroke(nullptr));
    } else if (i == 1) {
      strokes.SetAt(j, strokes[1]);
    } else if (i == 2) {
      strokes.SetAt(j, strokes[1]);
    } else {
      strokes.SetAt(j, strokes[3]);
    }
    j++;
  }
}
void CXFA_Box::GetStrokes(CXFA_StrokeArray& strokes) const {
  XFA_BOX_GetStrokes(m_pNode, strokes, FALSE);
}
FX_BOOL CXFA_Box::IsCircular() const {
  if (!m_pNode) {
    return FALSE;
  }
  return m_pNode->GetBoolean(XFA_ATTRIBUTE_Circular);
}
FX_BOOL CXFA_Box::GetStartAngle(FX_FLOAT& fStartAngle) const {
  fStartAngle = 0;
  if (!m_pNode) {
    return FALSE;
  }
  CXFA_Measurement ms;
  FX_BOOL bRet = m_pNode->TryMeasure(XFA_ATTRIBUTE_StartAngle, ms, FALSE);
  if (bRet) {
    fStartAngle = ms.GetValue();
  }
  return bRet;
}
FX_BOOL CXFA_Box::GetSweepAngle(FX_FLOAT& fSweepAngle) const {
  fSweepAngle = 360;
  if (!m_pNode) {
    return FALSE;
  }
  CXFA_Measurement ms;
  FX_BOOL bRet = m_pNode->TryMeasure(XFA_ATTRIBUTE_SweepAngle, ms, FALSE);
  if (bRet) {
    fSweepAngle = ms.GetValue();
  }
  return bRet;
}
CXFA_Fill CXFA_Box::GetFill(FX_BOOL bModified) const {
  if (!m_pNode) {
    return CXFA_Fill(nullptr);
  }
  CXFA_Node* pFillNode = m_pNode->GetProperty(0, XFA_ELEMENT_Fill, bModified);
  return CXFA_Fill(pFillNode);
}
CXFA_Margin CXFA_Box::GetMargin() const {
  return CXFA_Margin(m_pNode ? m_pNode->GetChild(0, XFA_ELEMENT_Margin)
                             : nullptr);
}
static int32_t XFA_BOX_3DStyle(const CXFA_StrokeArray& strokes,
                               CXFA_Stroke& stroke) {
  int32_t iCount = strokes.GetSize();
  if (iCount < 1) {
    return 0;
  }
  stroke = strokes[0];
  for (int32_t i = 1; i < iCount; i++) {
    CXFA_Stroke find = strokes[i];
    if (!find) {
      continue;
    }
    if (!stroke) {
      stroke = find;
    } else if (stroke.GetStrokeType() != find.GetStrokeType()) {
      stroke = find;
      break;
    }
  }
  int32_t iType = stroke.GetStrokeType();
  if (iType == XFA_ATTRIBUTEENUM_Lowered || iType == XFA_ATTRIBUTEENUM_Raised ||
      iType == XFA_ATTRIBUTEENUM_Etched ||
      iType == XFA_ATTRIBUTEENUM_Embossed) {
    return iType;
  }
  return 0;
}
int32_t CXFA_Box::Get3DStyle(FX_BOOL& bVisible, FX_FLOAT& fThickness) const {
  if (IsArc()) {
    return 0;
  }
  CXFA_StrokeArray strokes;
  XFA_BOX_GetStrokes(m_pNode, strokes, TRUE);
  CXFA_Stroke stroke(NULL);
  int32_t iType = XFA_BOX_3DStyle(strokes, stroke);
  if (iType) {
    bVisible = stroke.IsVisible();
    fThickness = stroke.GetThickness();
  }
  return iType;
}
int32_t CXFA_Stroke::GetPresence() const {
  return m_pNode ? m_pNode->GetEnum(XFA_ATTRIBUTE_Presence)
                 : XFA_ATTRIBUTEENUM_Invisible;
}
int32_t CXFA_Stroke::GetCapType() const {
  if (!m_pNode) {
    return XFA_ATTRIBUTEENUM_Square;
  }
  return m_pNode->GetEnum(XFA_ATTRIBUTE_Cap);
}
int32_t CXFA_Stroke::GetStrokeType() const {
  return m_pNode ? m_pNode->GetEnum(XFA_ATTRIBUTE_Stroke)
                 : XFA_ATTRIBUTEENUM_Solid;
}
FX_FLOAT CXFA_Stroke::GetThickness() const {
  return GetMSThickness().ToUnit(XFA_UNIT_Pt);
}
CXFA_Measurement CXFA_Stroke::GetMSThickness() const {
  return m_pNode ? m_pNode->GetMeasure(XFA_ATTRIBUTE_Thickness)
                 : XFA_GetAttributeDefaultValue_Measure(XFA_ELEMENT_Edge,
                                                        XFA_ATTRIBUTE_Thickness,
                                                        XFA_XDPPACKET_Form);
}
void CXFA_Stroke::SetMSThickness(CXFA_Measurement msThinkness) {
  if (!m_pNode) {
    return;
  }
  m_pNode->SetMeasure(XFA_ATTRIBUTE_Thickness, msThinkness);
}
FX_ARGB CXFA_Stroke::GetColor() const {
  if (!m_pNode) {
    return 0xFF000000;
  }
  CXFA_Node* pNode = m_pNode->GetChild(0, XFA_ELEMENT_Color);
  if (!pNode) {
    return 0xFF000000;
  }
  CFX_WideStringC wsColor;
  pNode->TryCData(XFA_ATTRIBUTE_Value, wsColor);
  return XFA_WStringToColor(wsColor);
}
void CXFA_Stroke::SetColor(FX_ARGB argb) {
  if (!m_pNode) {
    return;
  }
  CXFA_Node* pNode = m_pNode->GetProperty(0, XFA_ELEMENT_Color);
  CFX_WideString wsColor;
  int a, r, g, b;
  ArgbDecode(argb, a, r, g, b);
  wsColor.Format(L"%d,%d,%d", r, g, b);
  pNode->SetCData(XFA_ATTRIBUTE_Value, wsColor);
}
int32_t CXFA_Stroke::GetJoinType() const {
  return m_pNode ? m_pNode->GetEnum(XFA_ATTRIBUTE_Join)
                 : XFA_ATTRIBUTEENUM_Square;
}
FX_BOOL CXFA_Stroke::IsInverted() const {
  return m_pNode ? m_pNode->GetBoolean(XFA_ATTRIBUTE_Inverted) : FALSE;
}
FX_FLOAT CXFA_Stroke::GetRadius() const {
  return m_pNode ? m_pNode->GetMeasure(XFA_ATTRIBUTE_Radius).ToUnit(XFA_UNIT_Pt)
                 : 0;
}
FX_BOOL CXFA_Stroke::SameStyles(CXFA_Stroke stroke, uint32_t dwFlags) const {
  if (m_pNode == stroke.GetNode()) {
    return TRUE;
  }
  if (FXSYS_fabs(GetThickness() - stroke.GetThickness()) >= 0.01f) {
    return FALSE;
  }
  if ((dwFlags & XFA_STROKE_SAMESTYLE_NoPresence) == 0 &&
      IsVisible() != stroke.IsVisible()) {
    return FALSE;
  }
  if (GetStrokeType() != stroke.GetStrokeType()) {
    return FALSE;
  }
  if (GetColor() != stroke.GetColor()) {
    return FALSE;
  }
  if ((dwFlags & XFA_STROKE_SAMESTYLE_Corner) != 0 &&
      FXSYS_fabs(GetRadius() - stroke.GetRadius()) >= 0.01f) {
    return FALSE;
  }
  return TRUE;
}
FX_FLOAT XFA_GetEdgeThickness(const CXFA_StrokeArray& strokes,
                              FX_BOOL b3DStyle,
                              int32_t nIndex) {
  FX_FLOAT fThickness = 0;
  {
    if (strokes[nIndex * 2 + 1].GetPresence() == XFA_ATTRIBUTEENUM_Visible) {
      if (nIndex == 0) {
        fThickness += 2.5f;
      }
      fThickness += strokes[nIndex * 2 + 1].GetThickness() * (b3DStyle ? 4 : 2);
    }
  }
  return fThickness;
}
CXFA_WidgetData::CXFA_WidgetData(CXFA_Node* pNode)
    : CXFA_Data(pNode),
      m_bIsNull(TRUE),
      m_bPreNull(TRUE),
      m_pUiChildNode(NULL),
      m_eUIType(XFA_ELEMENT_UNKNOWN) {}
CXFA_Node* CXFA_WidgetData::GetUIChild() {
  if (m_eUIType == XFA_ELEMENT_UNKNOWN) {
    m_pUiChildNode = XFA_CreateUIChild(m_pNode, m_eUIType);
  }
  return m_pUiChildNode;
}
XFA_ELEMENT CXFA_WidgetData::GetUIType() {
  GetUIChild();
  return m_eUIType;
}
CFX_WideString CXFA_WidgetData::GetRawValue() {
  return m_pNode->GetContent();
}
int32_t CXFA_WidgetData::GetAccess(FX_BOOL bTemplate) {
  if (bTemplate) {
    CXFA_Node* pNode = m_pNode->GetTemplateNode();
    if (pNode) {
      return pNode->GetEnum(XFA_ATTRIBUTE_Access);
    }
    return XFA_ATTRIBUTEENUM_Open;
  }
  CXFA_Node* pNode = m_pNode;
  while (pNode) {
    int32_t iAcc = pNode->GetEnum(XFA_ATTRIBUTE_Access);
    if (iAcc != XFA_ATTRIBUTEENUM_Open) {
      return iAcc;
    }
    pNode =
        pNode->GetNodeItem(XFA_NODEITEM_Parent, XFA_OBJECTTYPE_ContainerNode);
  }
  return XFA_ATTRIBUTEENUM_Open;
}
int32_t CXFA_WidgetData::GetRotate() {
  CXFA_Measurement ms;
  if (!m_pNode->TryMeasure(XFA_ATTRIBUTE_Rotate, ms, FALSE)) {
    return 0;
  }
  int32_t iRotate = FXSYS_round(ms.GetValue());
  iRotate = XFA_MapRotation(iRotate);
  return iRotate / 90 * 90;
}
CXFA_Border CXFA_WidgetData::GetBorder(FX_BOOL bModified) {
  return CXFA_Border(m_pNode->GetProperty(0, XFA_ELEMENT_Border, bModified));
}
CXFA_Caption CXFA_WidgetData::GetCaption(FX_BOOL bModified) {
  return CXFA_Caption(m_pNode->GetProperty(0, XFA_ELEMENT_Caption, bModified));
}
CXFA_Font CXFA_WidgetData::GetFont(FX_BOOL bModified) {
  return CXFA_Font(m_pNode->GetProperty(0, XFA_ELEMENT_Font, bModified));
}
CXFA_Margin CXFA_WidgetData::GetMargin(FX_BOOL bModified) {
  return CXFA_Margin(m_pNode->GetProperty(0, XFA_ELEMENT_Margin, bModified));
}
CXFA_Para CXFA_WidgetData::GetPara(FX_BOOL bModified) {
  return CXFA_Para(m_pNode->GetProperty(0, XFA_ELEMENT_Para, bModified));
}
void CXFA_WidgetData::GetEventList(CXFA_NodeArray& events) {
  m_pNode->GetNodeList(events, 0, XFA_ELEMENT_Event);
}
int32_t CXFA_WidgetData::GetEventByActivity(int32_t iActivity,
                                            CXFA_NodeArray& events,
                                            FX_BOOL bIsFormReady) {
  CXFA_NodeArray allEvents;
  GetEventList(allEvents);
  int32_t iCount = allEvents.GetSize();
  for (int32_t i = 0; i < iCount; i++) {
    CXFA_Event event(allEvents[i]);
    if (event.GetActivity() == iActivity) {
      if (iActivity == XFA_ATTRIBUTEENUM_Ready) {
        CFX_WideStringC wsRef;
        event.GetRef(wsRef);
        if (bIsFormReady) {
          if (wsRef == CFX_WideStringC(L"$form")) {
            events.Add(allEvents[i]);
          }
        } else {
          if (wsRef == CFX_WideStringC(L"$layout")) {
            events.Add(allEvents[i]);
          }
        }
      } else {
        events.Add(allEvents[i]);
      }
    }
  }
  return events.GetSize();
}
CXFA_Value CXFA_WidgetData::GetDefaultValue(FX_BOOL bModified) {
  CXFA_Node* pTemNode = m_pNode->GetTemplateNode();
  return CXFA_Value(pTemNode
                        ? pTemNode->GetProperty(0, XFA_ELEMENT_Value, bModified)
                        : nullptr);
}
CXFA_Value CXFA_WidgetData::GetFormValue(FX_BOOL bModified) {
  return CXFA_Value(m_pNode->GetProperty(0, XFA_ELEMENT_Value, bModified));
}
CXFA_Calculate CXFA_WidgetData::GetCalculate(FX_BOOL bModified) {
  return CXFA_Calculate(
      m_pNode->GetProperty(0, XFA_ELEMENT_Calculate, bModified));
}
CXFA_Validate CXFA_WidgetData::GetValidate(FX_BOOL bModified) {
  return CXFA_Validate(
      m_pNode->GetProperty(0, XFA_ELEMENT_Validate, bModified));
}
CXFA_Bind CXFA_WidgetData::GetBind(FX_BOOL bModified) {
  return CXFA_Bind(m_pNode->GetProperty(0, XFA_ELEMENT_Bind, bModified));
}
CXFA_Assist CXFA_WidgetData::GetAssist(FX_BOOL bModified) {
  return CXFA_Assist(m_pNode->GetProperty(0, XFA_ELEMENT_Assist, bModified));
}
FX_BOOL CXFA_WidgetData::GetWidth(FX_FLOAT& fWidth) {
  return TryMeasure(XFA_ATTRIBUTE_W, fWidth);
}
FX_BOOL CXFA_WidgetData::GetHeight(FX_FLOAT& fHeight) {
  return TryMeasure(XFA_ATTRIBUTE_H, fHeight);
}
FX_BOOL CXFA_WidgetData::GetMinWidth(FX_FLOAT& fMinWidth) {
  return TryMeasure(XFA_ATTRIBUTE_MinW, fMinWidth);
}
FX_BOOL CXFA_WidgetData::GetMinHeight(FX_FLOAT& fMinHeight) {
  return TryMeasure(XFA_ATTRIBUTE_MinH, fMinHeight);
}
FX_BOOL CXFA_WidgetData::GetMaxWidth(FX_FLOAT& fMaxWidth) {
  return TryMeasure(XFA_ATTRIBUTE_MaxW, fMaxWidth);
}
FX_BOOL CXFA_WidgetData::GetMaxHeight(FX_FLOAT& fMaxHeight) {
  return TryMeasure(XFA_ATTRIBUTE_MaxH, fMaxHeight);
}
CXFA_Border CXFA_WidgetData::GetUIBorder(FX_BOOL bModified) {
  CXFA_Node* pUIChild = GetUIChild();
  return CXFA_Border(
      pUIChild ? pUIChild->GetProperty(0, XFA_ELEMENT_Border, bModified)
               : nullptr);
}
CXFA_Margin CXFA_WidgetData::GetUIMargin(FX_BOOL bModified) {
  CXFA_Node* pUIChild = GetUIChild();
  return CXFA_Margin(
      pUIChild ? pUIChild->GetProperty(0, XFA_ELEMENT_Margin, bModified)
               : nullptr);
}
void CXFA_WidgetData::GetUIMargin(CFX_RectF& rtUIMargin) {
  rtUIMargin.Reset();
  CXFA_Margin mgUI = GetUIMargin();
  if (!mgUI) {
    return;
  }
  CXFA_Border border = GetUIBorder();
  if (border && border.GetPresence() != XFA_ATTRIBUTEENUM_Visible) {
    return;
  }
  FX_FLOAT fLeftInset, fTopInset, fRightInset, fBottomInset;
  FX_BOOL bLeft = mgUI.GetLeftInset(fLeftInset);
  FX_BOOL bTop = mgUI.GetTopInset(fTopInset);
  FX_BOOL bRight = mgUI.GetRightInset(fRightInset);
  FX_BOOL bBottom = mgUI.GetBottomInset(fBottomInset);
  if (border) {
    FX_BOOL bVisible = FALSE;
    FX_FLOAT fThickness = 0;
    border.Get3DStyle(bVisible, fThickness);
    if (!bLeft || !bTop || !bRight || !bBottom) {
      CXFA_StrokeArray strokes;
      border.GetStrokes(strokes);
      if (!bTop) {
        fTopInset = XFA_GetEdgeThickness(strokes, bVisible, 0);
      }
      if (!bRight) {
        fRightInset = XFA_GetEdgeThickness(strokes, bVisible, 1);
      }
      if (!bBottom) {
        fBottomInset = XFA_GetEdgeThickness(strokes, bVisible, 2);
      }
      if (!bLeft) {
        fLeftInset = XFA_GetEdgeThickness(strokes, bVisible, 3);
      }
    }
  }
  rtUIMargin.Set(fLeftInset, fTopInset, fRightInset, fBottomInset);
}
int32_t CXFA_WidgetData::GetButtonHighlight() {
  CXFA_Node* pUIChild = GetUIChild();
  if (pUIChild) {
    return pUIChild->GetEnum(XFA_ATTRIBUTE_Highlight);
  }
  return XFA_GetAttributeDefaultValue_Enum(
      XFA_ELEMENT_Button, XFA_ATTRIBUTE_Highlight, XFA_XDPPACKET_Form);
}
FX_BOOL CXFA_WidgetData::GetButtonRollover(CFX_WideString& wsRollover,
                                           FX_BOOL& bRichText) {
  if (CXFA_Node* pItems = m_pNode->GetChild(0, XFA_ELEMENT_Items)) {
    CXFA_Node* pText = pItems->GetNodeItem(XFA_NODEITEM_FirstChild);
    while (pText) {
      CFX_WideStringC wsName;
      pText->TryCData(XFA_ATTRIBUTE_Name, wsName);
      if (wsName == FX_WSTRC(L"rollover")) {
        pText->TryContent(wsRollover);
        bRichText = pText->GetClassID() == XFA_ELEMENT_ExData;
        return !wsRollover.IsEmpty();
      }
      pText = pText->GetNodeItem(XFA_NODEITEM_NextSibling);
    }
  }
  return FALSE;
}
FX_BOOL CXFA_WidgetData::GetButtonDown(CFX_WideString& wsDown,
                                       FX_BOOL& bRichText) {
  if (CXFA_Node* pItems = m_pNode->GetChild(0, XFA_ELEMENT_Items)) {
    CXFA_Node* pText = pItems->GetNodeItem(XFA_NODEITEM_FirstChild);
    while (pText) {
      CFX_WideStringC wsName;
      pText->TryCData(XFA_ATTRIBUTE_Name, wsName);
      if (wsName == FX_WSTRC(L"down")) {
        pText->TryContent(wsDown);
        bRichText = pText->GetClassID() == XFA_ELEMENT_ExData;
        return !wsDown.IsEmpty();
      }
      pText = pText->GetNodeItem(XFA_NODEITEM_NextSibling);
    }
  }
  return FALSE;
}
int32_t CXFA_WidgetData::GetCheckButtonShape() {
  CXFA_Node* pUIChild = GetUIChild();
  if (pUIChild) {
    return pUIChild->GetEnum(XFA_ATTRIBUTE_Shape);
  }
  return XFA_GetAttributeDefaultValue_Enum(
      XFA_ELEMENT_CheckButton, XFA_ATTRIBUTE_Shape, XFA_XDPPACKET_Form);
}
int32_t CXFA_WidgetData::GetCheckButtonMark() {
  CXFA_Node* pUIChild = GetUIChild();
  if (pUIChild) {
    return pUIChild->GetEnum(XFA_ATTRIBUTE_Mark);
  }
  return XFA_GetAttributeDefaultValue_Enum(
      XFA_ELEMENT_CheckButton, XFA_ATTRIBUTE_Mark, XFA_XDPPACKET_Form);
}
FX_BOOL CXFA_WidgetData::IsRadioButton() {
  if (CXFA_Node* pParent = m_pNode->GetNodeItem(XFA_NODEITEM_Parent)) {
    return pParent->GetClassID() == XFA_ELEMENT_ExclGroup;
  }
  return FALSE;
}
FX_FLOAT CXFA_WidgetData::GetCheckButtonSize() {
  CXFA_Node* pUIChild = GetUIChild();
  if (pUIChild) {
    return pUIChild->GetMeasure(XFA_ATTRIBUTE_Size).ToUnit(XFA_UNIT_Pt);
  }
  return XFA_GetAttributeDefaultValue_Measure(
             XFA_ELEMENT_CheckButton, XFA_ATTRIBUTE_Size, XFA_XDPPACKET_Form)
      .ToUnit(XFA_UNIT_Pt);
}
FX_BOOL CXFA_WidgetData::IsAllowNeutral() {
  CXFA_Node* pUIChild = GetUIChild();
  if (pUIChild) {
    return pUIChild->GetBoolean(XFA_ATTRIBUTE_AllowNeutral);
  }
  return XFA_GetAttributeDefaultValue_Boolean(
      XFA_ELEMENT_CheckButton, XFA_ATTRIBUTE_AllowNeutral, XFA_XDPPACKET_Form);
}
XFA_CHECKSTATE CXFA_WidgetData::GetCheckState() {
  CFX_WideString wsValue = GetRawValue();
  if (wsValue.IsEmpty()) {
    return XFA_CHECKSTATE_Off;
  }
  if (CXFA_Node* pItems = m_pNode->GetChild(0, XFA_ELEMENT_Items)) {
    CXFA_Node* pText = pItems->GetNodeItem(XFA_NODEITEM_FirstChild);
    int32_t i = 0;
    while (pText) {
      CFX_WideString wsContent;
      if (pText->TryContent(wsContent) && (wsContent == wsValue)) {
        return (XFA_CHECKSTATE)i;
      }
      i++;
      pText = pText->GetNodeItem(XFA_NODEITEM_NextSibling);
    }
  }
  return XFA_CHECKSTATE_Off;
}
void CXFA_WidgetData::SetCheckState(XFA_CHECKSTATE eCheckState,
                                    FX_BOOL bNotify) {
  CXFA_WidgetData exclGroup(GetExclGroupNode());
  if (exclGroup) {
    CFX_WideString wsValue;
    if (eCheckState != XFA_CHECKSTATE_Off) {
      if (CXFA_Node* pItems = m_pNode->GetChild(0, XFA_ELEMENT_Items)) {
        CXFA_Node* pText = pItems->GetNodeItem(XFA_NODEITEM_FirstChild);
        if (pText) {
          pText->TryContent(wsValue);
        }
      }
    }
    CXFA_Node* pChild =
        exclGroup.GetNode()->GetNodeItem(XFA_NODEITEM_FirstChild);
    for (; pChild; pChild = pChild->GetNodeItem(XFA_NODEITEM_NextSibling)) {
      if (pChild->GetClassID() != XFA_ELEMENT_Field) {
        continue;
      }
      CXFA_Node* pItem = pChild->GetChild(0, XFA_ELEMENT_Items);
      if (!pItem) {
        continue;
      }
      CXFA_Node* pItemchild = pItem->GetNodeItem(XFA_NODEITEM_FirstChild);
      if (!pItemchild) {
        continue;
      }
      CFX_WideString text = pItemchild->GetContent();
      CFX_WideString wsChildValue = text;
      if (wsValue != text) {
        pItemchild = pItemchild->GetNodeItem(XFA_NODEITEM_NextSibling);
        if (pItemchild) {
          wsChildValue = pItemchild->GetContent();
        } else {
          wsChildValue.Empty();
        }
      }
      CXFA_WidgetData ch(pChild);
      ch.SyncValue(wsChildValue, bNotify);
    }
    exclGroup.SyncValue(wsValue, bNotify);
  } else {
    CXFA_Node* pItems = m_pNode->GetChild(0, XFA_ELEMENT_Items);
    if (!pItems) {
      return;
    }
    int32_t i = -1;
    CXFA_Node* pText = pItems->GetNodeItem(XFA_NODEITEM_FirstChild);
    CFX_WideString wsContent;
    while (pText) {
      i++;
      if (i == eCheckState) {
        pText->TryContent(wsContent);
        break;
      }
      pText = pText->GetNodeItem(XFA_NODEITEM_NextSibling);
    }
    SyncValue(wsContent, bNotify);
  }
}
CXFA_Node* CXFA_WidgetData::GetExclGroupNode() {
  CXFA_Node* pExcl = ToNode(m_pNode->GetNodeItem(XFA_NODEITEM_Parent));
  if (!pExcl || pExcl->GetClassID() != XFA_ELEMENT_ExclGroup) {
    return NULL;
  }
  return pExcl;
}
CXFA_Node* CXFA_WidgetData::GetSelectedMember() {
  CXFA_Node* pSelectedMember = NULL;
  CFX_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_WidgetData widgetData(pNode);
    if (widgetData.GetCheckState() == XFA_CHECKSTATE_On) {
      pSelectedMember = pNode;
      break;
    }
  }
  return pSelectedMember;
}
CXFA_Node* CXFA_WidgetData::SetSelectedMember(const CFX_WideStringC& wsName,
                                              FX_BOOL bNotify) {
  CXFA_Node* pSelectedMember = NULL;
  uint32_t nameHash =
      FX_HashCode_String_GetW(wsName.raw_str(), wsName.GetLength());
  for (CXFA_Node* pNode = ToNode(m_pNode->GetNodeItem(XFA_NODEITEM_FirstChild));
       pNode; pNode = pNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
    if (pNode->GetNameHash() == nameHash) {
      CXFA_WidgetData widgetData(pNode);
      widgetData.SetCheckState(XFA_CHECKSTATE_On, bNotify);
      pSelectedMember = pNode;
      break;
    }
  }
  return pSelectedMember;
}
void CXFA_WidgetData::SetSelectedMemberByValue(const CFX_WideStringC& wsValue,
                                               FX_BOOL bNotify,
                                               FX_BOOL bScriptModify,
                                               FX_BOOL bSyncData) {
  CFX_WideString wsExclGroup;
  for (CXFA_Node* pNode = m_pNode->GetNodeItem(XFA_NODEITEM_FirstChild); pNode;
       pNode = pNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
    if (pNode->GetClassID() != XFA_ELEMENT_Field) {
      continue;
    }
    CXFA_Node* pItem = pNode->GetChild(0, XFA_ELEMENT_Items);
    if (!pItem) {
      continue;
    }
    CXFA_Node* pItemchild = pItem->GetNodeItem(XFA_NODEITEM_FirstChild);
    if (!pItemchild) {
      continue;
    }
    CFX_WideString wsChildValue = pItemchild->GetContent();
    if (wsValue != wsChildValue) {
      pItemchild = pItemchild->GetNodeItem(XFA_NODEITEM_NextSibling);
      if (pItemchild) {
        wsChildValue = pItemchild->GetContent();
      } else {
        wsChildValue.Empty();
      }
    } else {
      wsExclGroup = wsValue;
    }
    pNode->SetContent(wsChildValue, wsChildValue, bNotify, bScriptModify,
                      FALSE);
  }
  if (m_pNode) {
    m_pNode->SetContent(wsExclGroup, wsExclGroup, bNotify, bScriptModify,
                        bSyncData);
  }
}
CXFA_Node* CXFA_WidgetData::GetExclGroupFirstMember() {
  CXFA_Node* pExcl = GetNode();
  if (!pExcl) {
    return NULL;
  }
  CXFA_Node* pNode = pExcl->GetNodeItem(XFA_NODEITEM_FirstChild);
  while (pNode) {
    if (pNode->GetClassID() == XFA_ELEMENT_Field) {
      return pNode;
    }
    pNode = pNode->GetNodeItem(XFA_NODEITEM_NextSibling);
  }
  return NULL;
}
CXFA_Node* CXFA_WidgetData::GetExclGroupNextMember(CXFA_Node* pNode) {
  if (!pNode) {
    return NULL;
  }
  CXFA_Node* pNodeField = pNode->GetNodeItem(XFA_NODEITEM_NextSibling);
  while (pNodeField) {
    if (pNodeField->GetClassID() == XFA_ELEMENT_Field) {
      return pNodeField;
    }
    pNodeField = pNodeField->GetNodeItem(XFA_NODEITEM_NextSibling);
  }
  return NULL;
}
int32_t CXFA_WidgetData::GetChoiceListCommitOn() {
  CXFA_Node* pUIChild = GetUIChild();
  if (pUIChild) {
    return pUIChild->GetEnum(XFA_ATTRIBUTE_CommitOn);
  }
  return XFA_GetAttributeDefaultValue_Enum(
      XFA_ELEMENT_ChoiceList, XFA_ATTRIBUTE_CommitOn, XFA_XDPPACKET_Form);
}
FX_BOOL CXFA_WidgetData::IsChoiceListAllowTextEntry() {
  CXFA_Node* pUIChild = GetUIChild();
  if (pUIChild) {
    return pUIChild->GetBoolean(XFA_ATTRIBUTE_TextEntry);
  }
  return XFA_GetAttributeDefaultValue_Boolean(
      XFA_ELEMENT_ChoiceList, XFA_ATTRIBUTE_TextEntry, XFA_XDPPACKET_Form);
}
int32_t CXFA_WidgetData::GetChoiceListOpen() {
  CXFA_Node* pUIChild = GetUIChild();
  if (pUIChild) {
    return pUIChild->GetEnum(XFA_ATTRIBUTE_Open);
  }
  return XFA_GetAttributeDefaultValue_Enum(
      XFA_ELEMENT_ChoiceList, XFA_ATTRIBUTE_Open, XFA_XDPPACKET_Form);
}
FX_BOOL CXFA_WidgetData::IsListBox() {
  int32_t iOpenMode = GetChoiceListOpen();
  return (iOpenMode == XFA_ATTRIBUTEENUM_Always ||
          iOpenMode == XFA_ATTRIBUTEENUM_MultiSelect);
}
int32_t CXFA_WidgetData::CountChoiceListItems(FX_BOOL bSaveValue) {
  CXFA_NodeArray pItems;
  CXFA_Node* pItem = NULL;
  int32_t iCount = 0;
  CXFA_Node* pNode = m_pNode->GetNodeItem(XFA_NODEITEM_FirstChild);
  for (; pNode; pNode = pNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
    if (pNode->GetClassID() != XFA_ELEMENT_Items) {
      continue;
    }
    iCount++;
    pItems.Add(pNode);
    if (iCount == 2) {
      break;
    }
  }
  if (iCount == 0) {
    return 0;
  }
  pItem = pItems[0];
  if (iCount > 1) {
    FX_BOOL bItemOneHasSave = pItems[0]->GetBoolean(XFA_ATTRIBUTE_Save);
    FX_BOOL bItemTwoHasSave = pItems[1]->GetBoolean(XFA_ATTRIBUTE_Save);
    if (bItemOneHasSave != bItemTwoHasSave && bSaveValue == bItemTwoHasSave) {
      pItem = pItems[1];
    }
  }
  pItems.RemoveAll();
  return pItem->CountChildren(XFA_ELEMENT_UNKNOWN);
}
FX_BOOL CXFA_WidgetData::GetChoiceListItem(CFX_WideString& wsText,
                                           int32_t nIndex,
                                           FX_BOOL bSaveValue) {
  wsText.Empty();
  CXFA_NodeArray pItemsArray;
  CXFA_Node* pItems = NULL;
  int32_t iCount = 0;
  CXFA_Node* pNode = m_pNode->GetNodeItem(XFA_NODEITEM_FirstChild);
  for (; pNode; pNode = pNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
    if (pNode->GetClassID() != XFA_ELEMENT_Items) {
      continue;
    }
    iCount++;
    pItemsArray.Add(pNode);
    if (iCount == 2) {
      break;
    }
  }
  if (iCount == 0) {
    return FALSE;
  }
  pItems = pItemsArray[0];
  if (iCount > 1) {
    FX_BOOL bItemOneHasSave = pItemsArray[0]->GetBoolean(XFA_ATTRIBUTE_Save);
    FX_BOOL bItemTwoHasSave = pItemsArray[1]->GetBoolean(XFA_ATTRIBUTE_Save);
    if (bItemOneHasSave != bItemTwoHasSave && bSaveValue == bItemTwoHasSave) {
      pItems = pItemsArray[1];
    }
  }
  if (pItems) {
    CXFA_Node* pItem = pItems->GetChild(nIndex, XFA_ELEMENT_UNKNOWN);
    if (pItem) {
      pItem->TryContent(wsText);
      return TRUE;
    }
  }
  return FALSE;
}
void CXFA_WidgetData::GetChoiceListItems(CFX_WideStringArray& wsTextArray,
                                         FX_BOOL bSaveValue) {
  CXFA_NodeArray pItems;
  CXFA_Node* pItem = NULL;
  int32_t iCount = 0;
  CXFA_Node* pNode = m_pNode->GetNodeItem(XFA_NODEITEM_FirstChild);
  for (; pNode; pNode = pNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
    if (pNode->GetClassID() != XFA_ELEMENT_Items) {
      continue;
    }
    iCount++;
    pItems.Add(pNode);
    if (iCount == 2) {
      break;
    }
  }
  if (iCount == 0) {
    return;
  }
  pItem = pItems[0];
  if (iCount > 1) {
    FX_BOOL bItemOneHasSave = pItems[0]->GetBoolean(XFA_ATTRIBUTE_Save);
    FX_BOOL bItemTwoHasSave = pItems[1]->GetBoolean(XFA_ATTRIBUTE_Save);
    if (bItemOneHasSave != bItemTwoHasSave && bSaveValue == bItemTwoHasSave) {
      pItem = pItems[1];
    }
  }
  pItems.RemoveAll();
  pNode = pItem->GetNodeItem(XFA_NODEITEM_FirstChild);
  for (; pNode; pNode = pNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
    pNode->TryContent(wsTextArray.Add());
  }
}
int32_t CXFA_WidgetData::CountSelectedItems() {
  CFX_WideStringArray wsValueArray;
  GetSelectedItemsValue(wsValueArray);
  if (IsListBox() || !IsChoiceListAllowTextEntry()) {
    return wsValueArray.GetSize();
  }
  int32_t iSelected = 0;
  CFX_WideStringArray wsSaveTextArray;
  GetChoiceListItems(wsSaveTextArray, TRUE);
  int32_t iValues = wsValueArray.GetSize();
  for (int32_t i = 0; i < iValues; i++) {
    int32_t iSaves = wsSaveTextArray.GetSize();
    for (int32_t j = 0; j < iSaves; j++) {
      if (wsValueArray[i] == wsSaveTextArray[j]) {
        iSelected++;
        break;
      }
    }
  }
  return iSelected;
}
int32_t CXFA_WidgetData::GetSelectedItem(int32_t nIndex) {
  CFX_WideStringArray wsValueArray;
  GetSelectedItemsValue(wsValueArray);
  CFX_WideStringArray wsSaveTextArray;
  GetChoiceListItems(wsSaveTextArray, TRUE);
  int32_t iSaves = wsSaveTextArray.GetSize();
  for (int32_t j = 0; j < iSaves; j++) {
    if (wsValueArray[nIndex] == wsSaveTextArray[j]) {
      return j;
    }
  }
  return -1;
}
void CXFA_WidgetData::GetSelectedItems(CFX_Int32Array& iSelArray) {
  CFX_WideStringArray wsValueArray;
  GetSelectedItemsValue(wsValueArray);
  int32_t iValues = wsValueArray.GetSize();
  if (iValues < 1) {
    return;
  }
  CFX_WideStringArray wsSaveTextArray;
  GetChoiceListItems(wsSaveTextArray, TRUE);
  int32_t iSaves = wsSaveTextArray.GetSize();
  for (int32_t i = 0; i < iValues; i++) {
    for (int32_t j = 0; j < iSaves; j++) {
      if (wsValueArray[i] == wsSaveTextArray[j]) {
        iSelArray.Add(j);
        break;
      }
    }
  }
}
void CXFA_WidgetData::GetSelectedItemsValue(
    CFX_WideStringArray& wsSelTextArray) {
  CFX_WideString wsValue = GetRawValue();
  if (GetChoiceListOpen() == XFA_ATTRIBUTEENUM_MultiSelect) {
    if (!wsValue.IsEmpty()) {
      int32_t iStart = 0;
      int32_t iLength = wsValue.GetLength();
      int32_t iEnd = wsValue.Find(L'\n', iStart);
      iEnd = (iEnd == -1) ? iLength : iEnd;
      while (iEnd >= iStart) {
        wsSelTextArray.Add(wsValue.Mid(iStart, iEnd - iStart));
        iStart = iEnd + 1;
        if (iStart >= iLength) {
          break;
        }
        iEnd = wsValue.Find(L'\n', iStart);
        if (iEnd < 0) {
          wsSelTextArray.Add(wsValue.Mid(iStart, iLength - iStart));
        }
      }
    }
  } else {
    wsSelTextArray.Add(wsValue);
  }
}
FX_BOOL CXFA_WidgetData::GetItemState(int32_t nIndex) {
  if (nIndex < 0) {
    return FALSE;
  }
  CFX_WideStringArray wsSaveTextArray;
  GetChoiceListItems(wsSaveTextArray, TRUE);
  if (wsSaveTextArray.GetSize() <= nIndex) {
    return FALSE;
  }
  CFX_WideStringArray wsValueArray;
  GetSelectedItemsValue(wsValueArray);
  int32_t iValues = wsValueArray.GetSize();
  for (int32_t j = 0; j < iValues; j++) {
    if (wsValueArray[j] == wsSaveTextArray[nIndex]) {
      return TRUE;
    }
  }
  return FALSE;
}
void CXFA_WidgetData::SetItemState(int32_t nIndex,
                                   FX_BOOL bSelected,
                                   FX_BOOL bNotify,
                                   FX_BOOL bScriptModify,
                                   FX_BOOL bSyncData) {
  if (nIndex < 0) {
    return;
  }
  CFX_WideStringArray wsSaveTextArray;
  GetChoiceListItems(wsSaveTextArray, TRUE);
  if (wsSaveTextArray.GetSize() <= nIndex) {
    return;
  }
  int32_t iSel = -1;
  CFX_WideStringArray wsValueArray;
  GetSelectedItemsValue(wsValueArray);
  int32_t iValues = wsValueArray.GetSize();
  for (int32_t j = 0; j < iValues; j++) {
    if (wsValueArray[j] == wsSaveTextArray[nIndex]) {
      iSel = j;
      break;
    }
  }
  if (GetChoiceListOpen() == XFA_ATTRIBUTEENUM_MultiSelect) {
    if (bSelected) {
      if (iSel < 0) {
        CFX_WideString wsValue = GetRawValue();
        if (!wsValue.IsEmpty()) {
          wsValue += L"\n";
        }
        wsValue += wsSaveTextArray[nIndex];
        m_pNode->SetContent(wsValue, wsValue, bNotify, bScriptModify,
                            bSyncData);
      }
    } else if (iSel >= 0) {
      CFX_Int32Array iSelArray;
      GetSelectedItems(iSelArray);
      for (int32_t i = 0; i < iSelArray.GetSize(); i++) {
        if (iSelArray[i] == nIndex) {
          iSelArray.RemoveAt(i);
          break;
        }
      }
      SetSelectdItems(iSelArray, bNotify, bScriptModify, bSyncData);
    }
  } else {
    if (bSelected) {
      if (iSel < 0) {
        CFX_WideString wsSaveText = wsSaveTextArray[nIndex];
        CFX_WideString wsFormatText(wsSaveText);
        GetFormatDataValue(wsSaveText, wsFormatText);
        m_pNode->SetContent(wsSaveText, wsFormatText, bNotify, bScriptModify,
                            bSyncData);
      }
    } else if (iSel >= 0) {
      m_pNode->SetContent(CFX_WideString(), CFX_WideString(), bNotify,
                          bScriptModify, bSyncData);
    }
  }
}
void CXFA_WidgetData::SetSelectdItems(CFX_Int32Array& iSelArray,
                                      FX_BOOL bNotify,
                                      FX_BOOL bScriptModify,
                                      FX_BOOL bSyncData) {
  CFX_WideString wsValue;
  int32_t iSize = iSelArray.GetSize();
  if (iSize >= 1) {
    CFX_WideStringArray wsSaveTextArray;
    GetChoiceListItems(wsSaveTextArray, TRUE);
    CFX_WideString wsItemValue;
    for (int32_t i = 0; i < iSize; i++) {
      wsItemValue = (iSize == 1)
                        ? wsSaveTextArray[iSelArray[i]]
                        : wsSaveTextArray[iSelArray[i]] + FX_WSTRC(L"\n");
      wsValue += wsItemValue;
    }
  }
  CFX_WideString wsFormat(wsValue);
  if (GetChoiceListOpen() != XFA_ATTRIBUTEENUM_MultiSelect) {
    GetFormatDataValue(wsValue, wsFormat);
  }
  m_pNode->SetContent(wsValue, wsFormat, bNotify, bScriptModify, bSyncData);
}
void CXFA_WidgetData::ClearAllSelections() {
  CXFA_Node* pBind = m_pNode->GetBindData();
  if (pBind && GetChoiceListOpen() == XFA_ATTRIBUTEENUM_MultiSelect) {
    while (CXFA_Node* pChildNode =
               pBind->GetNodeItem(XFA_NODEITEM_FirstChild)) {
      pBind->RemoveChild(pChildNode);
    }
  } else {
    SyncValue(CFX_WideString(), FALSE);
  }
}
void CXFA_WidgetData::InsertItem(const CFX_WideString& wsLabel,
                                 const CFX_WideString& wsValue,
                                 int32_t nIndex,
                                 FX_BOOL bNotify) {
  CFX_WideString wsNewValue(wsValue);
  if (wsNewValue.IsEmpty()) {
    wsNewValue = wsLabel;
  }
  CXFA_NodeArray listitems;
  int32_t iCount = 0;
  CXFA_Node* pItemNode = m_pNode->GetNodeItem(XFA_NODEITEM_FirstChild);
  for (; pItemNode;
       pItemNode = pItemNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
    if (pItemNode->GetClassID() != XFA_ELEMENT_Items) {
      continue;
    }
    listitems.Add(pItemNode);
    iCount++;
  }
  if (iCount < 1) {
    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->SetBoolean(XFA_ATTRIBUTE_Save, TRUE);
    InsertListTextItem(pSaveItems, wsNewValue, nIndex);
  } else if (iCount > 1) {
    for (int32_t i = 0; i < 2; i++) {
      CXFA_Node* pNode = listitems[i];
      FX_BOOL bHasSave = pNode->GetBoolean(XFA_ATTRIBUTE_Save);
      if (bHasSave) {
        InsertListTextItem(pNode, wsNewValue, nIndex);
      } else {
        InsertListTextItem(pNode, wsLabel, nIndex);
      }
    }
  } else {
    CXFA_Node* pNode = listitems[0];
    pNode->SetBoolean(XFA_ATTRIBUTE_Save, FALSE);
    pNode->SetEnum(XFA_ATTRIBUTE_Presence, XFA_ATTRIBUTEENUM_Visible);
    CXFA_Node* pSaveItems = m_pNode->CreateSamePacketNode(XFA_ELEMENT_Items);
    m_pNode->InsertChild(-1, pSaveItems);
    pSaveItems->SetBoolean(XFA_ATTRIBUTE_Save, TRUE);
    pSaveItems->SetEnum(XFA_ATTRIBUTE_Presence, XFA_ATTRIBUTEENUM_Hidden);
    listitems.RemoveAll();
    CXFA_Node* pListNode = pNode->GetNodeItem(XFA_NODEITEM_FirstChild);
    int32_t i = 0;
    while (pListNode) {
      CFX_WideString wsOldValue;
      pListNode->TryContent(wsOldValue);
      InsertListTextItem(pSaveItems, wsOldValue, i);
      i++;
      pListNode = pListNode->GetNodeItem(XFA_NODEITEM_NextSibling);
    }
    InsertListTextItem(pNode, wsLabel, nIndex);
    InsertListTextItem(pSaveItems, wsNewValue, nIndex);
  }
  if (!bNotify) {
    return;
  }
  m_pNode->GetDocument()->GetNotify()->OnWidgetDataEvent(
      this, XFA_WIDGETEVENT_ListItemAdded, (void*)(const FX_WCHAR*)wsLabel,
      (void*)(const FX_WCHAR*)wsValue, (void*)(uintptr_t)nIndex);
}
void CXFA_WidgetData::GetItemLabel(const CFX_WideStringC& wsValue,
                                   CFX_WideString& wsLabel) {
  int32_t iCount = 0;
  CXFA_NodeArray listitems;
  CXFA_Node* pItems = m_pNode->GetNodeItem(XFA_NODEITEM_FirstChild);
  for (; pItems; pItems = pItems->GetNodeItem(XFA_NODEITEM_NextSibling)) {
    if (pItems->GetClassID() != XFA_ELEMENT_Items) {
      continue;
    }
    iCount++;
    listitems.Add(pItems);
  }
  if (iCount <= 1) {
    wsLabel = wsValue;
  } else {
    CXFA_Node* pLabelItems = listitems[0];
    FX_BOOL bSave = pLabelItems->GetBoolean(XFA_ATTRIBUTE_Save);
    CXFA_Node* pSaveItems = NULL;
    if (bSave) {
      pSaveItems = pLabelItems;
      pLabelItems = listitems[1];
    } else {
      pSaveItems = listitems[1];
    }
    iCount = 0;
    int32_t iSearch = -1;
    CFX_WideString wsContent;
    CXFA_Node* pChildItem = pSaveItems->GetNodeItem(XFA_NODEITEM_FirstChild);
    for (; pChildItem;
         pChildItem = pChildItem->GetNodeItem(XFA_NODEITEM_NextSibling)) {
      pChildItem->TryContent(wsContent);
      if (wsContent == wsValue) {
        iSearch = iCount;
        break;
      }
      iCount++;
    }
    if (iSearch < 0) {
      return;
    }
    if (CXFA_Node* pText =
            pLabelItems->GetChild(iSearch, XFA_ELEMENT_UNKNOWN)) {
      pText->TryContent(wsLabel);
    }
  }
}
void CXFA_WidgetData::GetItemValue(const CFX_WideStringC& wsLabel,
                                   CFX_WideString& wsValue) {
  int32_t iCount = 0;
  CXFA_NodeArray listitems;
  CXFA_Node* pItems = m_pNode->GetNodeItem(XFA_NODEITEM_FirstChild);
  for (; pItems; pItems = pItems->GetNodeItem(XFA_NODEITEM_NextSibling)) {
    if (pItems->GetClassID() != XFA_ELEMENT_Items) {
      continue;
    }
    iCount++;
    listitems.Add(pItems);
  }
  if (iCount <= 1) {
    wsValue = wsLabel;
  } else {
    CXFA_Node* pLabelItems = listitems[0];
    FX_BOOL bSave = pLabelItems->GetBoolean(XFA_ATTRIBUTE_Save);
    CXFA_Node* pSaveItems = NULL;
    if (bSave) {
      pSaveItems = pLabelItems;
      pLabelItems = listitems[1];
    } else {
      pSaveItems = listitems[1];
    }
    iCount = 0;
    int32_t iSearch = -1;
    CFX_WideString wsContent;
    CXFA_Node* pChildItem = pLabelItems->GetNodeItem(XFA_NODEITEM_FirstChild);
    for (; pChildItem;
         pChildItem = pChildItem->GetNodeItem(XFA_NODEITEM_NextSibling)) {
      pChildItem->TryContent(wsContent);
      if (wsContent == wsLabel) {
        iSearch = iCount;
        break;
      }
      iCount++;
    }
    if (iSearch < 0) {
      return;
    }
    if (CXFA_Node* pText = pSaveItems->GetChild(iSearch, XFA_ELEMENT_UNKNOWN)) {
      pText->TryContent(wsValue);
    }
  }
}
FX_BOOL CXFA_WidgetData::DeleteItem(int32_t nIndex,
                                    FX_BOOL bNotify,
                                    FX_BOOL bScriptModify,
                                    FX_BOOL bSyncData) {
  FX_BOOL bSetValue = FALSE;
  CXFA_Node* pItems = m_pNode->GetNodeItem(XFA_NODEITEM_FirstChild);
  for (; pItems; pItems = pItems->GetNodeItem(XFA_NODEITEM_NextSibling)) {
    if (pItems->GetClassID() != XFA_ELEMENT_Items) {
      continue;
    }
    if (nIndex < 0) {
      while (CXFA_Node* pNode = pItems->GetNodeItem(XFA_NODEITEM_FirstChild)) {
        pItems->RemoveChild(pNode);
      }
    } else {
      if (!bSetValue && pItems->GetBoolean(XFA_ATTRIBUTE_Save)) {
        SetItemState(nIndex, FALSE, TRUE, bScriptModify, bSyncData);
        bSetValue = TRUE;
      }
      int32_t i = 0;
      CXFA_Node* pNode = pItems->GetNodeItem(XFA_NODEITEM_FirstChild);
      while (pNode) {
        if (i == nIndex) {
          pItems->RemoveChild(pNode);
          break;
        }
        i++;
        pNode = pNode->GetNodeItem(XFA_NODEITEM_NextSibling);
      }
    }
  }
  if (!bNotify) {
    return TRUE;
  }
  m_pNode->GetDocument()->GetNotify()->OnWidgetDataEvent(
      this, XFA_WIDGETEVENT_ListItemRemoved, (void*)(uintptr_t)nIndex);
  return TRUE;
}
int32_t CXFA_WidgetData::GetHorizontalScrollPolicy() {
  CXFA_Node* pUIChild = GetUIChild();
  if (pUIChild) {
    return pUIChild->GetEnum(XFA_ATTRIBUTE_HScrollPolicy);
  }
  return XFA_ATTRIBUTEENUM_Auto;
}
int32_t CXFA_WidgetData::GetNumberOfCells() {
  CXFA_Node* pUIChild = GetUIChild();
  if (!pUIChild) {
    return -1;
  }
  if (CXFA_Node* pNode = pUIChild->GetChild(0, XFA_ELEMENT_Comb)) {
    return pNode->GetInteger(XFA_ATTRIBUTE_NumberOfCells);
  }
  return -1;
}
CFX_WideString CXFA_WidgetData::GetBarcodeType() {
  CXFA_Node* pUIChild = GetUIChild();
  return pUIChild ? pUIChild->GetCData(XFA_ATTRIBUTE_Type) : NULL;
}
FX_BOOL CXFA_WidgetData::GetBarcodeAttribute_CharEncoding(int32_t& val) {
  CXFA_Node* pUIChild = GetUIChild();
  CFX_WideString wsCharEncoding;
  if (pUIChild->TryCData(XFA_ATTRIBUTE_CharEncoding, wsCharEncoding)) {
    if (wsCharEncoding.CompareNoCase(L"UTF-16")) {
      val = CHAR_ENCODING_UNICODE;
      return TRUE;
    } else if (wsCharEncoding.CompareNoCase(L"UTF-8")) {
      val = CHAR_ENCODING_UTF8;
      return TRUE;
    }
  }
  return FALSE;
}
FX_BOOL CXFA_WidgetData::GetBarcodeAttribute_Checksum(int32_t& val) {
  CXFA_Node* pUIChild = GetUIChild();
  XFA_ATTRIBUTEENUM eChecksum;
  if (pUIChild->TryEnum(XFA_ATTRIBUTE_Checksum, eChecksum)) {
    switch (eChecksum) {
      case XFA_ATTRIBUTEENUM_None:
        val = 0;
        return TRUE;
      case XFA_ATTRIBUTEENUM_Auto:
        val = 1;
        return TRUE;
      case XFA_ATTRIBUTEENUM_1mod10:
        break;
      case XFA_ATTRIBUTEENUM_1mod10_1mod11:
        break;
      case XFA_ATTRIBUTEENUM_2mod10:
        break;
      default:
        break;
    }
  }
  return FALSE;
}
FX_BOOL CXFA_WidgetData::GetBarcodeAttribute_DataLength(int32_t& val) {
  CXFA_Node* pUIChild = GetUIChild();
  CFX_WideString wsDataLength;
  if (pUIChild->TryCData(XFA_ATTRIBUTE_DataLength, wsDataLength)) {
    val = FXSYS_wtoi(wsDataLength);
    return TRUE;
  }
  return FALSE;
}
FX_BOOL CXFA_WidgetData::GetBarcodeAttribute_StartChar(FX_CHAR& val) {
  CXFA_Node* pUIChild = GetUIChild();
  CFX_WideStringC wsStartEndChar;
  if (pUIChild->TryCData(XFA_ATTRIBUTE_StartChar, wsStartEndChar)) {
    if (wsStartEndChar.GetLength()) {
      val = (FX_CHAR)wsStartEndChar.GetAt(0);
      return TRUE;
    }
  }
  return FALSE;
}
FX_BOOL CXFA_WidgetData::GetBarcodeAttribute_EndChar(FX_CHAR& val) {
  CXFA_Node* pUIChild = GetUIChild();
  CFX_WideStringC wsStartEndChar;
  if (pUIChild->TryCData(XFA_ATTRIBUTE_EndChar, wsStartEndChar)) {
    if (wsStartEndChar.GetLength()) {
      val = (FX_CHAR)wsStartEndChar.GetAt(0);
      return TRUE;
    }
  }
  return FALSE;
}
FX_BOOL CXFA_WidgetData::GetBarcodeAttribute_ECLevel(int32_t& val) {
  CXFA_Node* pUIChild = GetUIChild();
  CFX_WideString wsECLevel;
  if (pUIChild->TryCData(XFA_ATTRIBUTE_ErrorCorrectionLevel, wsECLevel)) {
    val = FXSYS_wtoi(wsECLevel);
    return TRUE;
  }
  return FALSE;
}
FX_BOOL CXFA_WidgetData::GetBarcodeAttribute_ModuleWidth(int32_t& val) {
  CXFA_Node* pUIChild = GetUIChild();
  CXFA_Measurement mModuleWidthHeight;
  if (pUIChild->TryMeasure(XFA_ATTRIBUTE_ModuleWidth, mModuleWidthHeight)) {
    val = (int32_t)mModuleWidthHeight.ToUnit(XFA_UNIT_Pt);
    return TRUE;
  }
  return FALSE;
}
FX_BOOL CXFA_WidgetData::GetBarcodeAttribute_ModuleHeight(int32_t& val) {
  CXFA_Node* pUIChild = GetUIChild();
  CXFA_Measurement mModuleWidthHeight;
  if (pUIChild->TryMeasure(XFA_ATTRIBUTE_ModuleHeight, mModuleWidthHeight)) {
    val = (int32_t)mModuleWidthHeight.ToUnit(XFA_UNIT_Pt);
    return TRUE;
  }
  return FALSE;
}
FX_BOOL CXFA_WidgetData::GetBarcodeAttribute_PrintChecksum(FX_BOOL& val) {
  CXFA_Node* pUIChild = GetUIChild();
  FX_BOOL bPrintCheckDigit;
  if (pUIChild->TryBoolean(XFA_ATTRIBUTE_PrintCheckDigit, bPrintCheckDigit)) {
    val = bPrintCheckDigit;
    return TRUE;
  }
  return FALSE;
}
FX_BOOL CXFA_WidgetData::GetBarcodeAttribute_TextLocation(int32_t& val) {
  CXFA_Node* pUIChild = GetUIChild();
  XFA_ATTRIBUTEENUM eTextLocation;
  if (pUIChild->TryEnum(XFA_ATTRIBUTE_TextLocation, eTextLocation)) {
    switch (eTextLocation) {
      case XFA_ATTRIBUTEENUM_None:
        val = BC_TEXT_LOC_NONE;
        return TRUE;
      case XFA_ATTRIBUTEENUM_Above:
        val = BC_TEXT_LOC_ABOVE;
        return TRUE;
      case XFA_ATTRIBUTEENUM_Below:
        val = BC_TEXT_LOC_BELOW;
        return TRUE;
      case XFA_ATTRIBUTEENUM_AboveEmbedded:
        val = BC_TEXT_LOC_ABOVEEMBED;
        return TRUE;
      case XFA_ATTRIBUTEENUM_BelowEmbedded:
        val = BC_TEXT_LOC_BELOWEMBED;
        return TRUE;
      default:
        break;
    }
  }
  return FALSE;
}
FX_BOOL CXFA_WidgetData::GetBarcodeAttribute_Truncate(FX_BOOL& val) {
  CXFA_Node* pUIChild = GetUIChild();
  FX_BOOL bTruncate;
  if (pUIChild->TryBoolean(XFA_ATTRIBUTE_Truncate, bTruncate)) {
    val = bTruncate;
    return TRUE;
  }
  return FALSE;
}
FX_BOOL CXFA_WidgetData::GetBarcodeAttribute_WideNarrowRatio(FX_FLOAT& val) {
  CXFA_Node* pUIChild = GetUIChild();
  CFX_WideString wsWideNarrowRatio;
  if (pUIChild->TryCData(XFA_ATTRIBUTE_WideNarrowRatio, wsWideNarrowRatio)) {
    FX_STRSIZE ptPos = wsWideNarrowRatio.Find(':');
    FX_FLOAT fRatio = 0;
    if (ptPos >= 0) {
      fRatio = (FX_FLOAT)FXSYS_wtoi(wsWideNarrowRatio);
    } else {
      int32_t fA, fB;
      fA = FXSYS_wtoi(wsWideNarrowRatio.Left(ptPos));
      fB = FXSYS_wtoi(wsWideNarrowRatio.Mid(ptPos + 1));
      if (fB) {
        fRatio = (FX_FLOAT)fA / fB;
      }
    }
    val = fRatio;
    return TRUE;
  }
  return FALSE;
}
void CXFA_WidgetData::GetPasswordChar(CFX_WideString& wsPassWord) {
  CXFA_Node* pUIChild = GetUIChild();
  if (pUIChild) {
    pUIChild->TryCData(XFA_ATTRIBUTE_PasswordChar, wsPassWord);
  } else {
    wsPassWord = XFA_GetAttributeDefaultValue_Cdata(XFA_ELEMENT_PasswordEdit,
                                                    XFA_ATTRIBUTE_PasswordChar,
                                                    XFA_XDPPACKET_Form);
  }
}
FX_BOOL CXFA_WidgetData::IsMultiLine() {
  CXFA_Node* pUIChild = GetUIChild();
  if (pUIChild) {
    return pUIChild->GetBoolean(XFA_ATTRIBUTE_MultiLine);
  }
  return XFA_GetAttributeDefaultValue_Boolean(
      XFA_ELEMENT_TextEdit, XFA_ATTRIBUTE_MultiLine, XFA_XDPPACKET_Form);
}
int32_t CXFA_WidgetData::GetVerticalScrollPolicy() {
  CXFA_Node* pUIChild = GetUIChild();
  if (pUIChild) {
    return pUIChild->GetEnum(XFA_ATTRIBUTE_VScrollPolicy);
  }
  return XFA_GetAttributeDefaultValue_Enum(
      XFA_ELEMENT_TextEdit, XFA_ATTRIBUTE_VScrollPolicy, XFA_XDPPACKET_Form);
}
int32_t CXFA_WidgetData::GetMaxChars(XFA_ELEMENT& eType) {
  if (CXFA_Node* pNode = m_pNode->GetChild(0, XFA_ELEMENT_Value)) {
    if (CXFA_Node* pChild = pNode->GetNodeItem(XFA_NODEITEM_FirstChild)) {
      switch (pChild->GetClassID()) {
        case XFA_ELEMENT_Text:
          eType = XFA_ELEMENT_Text;
          return pChild->GetInteger(XFA_ATTRIBUTE_MaxChars);
        case XFA_ELEMENT_ExData: {
          eType = XFA_ELEMENT_ExData;
          int32_t iMax = pChild->GetInteger(XFA_ATTRIBUTE_MaxLength);
          return iMax < 0 ? 0 : iMax;
        }
        default:
          break;
      }
    }
  }
  return 0;
}
FX_BOOL CXFA_WidgetData::GetFracDigits(int32_t& iFracDigits) {
  if (CXFA_Node* pNode = m_pNode->GetChild(0, XFA_ELEMENT_Value)) {
    if (CXFA_Node* pChild = pNode->GetChild(0, XFA_ELEMENT_Decimal)) {
      return pChild->TryInteger(XFA_ATTRIBUTE_FracDigits, iFracDigits);
    }
  }
  iFracDigits = -1;
  return FALSE;
}
FX_BOOL CXFA_WidgetData::GetLeadDigits(int32_t& iLeadDigits) {
  if (CXFA_Node* pNode = m_pNode->GetChild(0, XFA_ELEMENT_Value)) {
    if (CXFA_Node* pChild = pNode->GetChild(0, XFA_ELEMENT_Decimal)) {
      return pChild->TryInteger(XFA_ATTRIBUTE_LeadDigits, iLeadDigits);
    }
  }
  iLeadDigits = -1;
  return FALSE;
}
CFX_WideString XFA_NumericLimit(const CFX_WideString& wsValue,
                                int32_t iLead,
                                int32_t iTread) {
  if ((iLead == -1) && (iTread == -1)) {
    return wsValue;
  }
  CFX_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++) {
    FX_WCHAR wc = wsValue[i];
    if (XFA_IsDigit(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);
            wsDeci.SetScale(iTread);
            wsRet = wsDeci;
          }
          return wsRet;
        }
      }
    } else if (wc == L'.') {
      iTread_ = 0;
      iLead = -1;
    }
    wsRet += wc;
  }
  return wsRet;
}
FX_BOOL CXFA_WidgetData::SetValue(const CFX_WideString& wsValue,
                                  XFA_VALUEPICTURE eValueType) {
  if (wsValue.IsEmpty()) {
    SyncValue(wsValue, TRUE);
    return TRUE;
  }
  m_bPreNull = m_bIsNull;
  m_bIsNull = FALSE;
  CFX_WideString wsNewText(wsValue);
  CFX_WideString wsPicture;
  GetPictureContent(wsPicture, eValueType);
  FX_BOOL bValidate = TRUE;
  FX_BOOL bSyncData = FALSE;
  CXFA_Node* pNode = GetUIChild();
  if (!pNode) {
    return TRUE;
  }
  XFA_ELEMENT uiType = pNode->GetClassID();
  if (!wsPicture.IsEmpty()) {
    CXFA_LocaleMgr* pLocalMgr = m_pNode->GetDocument()->GetLocalMgr();
    IFX_Locale* pLocale = GetLocal();
    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 (uiType == XFA_ELEMENT_NumericEdit) {
        int32_t iLeadDigits = 0;
        int32_t iFracDigits = 0;
        GetLeadDigits(iLeadDigits);
        GetFracDigits(iFracDigits);
        wsNewText = XFA_NumericLimit(wsNewText, iLeadDigits, iFracDigits);
      }
      bSyncData = TRUE;
    }
  } else {
    if (uiType == XFA_ELEMENT_NumericEdit) {
      if (wsNewText != FX_WSTRC(L"0")) {
        int32_t iLeadDigits = 0;
        int32_t iFracDigits = 0;
        GetLeadDigits(iLeadDigits);
        GetFracDigits(iFracDigits);
        wsNewText = XFA_NumericLimit(wsNewText, iLeadDigits, iFracDigits);
      }
      bSyncData = TRUE;
    }
  }
  if (uiType != XFA_ELEMENT_NumericEdit || bSyncData) {
    SyncValue(wsNewText, TRUE);
  }
  return bValidate;
}
FX_BOOL CXFA_WidgetData::GetPictureContent(CFX_WideString& wsPicture,
                                           XFA_VALUEPICTURE ePicture) {
  if (ePicture == XFA_VALUEPICTURE_Raw) {
    return FALSE;
  }
  CXFA_LocaleValue widgetValue = XFA_GetLocaleValue(this);
  switch (ePicture) {
    case XFA_VALUEPICTURE_Display: {
      if (CXFA_Node* pFormat = m_pNode->GetChild(0, XFA_ELEMENT_Format)) {
        if (CXFA_Node* pPicture = pFormat->GetChild(0, XFA_ELEMENT_Picture)) {
          if (pPicture->TryContent(wsPicture)) {
            return TRUE;
          }
        }
      }
      CFX_WideString wsDataPicture, wsTimePicture;
      IFX_Locale* pLocale = GetLocal();
      if (!pLocale) {
        return FALSE;
      }
      uint32_t dwType = widgetValue.GetType();
      switch (dwType) {
        case XFA_VT_DATE:
          pLocale->GetDatePattern(FX_LOCALEDATETIMESUBCATEGORY_Medium,
                                  wsPicture);
          break;
        case XFA_VT_TIME:
          pLocale->GetTimePattern(FX_LOCALEDATETIMESUBCATEGORY_Medium,
                                  wsPicture);
          break;
        case XFA_VT_DATETIME:
          pLocale->GetDatePattern(FX_LOCALEDATETIMESUBCATEGORY_Medium,
                                  wsDataPicture);
          pLocale->GetTimePattern(FX_LOCALEDATETIMESUBCATEGORY_Medium,
                                  wsTimePicture);
          wsPicture = wsDataPicture + FX_WSTRC(L"T") + wsTimePicture;
          break;
        case XFA_VT_DECIMAL:
        case XFA_VT_FLOAT:
          break;
        default:
          break;
      }
    }
      return TRUE;
    case XFA_VALUEPICTURE_Edit: {
      CXFA_Node* pUI = m_pNode->GetChild(0, XFA_ELEMENT_Ui);
      if (pUI) {
        if (CXFA_Node* pPicture = pUI->GetChild(0, XFA_ELEMENT_Picture)) {
          if (pPicture->TryContent(wsPicture)) {
            return TRUE;
          }
        }
      }
      {
        CFX_WideString wsDataPicture, wsTimePicture;
        IFX_Locale* pLocale = GetLocal();
        if (!pLocale) {
          return FALSE;
        }
        uint32_t dwType = widgetValue.GetType();
        switch (dwType) {
          case XFA_VT_DATE:
            pLocale->GetDatePattern(FX_LOCALEDATETIMESUBCATEGORY_Short,
                                    wsPicture);
            break;
          case XFA_VT_TIME:
            pLocale->GetTimePattern(FX_LOCALEDATETIMESUBCATEGORY_Short,
                                    wsPicture);
            break;
          case XFA_VT_DATETIME:
            pLocale->GetDatePattern(FX_LOCALEDATETIMESUBCATEGORY_Short,
                                    wsDataPicture);
            pLocale->GetTimePattern(FX_LOCALEDATETIMESUBCATEGORY_Short,
                                    wsTimePicture);
            wsPicture = wsDataPicture + L"T" + wsTimePicture;
            break;
          default:
            break;
        }
      }
    }
      return TRUE;
    case XFA_VALUEPICTURE_DataBind: {
      if (CXFA_Bind bind = GetBind()) {
        bind.GetPicture(wsPicture);
        return TRUE;
      }
    } break;
    default:
      break;
  }
  return FALSE;
}
IFX_Locale* CXFA_WidgetData::GetLocal() {
  IFX_Locale* pLocale = NULL;
  if (!m_pNode) {
    return pLocale;
  }
  FX_BOOL bLocale = FALSE;
  CFX_WideString wsLocaleName;
  bLocale = m_pNode->GetLocaleName(wsLocaleName);
  if (bLocale) {
    if (wsLocaleName == FX_WSTRC(L"ambient")) {
      pLocale = m_pNode->GetDocument()->GetLocalMgr()->GetDefLocale();
    } else {
      pLocale =
          m_pNode->GetDocument()->GetLocalMgr()->GetLocaleByName(wsLocaleName);
    }
  }
  return pLocale;
}
static FX_BOOL XFA_SplitDateTime(const CFX_WideString& wsDateTime,
                                 CFX_WideString& wsDate,
                                 CFX_WideString& wsTime) {
  wsDate = L"";
  wsTime = L"";
  if (wsDateTime.IsEmpty()) {
    return FALSE;
  }
  int nSplitIndex = -1;
  nSplitIndex = wsDateTime.Find('T');
  if (nSplitIndex < 0) {
    nSplitIndex = wsDateTime.Find(' ');
  }
  if (nSplitIndex < 0) {
    return FALSE;
  }
  wsDate = wsDateTime.Left(nSplitIndex);
  if (!wsDate.IsEmpty()) {
    int32_t iCount = wsDate.GetLength();
    int32_t i = 0;
    for (i = 0; i < iCount; i++) {
      if (wsDate[i] >= '0' && wsDate[i] <= '9') {
        break;
      }
    }
    if (i == iCount) {
      return FALSE;
    }
  }
  wsTime = wsDateTime.Right(wsDateTime.GetLength() - nSplitIndex - 1);
  if (!wsTime.IsEmpty()) {
    int32_t iCount = wsTime.GetLength();
    int32_t i = 0;
    for (i = 0; i < iCount; i++) {
      if (wsTime[i] >= '0' && wsTime[i] <= '9') {
        break;
      }
    }
    if (i == iCount) {
      return FALSE;
    }
  }
  return TRUE;
}

FX_BOOL CXFA_WidgetData::GetValue(CFX_WideString& wsValue,
                                  XFA_VALUEPICTURE eValueType) {
  wsValue = m_pNode->GetContent();

  if (eValueType == XFA_VALUEPICTURE_Display)
    GetItemLabel(wsValue, wsValue);

  CFX_WideString wsPicture;
  GetPictureContent(wsPicture, eValueType);
  CXFA_Node* pNode = GetUIChild();
  if (!pNode)
    return TRUE;

  XFA_ELEMENT uiType = GetUIChild()->GetClassID();
  switch (uiType) {
    case XFA_ELEMENT_ChoiceList: {
      if (eValueType == XFA_VALUEPICTURE_Display) {
        int32_t iSelItemIndex = GetSelectedItem(0);
        if (iSelItemIndex >= 0) {
          GetChoiceListItem(wsValue, iSelItemIndex);
          wsPicture.Empty();
        }
      }
    } break;
    case XFA_ELEMENT_NumericEdit:
      if (eValueType != XFA_VALUEPICTURE_Raw && wsPicture.IsEmpty()) {
        IFX_Locale* pLocale = GetLocal();
        if (eValueType == XFA_VALUEPICTURE_Display && pLocale) {
          CFX_WideString wsOutput;
          NormalizeNumStr(wsValue, wsOutput);
          FormatNumStr(wsOutput, pLocale, wsOutput);
          wsValue = wsOutput;
        }
      }
      break;
    default:
      break;
  }
  if (wsPicture.IsEmpty())
    return TRUE;

  if (IFX_Locale* pLocale = GetLocal()) {
    CXFA_LocaleValue widgetValue = XFA_GetLocaleValue(this);
    CXFA_LocaleMgr* pLocalMgr = m_pNode->GetDocument()->GetLocalMgr();
    switch (widgetValue.GetType()) {
      case XFA_VT_DATE: {
        CFX_WideString wsDate, wsTime;
        if (XFA_SplitDateTime(wsValue, wsDate, wsTime)) {
          CXFA_LocaleValue date(XFA_VT_DATE, wsDate, pLocalMgr);
          if (date.FormatPatterns(wsValue, wsPicture, pLocale, eValueType))
            return TRUE;
        }
        break;
      }
      case XFA_VT_TIME: {
        CFX_WideString wsDate, wsTime;
        if (XFA_SplitDateTime(wsValue, wsDate, wsTime)) {
          CXFA_LocaleValue time(XFA_VT_TIME, wsTime, pLocalMgr);
          if (time.FormatPatterns(wsValue, wsPicture, pLocale, eValueType))
            return TRUE;
        }
        break;
      }
      default:
        break;
    }
    widgetValue.FormatPatterns(wsValue, wsPicture, pLocale, eValueType);
  }
  return TRUE;
}

FX_BOOL CXFA_WidgetData::GetNormalizeDataValue(
    const CFX_WideStringC& wsValue,
    CFX_WideString& wsNormalizeValue) {
  wsNormalizeValue = wsValue;
  if (wsValue.IsEmpty()) {
    return TRUE;
  }
  CFX_WideString wsPicture;
  GetPictureContent(wsPicture, XFA_VALUEPICTURE_DataBind);
  if (wsPicture.IsEmpty()) {
    return TRUE;
  }
  FXSYS_assert(GetNode());
  CXFA_LocaleMgr* pLocalMgr = GetNode()->GetDocument()->GetLocalMgr();
  IFX_Locale* pLocale = GetLocal();
  CXFA_LocaleValue widgetValue = XFA_GetLocaleValue(this);
  if (widgetValue.ValidateValue(wsValue, wsPicture, pLocale, &wsPicture)) {
    widgetValue = CXFA_LocaleValue(widgetValue.GetType(), wsNormalizeValue,
                                   wsPicture, pLocale, pLocalMgr);
    wsNormalizeValue = widgetValue.GetValue();
    return TRUE;
  }
  return FALSE;
}
FX_BOOL CXFA_WidgetData::GetFormatDataValue(const CFX_WideStringC& wsValue,
                                            CFX_WideString& wsFormatedValue) {
  wsFormatedValue = wsValue;
  if (wsValue.IsEmpty()) {
    return TRUE;
  }
  CFX_WideString wsPicture;
  GetPictureContent(wsPicture, XFA_VALUEPICTURE_DataBind);
  if (wsPicture.IsEmpty()) {
    return TRUE;
  }
  if (IFX_Locale* pLocale = GetLocal()) {
    FXSYS_assert(GetNode());
    CXFA_Node* pNodeValue = GetNode()->GetChild(0, XFA_ELEMENT_Value);
    if (!pNodeValue) {
      return FALSE;
    }
    CXFA_Node* pValueChild = pNodeValue->GetNodeItem(XFA_NODEITEM_FirstChild);
    if (!pValueChild) {
      return FALSE;
    }
    int32_t iVTType = XFA_VT_NULL;
    XFA_ELEMENT eType = pValueChild->GetClassID();
    switch (eType) {
      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: {
        CFX_WideString wsDate, wsTime;
        if (XFA_SplitDateTime(wsValue, wsDate, wsTime)) {
          CXFA_LocaleValue date(XFA_VT_DATE, wsDate, pLocalMgr);
          if (date.FormatPatterns(wsFormatedValue, wsPicture, pLocale,
                                  XFA_VALUEPICTURE_DataBind)) {
            return TRUE;
          }
        }
        break;
      }
      case XFA_VT_TIME: {
        CFX_WideString wsDate, wsTime;
        if (XFA_SplitDateTime(wsValue, wsDate, wsTime)) {
          CXFA_LocaleValue time(XFA_VT_TIME, wsTime, pLocalMgr);
          if (time.FormatPatterns(wsFormatedValue, wsPicture, pLocale,
                                  XFA_VALUEPICTURE_DataBind)) {
            return TRUE;
          }
        }
        break;
      }
      default:
        break;
    }
    widgetValue.FormatPatterns(wsFormatedValue, wsPicture, pLocale,
                               XFA_VALUEPICTURE_DataBind);
  }
  return FALSE;
}
void CXFA_WidgetData::NormalizeNumStr(const CFX_WideString& wsValue,
                                      CFX_WideString& wsOutput) {
  if (wsValue.IsEmpty()) {
    return;
  }
  wsOutput = wsValue;
  wsOutput.TrimLeft('0');
  int32_t dot_index = wsOutput.Find('.');
  int32_t iFracDigits = 0;
  if (!wsOutput.IsEmpty() && dot_index >= 0 &&
      (!GetFracDigits(iFracDigits) || iFracDigits != -1)) {
    wsOutput.TrimRight(L"0");
    wsOutput.TrimRight(L".");
  }
  if (wsOutput.IsEmpty() || wsOutput[0] == '.') {
    wsOutput.Insert(0, '0');
  }
}
void CXFA_WidgetData::FormatNumStr(const CFX_WideString& wsValue,
                                   IFX_Locale* pLocale,
                                   CFX_WideString& wsOutput) {
  if (wsValue.IsEmpty()) {
    return;
  }
  CFX_WideString wsSrcNum = wsValue;
  CFX_WideString wsGroupSymbol;
  pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_Grouping, wsGroupSymbol);
  FX_BOOL bNeg = FALSE;
  if (wsSrcNum[0] == '-') {
    bNeg = TRUE;
    wsSrcNum.Delete(0, 1);
  }
  int32_t len = wsSrcNum.GetLength();
  int32_t dot_index = wsSrcNum.Find('.');
  if (dot_index == -1) {
    dot_index = len;
  }
  int32_t cc = dot_index - 1;
  if (cc >= 0) {
    int nPos = dot_index % 3;
    wsOutput.Empty();
    for (int32_t i = 0; i < dot_index; i++) {
      if (i % 3 == nPos && i != 0) {
        wsOutput += wsGroupSymbol;
      }
      wsOutput += wsSrcNum[i];
    }
    if (dot_index < len) {
      CFX_WideString wsSymbol;
      pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_Decimal, wsSymbol);
      wsOutput += wsSymbol;
      wsOutput += wsSrcNum.Right(len - dot_index - 1);
    }
    if (bNeg) {
      CFX_WideString wsMinusymbol;
      pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_Minus, wsMinusymbol);
      wsOutput = wsMinusymbol + wsOutput;
    }
  }
}
void CXFA_WidgetData::SyncValue(const CFX_WideString& wsValue,
                                FX_BOOL bNotify) {
  if (!m_pNode) {
    return;
  }
  CFX_WideString wsFormatValue(wsValue);
  CXFA_WidgetData* pContainerWidgetData = m_pNode->GetContainerWidgetData();
  if (pContainerWidgetData) {
    pContainerWidgetData->GetFormatDataValue(wsValue, wsFormatValue);
  }
  m_pNode->SetContent(wsValue, wsFormatValue, bNotify);
}
void CXFA_WidgetData::InsertListTextItem(CXFA_Node* pItems,
                                         const CFX_WideStringC& wsText,
                                         int32_t nIndex) {
  CXFA_Node* pText = pItems->CreateSamePacketNode(XFA_ELEMENT_Text);
  pItems->InsertChild(nIndex, pText);
  pText->SetContent(wsText, wsText, FALSE, FALSE, FALSE);
}
CXFA_Occur::CXFA_Occur(CXFA_Node* pNode) : CXFA_Data(pNode) {}
int32_t CXFA_Occur::GetMax() {
  int32_t iMax = 1;
  if (m_pNode) {
    if (!m_pNode->TryInteger(XFA_ATTRIBUTE_Max, iMax, TRUE)) {
      iMax = GetMin();
    }
  }
  return iMax;
}
int32_t CXFA_Occur::GetMin() {
  int32_t iMin = 1;
  if (m_pNode) {
    if (!m_pNode->TryInteger(XFA_ATTRIBUTE_Min, iMin, TRUE) || iMin < 0) {
      iMin = 1;
    }
  }
  return iMin;
}
FX_BOOL CXFA_Occur::GetOccurInfo(int32_t& iMin, int32_t& iMax, int32_t& iInit) {
  if (!m_pNode) {
    return FALSE;
  }
  if (!m_pNode->TryInteger(XFA_ATTRIBUTE_Min, iMin, FALSE) || iMin < 0) {
    iMin = 1;
  }
  if (!m_pNode->TryInteger(XFA_ATTRIBUTE_Max, iMax, FALSE)) {
    if (iMin == 0) {
      iMax = 1;
    } else {
      iMax = iMin;
    }
  }
  if (!m_pNode->TryInteger(XFA_ATTRIBUTE_Initial, iInit, FALSE) ||
      iInit < iMin) {
    iInit = iMin;
  }
  return TRUE;
}
void CXFA_Occur::SetMax(int32_t iMax) {
  iMax = (iMax != -1 && iMax < 1) ? 1 : iMax;
  m_pNode->SetInteger(XFA_ATTRIBUTE_Max, iMax, FALSE);
  int32_t iMin = GetMin();
  if (iMax != -1 && iMax < iMin) {
    iMin = iMax;
    m_pNode->SetInteger(XFA_ATTRIBUTE_Min, iMin, FALSE);
  }
}
void CXFA_Occur::SetMin(int32_t iMin) {
  iMin = (iMin < 0) ? 1 : iMin;
  m_pNode->SetInteger(XFA_ATTRIBUTE_Min, iMin, FALSE);
  int32_t iMax = GetMax();
  if (iMax > 0 && iMax < iMin) {
    iMax = iMin;
    m_pNode->SetInteger(XFA_ATTRIBUTE_Max, iMax, FALSE);
  }
}
XFA_ATTRIBUTEENUM XFA_GetEnumTypeAttribute(
    CXFA_Node* pNode,
    XFA_ATTRIBUTE attributeValue = XFA_ATTRIBUTE_Type,
    XFA_ATTRIBUTEENUM eDefaultValue = XFA_ATTRIBUTEENUM_Optional) {
  XFA_ATTRIBUTEENUM eType = eDefaultValue;
  if (pNode) {
    if (!pNode->TryEnum(attributeValue, eType, TRUE)) {
      eType = eDefaultValue;
    }
  }
  return eType;
}
