1 // Copyright 2016 PDFium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6
7 #include "xfa/fxfa/parser/cxfa_widgetdata.h"
8
9 #include "core/fxcrt/fx_ext.h"
10 #include "third_party/base/stl_util.h"
11 #include "xfa/fxbarcode/BC_Library.h"
12 #include "xfa/fxfa/app/xfa_ffnotify.h"
13 #include "xfa/fxfa/parser/cxfa_document.h"
14 #include "xfa/fxfa/parser/cxfa_event.h"
15 #include "xfa/fxfa/parser/cxfa_measurement.h"
16 #include "xfa/fxfa/parser/xfa_localevalue.h"
17 #include "xfa/fxfa/parser/xfa_object.h"
18
19 namespace {
20
GetEdgeThickness(const std::vector<CXFA_Stroke> & strokes,bool b3DStyle,int32_t nIndex)21 FX_FLOAT GetEdgeThickness(const std::vector<CXFA_Stroke>& strokes,
22 bool b3DStyle,
23 int32_t nIndex) {
24 FX_FLOAT fThickness = 0;
25
26 if (strokes[nIndex * 2 + 1].GetPresence() == XFA_ATTRIBUTEENUM_Visible) {
27 if (nIndex == 0)
28 fThickness += 2.5f;
29
30 fThickness += strokes[nIndex * 2 + 1].GetThickness() * (b3DStyle ? 4 : 2);
31 }
32 return fThickness;
33 }
34
SplitDateTime(const CFX_WideString & wsDateTime,CFX_WideString & wsDate,CFX_WideString & wsTime)35 bool SplitDateTime(const CFX_WideString& wsDateTime,
36 CFX_WideString& wsDate,
37 CFX_WideString& wsTime) {
38 wsDate = L"";
39 wsTime = L"";
40 if (wsDateTime.IsEmpty())
41 return false;
42
43 int nSplitIndex = -1;
44 nSplitIndex = wsDateTime.Find('T');
45 if (nSplitIndex < 0)
46 nSplitIndex = wsDateTime.Find(' ');
47 if (nSplitIndex < 0)
48 return false;
49
50 wsDate = wsDateTime.Left(nSplitIndex);
51 if (!wsDate.IsEmpty()) {
52 int32_t iCount = wsDate.GetLength();
53 int32_t i = 0;
54 for (i = 0; i < iCount; i++) {
55 if (wsDate[i] >= '0' && wsDate[i] <= '9')
56 break;
57 }
58 if (i == iCount)
59 return false;
60 }
61 wsTime = wsDateTime.Right(wsDateTime.GetLength() - nSplitIndex - 1);
62 if (!wsTime.IsEmpty()) {
63 int32_t iCount = wsTime.GetLength();
64 int32_t i = 0;
65 for (i = 0; i < iCount; i++) {
66 if (wsTime[i] >= '0' && wsTime[i] <= '9')
67 break;
68 }
69 if (i == iCount)
70 return false;
71 }
72 return true;
73 }
74
CreateUIChild(CXFA_Node * pNode,XFA_Element & eWidgetType)75 CXFA_Node* CreateUIChild(CXFA_Node* pNode, XFA_Element& eWidgetType) {
76 XFA_Element eType = pNode->GetElementType();
77 eWidgetType = eType;
78 if (eType != XFA_Element::Field && eType != XFA_Element::Draw)
79 return nullptr;
80
81 eWidgetType = XFA_Element::Unknown;
82 XFA_Element eUIType = XFA_Element::Unknown;
83 CXFA_Value defValue(pNode->GetProperty(0, XFA_Element::Value, true));
84 XFA_Element eValueType = defValue.GetChildValueClassID();
85 switch (eValueType) {
86 case XFA_Element::Boolean:
87 eUIType = XFA_Element::CheckButton;
88 break;
89 case XFA_Element::Integer:
90 case XFA_Element::Decimal:
91 case XFA_Element::Float:
92 eUIType = XFA_Element::NumericEdit;
93 break;
94 case XFA_Element::ExData:
95 case XFA_Element::Text:
96 eUIType = XFA_Element::TextEdit;
97 eWidgetType = XFA_Element::Text;
98 break;
99 case XFA_Element::Date:
100 case XFA_Element::Time:
101 case XFA_Element::DateTime:
102 eUIType = XFA_Element::DateTimeEdit;
103 break;
104 case XFA_Element::Image:
105 eUIType = XFA_Element::ImageEdit;
106 eWidgetType = XFA_Element::Image;
107 break;
108 case XFA_Element::Arc:
109 case XFA_Element::Line:
110 case XFA_Element::Rectangle:
111 eUIType = XFA_Element::DefaultUi;
112 eWidgetType = eValueType;
113 break;
114 default:
115 break;
116 }
117
118 CXFA_Node* pUIChild = nullptr;
119 CXFA_Node* pUI = pNode->GetProperty(0, XFA_Element::Ui, true);
120 CXFA_Node* pChild = pUI->GetNodeItem(XFA_NODEITEM_FirstChild);
121 for (; pChild; pChild = pChild->GetNodeItem(XFA_NODEITEM_NextSibling)) {
122 XFA_Element eChildType = pChild->GetElementType();
123 if (eChildType == XFA_Element::Extras ||
124 eChildType == XFA_Element::Picture) {
125 continue;
126 }
127 const XFA_PROPERTY* pProperty = XFA_GetPropertyOfElement(
128 XFA_Element::Ui, eChildType, XFA_XDPPACKET_Form);
129 if (pProperty && (pProperty->uFlags & XFA_PROPERTYFLAG_OneOf)) {
130 pUIChild = pChild;
131 break;
132 }
133 }
134
135 if (eType == XFA_Element::Draw) {
136 XFA_Element eDraw =
137 pUIChild ? pUIChild->GetElementType() : XFA_Element::Unknown;
138 switch (eDraw) {
139 case XFA_Element::TextEdit:
140 eWidgetType = XFA_Element::Text;
141 break;
142 case XFA_Element::ImageEdit:
143 eWidgetType = XFA_Element::Image;
144 break;
145 default:
146 eWidgetType = eWidgetType == XFA_Element::Unknown ? XFA_Element::Text
147 : eWidgetType;
148 break;
149 }
150 } else {
151 if (pUIChild && pUIChild->GetElementType() == XFA_Element::DefaultUi) {
152 eWidgetType = XFA_Element::TextEdit;
153 } else {
154 eWidgetType =
155 pUIChild ? pUIChild->GetElementType()
156 : (eUIType == XFA_Element::Unknown ? XFA_Element::TextEdit
157 : eUIType);
158 }
159 }
160
161 if (!pUIChild) {
162 if (eUIType == XFA_Element::Unknown) {
163 eUIType = XFA_Element::TextEdit;
164 defValue.GetNode()->GetProperty(0, XFA_Element::Text, true);
165 }
166 return pUI->GetProperty(0, eUIType, true);
167 }
168
169 if (eUIType != XFA_Element::Unknown)
170 return pUIChild;
171
172 switch (pUIChild->GetElementType()) {
173 case XFA_Element::CheckButton: {
174 eValueType = XFA_Element::Text;
175 if (CXFA_Node* pItems = pNode->GetChild(0, XFA_Element::Items)) {
176 if (CXFA_Node* pItem = pItems->GetChild(0, XFA_Element::Unknown))
177 eValueType = pItem->GetElementType();
178 }
179 break;
180 }
181 case XFA_Element::DateTimeEdit:
182 eValueType = XFA_Element::DateTime;
183 break;
184 case XFA_Element::ImageEdit:
185 eValueType = XFA_Element::Image;
186 break;
187 case XFA_Element::NumericEdit:
188 eValueType = XFA_Element::Float;
189 break;
190 case XFA_Element::ChoiceList: {
191 eValueType = (pUIChild->GetEnum(XFA_ATTRIBUTE_Open) ==
192 XFA_ATTRIBUTEENUM_MultiSelect)
193 ? XFA_Element::ExData
194 : XFA_Element::Text;
195 break;
196 }
197 case XFA_Element::Barcode:
198 case XFA_Element::Button:
199 case XFA_Element::PasswordEdit:
200 case XFA_Element::Signature:
201 case XFA_Element::TextEdit:
202 default:
203 eValueType = XFA_Element::Text;
204 break;
205 }
206 defValue.GetNode()->GetProperty(0, eValueType, true);
207
208 return pUIChild;
209 }
210
GetAttributeDefaultValue_Enum(XFA_Element eElement,XFA_ATTRIBUTE eAttribute,uint32_t dwPacket)211 XFA_ATTRIBUTEENUM GetAttributeDefaultValue_Enum(XFA_Element eElement,
212 XFA_ATTRIBUTE eAttribute,
213 uint32_t dwPacket) {
214 void* pValue;
215 if (XFA_GetAttributeDefaultValue(pValue, eElement, eAttribute,
216 XFA_ATTRIBUTETYPE_Enum, dwPacket)) {
217 return (XFA_ATTRIBUTEENUM)(uintptr_t)pValue;
218 }
219 return XFA_ATTRIBUTEENUM_Unknown;
220 }
221
GetAttributeDefaultValue_Cdata(XFA_Element eElement,XFA_ATTRIBUTE eAttribute,uint32_t dwPacket)222 CFX_WideStringC GetAttributeDefaultValue_Cdata(XFA_Element eElement,
223 XFA_ATTRIBUTE eAttribute,
224 uint32_t dwPacket) {
225 void* pValue;
226 if (XFA_GetAttributeDefaultValue(pValue, eElement, eAttribute,
227 XFA_ATTRIBUTETYPE_Cdata, dwPacket)) {
228 return (const FX_WCHAR*)pValue;
229 }
230 return nullptr;
231 }
232
GetAttributeDefaultValue_Boolean(XFA_Element eElement,XFA_ATTRIBUTE eAttribute,uint32_t dwPacket)233 bool GetAttributeDefaultValue_Boolean(XFA_Element eElement,
234 XFA_ATTRIBUTE eAttribute,
235 uint32_t dwPacket) {
236 void* pValue;
237 if (XFA_GetAttributeDefaultValue(pValue, eElement, eAttribute,
238 XFA_ATTRIBUTETYPE_Boolean, dwPacket)) {
239 return !!pValue;
240 }
241 return false;
242 }
243
244 } // namespace
245
CXFA_WidgetData(CXFA_Node * pNode)246 CXFA_WidgetData::CXFA_WidgetData(CXFA_Node* pNode)
247 : CXFA_Data(pNode),
248 m_bIsNull(true),
249 m_bPreNull(true),
250 m_pUiChildNode(nullptr),
251 m_eUIType(XFA_Element::Unknown) {}
252
GetUIChild()253 CXFA_Node* CXFA_WidgetData::GetUIChild() {
254 if (m_eUIType == XFA_Element::Unknown)
255 m_pUiChildNode = CreateUIChild(m_pNode, m_eUIType);
256
257 return m_pUiChildNode;
258 }
259
GetUIType()260 XFA_Element CXFA_WidgetData::GetUIType() {
261 GetUIChild();
262 return m_eUIType;
263 }
264
GetRawValue()265 CFX_WideString CXFA_WidgetData::GetRawValue() {
266 return m_pNode->GetContent();
267 }
268
GetAccess(bool bTemplate)269 int32_t CXFA_WidgetData::GetAccess(bool bTemplate) {
270 if (bTemplate) {
271 CXFA_Node* pNode = m_pNode->GetTemplateNode();
272 if (pNode)
273 return pNode->GetEnum(XFA_ATTRIBUTE_Access);
274 return XFA_ATTRIBUTEENUM_Open;
275 }
276 CXFA_Node* pNode = m_pNode;
277 while (pNode) {
278 int32_t iAcc = pNode->GetEnum(XFA_ATTRIBUTE_Access);
279 if (iAcc != XFA_ATTRIBUTEENUM_Open)
280 return iAcc;
281
282 pNode =
283 pNode->GetNodeItem(XFA_NODEITEM_Parent, XFA_ObjectType::ContainerNode);
284 }
285 return XFA_ATTRIBUTEENUM_Open;
286 }
287
GetRotate()288 int32_t CXFA_WidgetData::GetRotate() {
289 CXFA_Measurement ms;
290 if (!m_pNode->TryMeasure(XFA_ATTRIBUTE_Rotate, ms, false))
291 return 0;
292
293 int32_t iRotate = FXSYS_round(ms.GetValue());
294 iRotate = XFA_MapRotation(iRotate);
295 return iRotate / 90 * 90;
296 }
297
GetBorder(bool bModified)298 CXFA_Border CXFA_WidgetData::GetBorder(bool bModified) {
299 return CXFA_Border(m_pNode->GetProperty(0, XFA_Element::Border, bModified));
300 }
301
GetCaption(bool bModified)302 CXFA_Caption CXFA_WidgetData::GetCaption(bool bModified) {
303 return CXFA_Caption(m_pNode->GetProperty(0, XFA_Element::Caption, bModified));
304 }
305
GetFont(bool bModified)306 CXFA_Font CXFA_WidgetData::GetFont(bool bModified) {
307 return CXFA_Font(m_pNode->GetProperty(0, XFA_Element::Font, bModified));
308 }
309
GetMargin(bool bModified)310 CXFA_Margin CXFA_WidgetData::GetMargin(bool bModified) {
311 return CXFA_Margin(m_pNode->GetProperty(0, XFA_Element::Margin, bModified));
312 }
313
GetPara(bool bModified)314 CXFA_Para CXFA_WidgetData::GetPara(bool bModified) {
315 return CXFA_Para(m_pNode->GetProperty(0, XFA_Element::Para, bModified));
316 }
317
GetEventList(CXFA_NodeArray & events)318 void CXFA_WidgetData::GetEventList(CXFA_NodeArray& events) {
319 m_pNode->GetNodeList(events, 0, XFA_Element::Event);
320 }
321
GetEventByActivity(int32_t iActivity,CXFA_NodeArray & events,bool bIsFormReady)322 int32_t CXFA_WidgetData::GetEventByActivity(int32_t iActivity,
323 CXFA_NodeArray& events,
324 bool bIsFormReady) {
325 CXFA_NodeArray allEvents;
326 GetEventList(allEvents);
327 int32_t iCount = allEvents.GetSize();
328 for (int32_t i = 0; i < iCount; i++) {
329 CXFA_Event event(allEvents[i]);
330 if (event.GetActivity() == iActivity) {
331 if (iActivity == XFA_ATTRIBUTEENUM_Ready) {
332 CFX_WideStringC wsRef;
333 event.GetRef(wsRef);
334 if (bIsFormReady) {
335 if (wsRef == CFX_WideStringC(L"$form"))
336 events.Add(allEvents[i]);
337 } else {
338 if (wsRef == CFX_WideStringC(L"$layout"))
339 events.Add(allEvents[i]);
340 }
341 } else {
342 events.Add(allEvents[i]);
343 }
344 }
345 }
346 return events.GetSize();
347 }
348
GetDefaultValue(bool bModified)349 CXFA_Value CXFA_WidgetData::GetDefaultValue(bool bModified) {
350 CXFA_Node* pTemNode = m_pNode->GetTemplateNode();
351 return CXFA_Value(
352 pTemNode ? pTemNode->GetProperty(0, XFA_Element::Value, bModified)
353 : nullptr);
354 }
355
GetFormValue(bool bModified)356 CXFA_Value CXFA_WidgetData::GetFormValue(bool bModified) {
357 return CXFA_Value(m_pNode->GetProperty(0, XFA_Element::Value, bModified));
358 }
359
GetCalculate(bool bModified)360 CXFA_Calculate CXFA_WidgetData::GetCalculate(bool bModified) {
361 return CXFA_Calculate(
362 m_pNode->GetProperty(0, XFA_Element::Calculate, bModified));
363 }
364
GetValidate(bool bModified)365 CXFA_Validate CXFA_WidgetData::GetValidate(bool bModified) {
366 return CXFA_Validate(
367 m_pNode->GetProperty(0, XFA_Element::Validate, bModified));
368 }
369
GetBind(bool bModified)370 CXFA_Bind CXFA_WidgetData::GetBind(bool bModified) {
371 return CXFA_Bind(m_pNode->GetProperty(0, XFA_Element::Bind, bModified));
372 }
373
GetAssist(bool bModified)374 CXFA_Assist CXFA_WidgetData::GetAssist(bool bModified) {
375 return CXFA_Assist(m_pNode->GetProperty(0, XFA_Element::Assist, bModified));
376 }
377
GetWidth(FX_FLOAT & fWidth)378 bool CXFA_WidgetData::GetWidth(FX_FLOAT& fWidth) {
379 return TryMeasure(XFA_ATTRIBUTE_W, fWidth);
380 }
381
GetHeight(FX_FLOAT & fHeight)382 bool CXFA_WidgetData::GetHeight(FX_FLOAT& fHeight) {
383 return TryMeasure(XFA_ATTRIBUTE_H, fHeight);
384 }
385
GetMinWidth(FX_FLOAT & fMinWidth)386 bool CXFA_WidgetData::GetMinWidth(FX_FLOAT& fMinWidth) {
387 return TryMeasure(XFA_ATTRIBUTE_MinW, fMinWidth);
388 }
389
GetMinHeight(FX_FLOAT & fMinHeight)390 bool CXFA_WidgetData::GetMinHeight(FX_FLOAT& fMinHeight) {
391 return TryMeasure(XFA_ATTRIBUTE_MinH, fMinHeight);
392 }
393
GetMaxWidth(FX_FLOAT & fMaxWidth)394 bool CXFA_WidgetData::GetMaxWidth(FX_FLOAT& fMaxWidth) {
395 return TryMeasure(XFA_ATTRIBUTE_MaxW, fMaxWidth);
396 }
397
GetMaxHeight(FX_FLOAT & fMaxHeight)398 bool CXFA_WidgetData::GetMaxHeight(FX_FLOAT& fMaxHeight) {
399 return TryMeasure(XFA_ATTRIBUTE_MaxH, fMaxHeight);
400 }
401
GetUIBorder()402 CXFA_Border CXFA_WidgetData::GetUIBorder() {
403 CXFA_Node* pUIChild = GetUIChild();
404 return CXFA_Border(pUIChild
405 ? pUIChild->GetProperty(0, XFA_Element::Border, false)
406 : nullptr);
407 }
408
GetUIMargin()409 CFX_RectF CXFA_WidgetData::GetUIMargin() {
410 CXFA_Node* pUIChild = GetUIChild();
411 CXFA_Margin mgUI = CXFA_Margin(
412 pUIChild ? pUIChild->GetProperty(0, XFA_Element::Margin, false)
413 : nullptr);
414
415 if (!mgUI)
416 return CFX_RectF();
417
418 CXFA_Border border = GetUIBorder();
419 if (border && border.GetPresence() != XFA_ATTRIBUTEENUM_Visible)
420 return CFX_RectF();
421
422 FX_FLOAT fLeftInset, fTopInset, fRightInset, fBottomInset;
423 bool bLeft = mgUI.GetLeftInset(fLeftInset);
424 bool bTop = mgUI.GetTopInset(fTopInset);
425 bool bRight = mgUI.GetRightInset(fRightInset);
426 bool bBottom = mgUI.GetBottomInset(fBottomInset);
427 if (border) {
428 bool bVisible = false;
429 FX_FLOAT fThickness = 0;
430 border.Get3DStyle(bVisible, fThickness);
431 if (!bLeft || !bTop || !bRight || !bBottom) {
432 std::vector<CXFA_Stroke> strokes;
433 border.GetStrokes(&strokes);
434 if (!bTop)
435 fTopInset = GetEdgeThickness(strokes, bVisible, 0);
436 if (!bRight)
437 fRightInset = GetEdgeThickness(strokes, bVisible, 1);
438 if (!bBottom)
439 fBottomInset = GetEdgeThickness(strokes, bVisible, 2);
440 if (!bLeft)
441 fLeftInset = GetEdgeThickness(strokes, bVisible, 3);
442 }
443 }
444 return CFX_RectF(fLeftInset, fTopInset, fRightInset, fBottomInset);
445 }
446
GetButtonHighlight()447 int32_t CXFA_WidgetData::GetButtonHighlight() {
448 CXFA_Node* pUIChild = GetUIChild();
449 if (pUIChild)
450 return pUIChild->GetEnum(XFA_ATTRIBUTE_Highlight);
451 return GetAttributeDefaultValue_Enum(
452 XFA_Element::Button, XFA_ATTRIBUTE_Highlight, XFA_XDPPACKET_Form);
453 }
454
GetButtonRollover(CFX_WideString & wsRollover,bool & bRichText)455 bool CXFA_WidgetData::GetButtonRollover(CFX_WideString& wsRollover,
456 bool& bRichText) {
457 if (CXFA_Node* pItems = m_pNode->GetChild(0, XFA_Element::Items)) {
458 CXFA_Node* pText = pItems->GetNodeItem(XFA_NODEITEM_FirstChild);
459 while (pText) {
460 CFX_WideStringC wsName;
461 pText->TryCData(XFA_ATTRIBUTE_Name, wsName);
462 if (wsName == L"rollover") {
463 pText->TryContent(wsRollover);
464 bRichText = pText->GetElementType() == XFA_Element::ExData;
465 return !wsRollover.IsEmpty();
466 }
467 pText = pText->GetNodeItem(XFA_NODEITEM_NextSibling);
468 }
469 }
470 return false;
471 }
472
GetButtonDown(CFX_WideString & wsDown,bool & bRichText)473 bool CXFA_WidgetData::GetButtonDown(CFX_WideString& wsDown, bool& bRichText) {
474 if (CXFA_Node* pItems = m_pNode->GetChild(0, XFA_Element::Items)) {
475 CXFA_Node* pText = pItems->GetNodeItem(XFA_NODEITEM_FirstChild);
476 while (pText) {
477 CFX_WideStringC wsName;
478 pText->TryCData(XFA_ATTRIBUTE_Name, wsName);
479 if (wsName == L"down") {
480 pText->TryContent(wsDown);
481 bRichText = pText->GetElementType() == XFA_Element::ExData;
482 return !wsDown.IsEmpty();
483 }
484 pText = pText->GetNodeItem(XFA_NODEITEM_NextSibling);
485 }
486 }
487 return false;
488 }
489
GetCheckButtonShape()490 int32_t CXFA_WidgetData::GetCheckButtonShape() {
491 CXFA_Node* pUIChild = GetUIChild();
492 if (pUIChild)
493 return pUIChild->GetEnum(XFA_ATTRIBUTE_Shape);
494 return GetAttributeDefaultValue_Enum(XFA_Element::CheckButton,
495 XFA_ATTRIBUTE_Shape, XFA_XDPPACKET_Form);
496 }
497
GetCheckButtonMark()498 int32_t CXFA_WidgetData::GetCheckButtonMark() {
499 CXFA_Node* pUIChild = GetUIChild();
500 if (pUIChild)
501 return pUIChild->GetEnum(XFA_ATTRIBUTE_Mark);
502 return GetAttributeDefaultValue_Enum(XFA_Element::CheckButton,
503 XFA_ATTRIBUTE_Mark, XFA_XDPPACKET_Form);
504 }
505
IsRadioButton()506 bool CXFA_WidgetData::IsRadioButton() {
507 if (CXFA_Node* pParent = m_pNode->GetNodeItem(XFA_NODEITEM_Parent))
508 return pParent->GetElementType() == XFA_Element::ExclGroup;
509 return false;
510 }
511
GetCheckButtonSize()512 FX_FLOAT CXFA_WidgetData::GetCheckButtonSize() {
513 CXFA_Node* pUIChild = GetUIChild();
514 if (pUIChild)
515 return pUIChild->GetMeasure(XFA_ATTRIBUTE_Size).ToUnit(XFA_UNIT_Pt);
516 return XFA_GetAttributeDefaultValue_Measure(
517 XFA_Element::CheckButton, XFA_ATTRIBUTE_Size, XFA_XDPPACKET_Form)
518 .ToUnit(XFA_UNIT_Pt);
519 }
520
IsAllowNeutral()521 bool CXFA_WidgetData::IsAllowNeutral() {
522 CXFA_Node* pUIChild = GetUIChild();
523 if (pUIChild)
524 return pUIChild->GetBoolean(XFA_ATTRIBUTE_AllowNeutral);
525 return GetAttributeDefaultValue_Boolean(
526 XFA_Element::CheckButton, XFA_ATTRIBUTE_AllowNeutral, XFA_XDPPACKET_Form);
527 }
528
GetCheckState()529 XFA_CHECKSTATE CXFA_WidgetData::GetCheckState() {
530 CFX_WideString wsValue = GetRawValue();
531 if (wsValue.IsEmpty())
532 return XFA_CHECKSTATE_Off;
533
534 if (CXFA_Node* pItems = m_pNode->GetChild(0, XFA_Element::Items)) {
535 CXFA_Node* pText = pItems->GetNodeItem(XFA_NODEITEM_FirstChild);
536 int32_t i = 0;
537 while (pText) {
538 CFX_WideString wsContent;
539 if (pText->TryContent(wsContent) && (wsContent == wsValue))
540 return (XFA_CHECKSTATE)i;
541
542 i++;
543 pText = pText->GetNodeItem(XFA_NODEITEM_NextSibling);
544 }
545 }
546 return XFA_CHECKSTATE_Off;
547 }
548
SetCheckState(XFA_CHECKSTATE eCheckState,bool bNotify)549 void CXFA_WidgetData::SetCheckState(XFA_CHECKSTATE eCheckState, bool bNotify) {
550 CXFA_WidgetData exclGroup(GetExclGroupNode());
551 if (exclGroup) {
552 CFX_WideString wsValue;
553 if (eCheckState != XFA_CHECKSTATE_Off) {
554 if (CXFA_Node* pItems = m_pNode->GetChild(0, XFA_Element::Items)) {
555 CXFA_Node* pText = pItems->GetNodeItem(XFA_NODEITEM_FirstChild);
556 if (pText)
557 pText->TryContent(wsValue);
558 }
559 }
560 CXFA_Node* pChild =
561 exclGroup.GetNode()->GetNodeItem(XFA_NODEITEM_FirstChild);
562 for (; pChild; pChild = pChild->GetNodeItem(XFA_NODEITEM_NextSibling)) {
563 if (pChild->GetElementType() != XFA_Element::Field)
564 continue;
565
566 CXFA_Node* pItem = pChild->GetChild(0, XFA_Element::Items);
567 if (!pItem)
568 continue;
569
570 CXFA_Node* pItemchild = pItem->GetNodeItem(XFA_NODEITEM_FirstChild);
571 if (!pItemchild)
572 continue;
573
574 CFX_WideString text = pItemchild->GetContent();
575 CFX_WideString wsChildValue = text;
576 if (wsValue != text) {
577 pItemchild = pItemchild->GetNodeItem(XFA_NODEITEM_NextSibling);
578 if (pItemchild)
579 wsChildValue = pItemchild->GetContent();
580 else
581 wsChildValue.clear();
582 }
583 CXFA_WidgetData ch(pChild);
584 ch.SyncValue(wsChildValue, bNotify);
585 }
586 exclGroup.SyncValue(wsValue, bNotify);
587 } else {
588 CXFA_Node* pItems = m_pNode->GetChild(0, XFA_Element::Items);
589 if (!pItems)
590 return;
591
592 int32_t i = -1;
593 CXFA_Node* pText = pItems->GetNodeItem(XFA_NODEITEM_FirstChild);
594 CFX_WideString wsContent;
595 while (pText) {
596 i++;
597 if (i == eCheckState) {
598 pText->TryContent(wsContent);
599 break;
600 }
601 pText = pText->GetNodeItem(XFA_NODEITEM_NextSibling);
602 }
603 SyncValue(wsContent, bNotify);
604 }
605 }
606
GetExclGroupNode()607 CXFA_Node* CXFA_WidgetData::GetExclGroupNode() {
608 CXFA_Node* pExcl = ToNode(m_pNode->GetNodeItem(XFA_NODEITEM_Parent));
609 if (!pExcl || pExcl->GetElementType() != XFA_Element::ExclGroup)
610 return nullptr;
611 return pExcl;
612 }
613
GetSelectedMember()614 CXFA_Node* CXFA_WidgetData::GetSelectedMember() {
615 CXFA_Node* pSelectedMember = nullptr;
616 CFX_WideString wsState = GetRawValue();
617 if (wsState.IsEmpty())
618 return pSelectedMember;
619
620 for (CXFA_Node* pNode = ToNode(m_pNode->GetNodeItem(XFA_NODEITEM_FirstChild));
621 pNode; pNode = pNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
622 CXFA_WidgetData widgetData(pNode);
623 if (widgetData.GetCheckState() == XFA_CHECKSTATE_On) {
624 pSelectedMember = pNode;
625 break;
626 }
627 }
628 return pSelectedMember;
629 }
630
SetSelectedMember(const CFX_WideStringC & wsName,bool bNotify)631 CXFA_Node* CXFA_WidgetData::SetSelectedMember(const CFX_WideStringC& wsName,
632 bool bNotify) {
633 uint32_t nameHash = FX_HashCode_GetW(wsName, false);
634 for (CXFA_Node* pNode = ToNode(m_pNode->GetNodeItem(XFA_NODEITEM_FirstChild));
635 pNode; pNode = pNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
636 if (pNode->GetNameHash() == nameHash) {
637 CXFA_WidgetData widgetData(pNode);
638 widgetData.SetCheckState(XFA_CHECKSTATE_On, bNotify);
639 return pNode;
640 }
641 }
642 return nullptr;
643 }
644
SetSelectedMemberByValue(const CFX_WideStringC & wsValue,bool bNotify,bool bScriptModify,bool bSyncData)645 void CXFA_WidgetData::SetSelectedMemberByValue(const CFX_WideStringC& wsValue,
646 bool bNotify,
647 bool bScriptModify,
648 bool bSyncData) {
649 CFX_WideString wsExclGroup;
650 for (CXFA_Node* pNode = m_pNode->GetNodeItem(XFA_NODEITEM_FirstChild); pNode;
651 pNode = pNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
652 if (pNode->GetElementType() != XFA_Element::Field)
653 continue;
654
655 CXFA_Node* pItem = pNode->GetChild(0, XFA_Element::Items);
656 if (!pItem)
657 continue;
658
659 CXFA_Node* pItemchild = pItem->GetNodeItem(XFA_NODEITEM_FirstChild);
660 if (!pItemchild)
661 continue;
662
663 CFX_WideString wsChildValue = pItemchild->GetContent();
664 if (wsValue != wsChildValue) {
665 pItemchild = pItemchild->GetNodeItem(XFA_NODEITEM_NextSibling);
666 if (pItemchild)
667 wsChildValue = pItemchild->GetContent();
668 else
669 wsChildValue.clear();
670 } else {
671 wsExclGroup = wsValue;
672 }
673 pNode->SetContent(wsChildValue, wsChildValue, bNotify, bScriptModify,
674 false);
675 }
676 if (m_pNode) {
677 m_pNode->SetContent(wsExclGroup, wsExclGroup, bNotify, bScriptModify,
678 bSyncData);
679 }
680 }
681
GetExclGroupFirstMember()682 CXFA_Node* CXFA_WidgetData::GetExclGroupFirstMember() {
683 CXFA_Node* pExcl = GetNode();
684 if (!pExcl)
685 return nullptr;
686
687 CXFA_Node* pNode = pExcl->GetNodeItem(XFA_NODEITEM_FirstChild);
688 while (pNode) {
689 if (pNode->GetElementType() == XFA_Element::Field)
690 return pNode;
691
692 pNode = pNode->GetNodeItem(XFA_NODEITEM_NextSibling);
693 }
694 return nullptr;
695 }
GetExclGroupNextMember(CXFA_Node * pNode)696 CXFA_Node* CXFA_WidgetData::GetExclGroupNextMember(CXFA_Node* pNode) {
697 if (!pNode)
698 return nullptr;
699
700 CXFA_Node* pNodeField = pNode->GetNodeItem(XFA_NODEITEM_NextSibling);
701 while (pNodeField) {
702 if (pNodeField->GetElementType() == XFA_Element::Field)
703 return pNodeField;
704
705 pNodeField = pNodeField->GetNodeItem(XFA_NODEITEM_NextSibling);
706 }
707 return nullptr;
708 }
709
GetChoiceListCommitOn()710 int32_t CXFA_WidgetData::GetChoiceListCommitOn() {
711 CXFA_Node* pUIChild = GetUIChild();
712 if (pUIChild)
713 return pUIChild->GetEnum(XFA_ATTRIBUTE_CommitOn);
714 return GetAttributeDefaultValue_Enum(
715 XFA_Element::ChoiceList, XFA_ATTRIBUTE_CommitOn, XFA_XDPPACKET_Form);
716 }
717
IsChoiceListAllowTextEntry()718 bool CXFA_WidgetData::IsChoiceListAllowTextEntry() {
719 CXFA_Node* pUIChild = GetUIChild();
720 if (pUIChild)
721 return pUIChild->GetBoolean(XFA_ATTRIBUTE_TextEntry);
722 return GetAttributeDefaultValue_Boolean(
723 XFA_Element::ChoiceList, XFA_ATTRIBUTE_TextEntry, XFA_XDPPACKET_Form);
724 }
725
GetChoiceListOpen()726 int32_t CXFA_WidgetData::GetChoiceListOpen() {
727 CXFA_Node* pUIChild = GetUIChild();
728 if (pUIChild)
729 return pUIChild->GetEnum(XFA_ATTRIBUTE_Open);
730 return GetAttributeDefaultValue_Enum(XFA_Element::ChoiceList,
731 XFA_ATTRIBUTE_Open, XFA_XDPPACKET_Form);
732 }
733
IsListBox()734 bool CXFA_WidgetData::IsListBox() {
735 int32_t iOpenMode = GetChoiceListOpen();
736 return (iOpenMode == XFA_ATTRIBUTEENUM_Always ||
737 iOpenMode == XFA_ATTRIBUTEENUM_MultiSelect);
738 }
739
CountChoiceListItems(bool bSaveValue)740 int32_t CXFA_WidgetData::CountChoiceListItems(bool bSaveValue) {
741 CXFA_NodeArray pItems;
742 CXFA_Node* pItem = nullptr;
743 int32_t iCount = 0;
744 CXFA_Node* pNode = m_pNode->GetNodeItem(XFA_NODEITEM_FirstChild);
745 for (; pNode; pNode = pNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
746 if (pNode->GetElementType() != XFA_Element::Items)
747 continue;
748
749 iCount++;
750 pItems.Add(pNode);
751 if (iCount == 2)
752 break;
753 }
754 if (iCount == 0)
755 return 0;
756
757 pItem = pItems[0];
758 if (iCount > 1) {
759 bool bItemOneHasSave = pItems[0]->GetBoolean(XFA_ATTRIBUTE_Save);
760 bool bItemTwoHasSave = pItems[1]->GetBoolean(XFA_ATTRIBUTE_Save);
761 if (bItemOneHasSave != bItemTwoHasSave && bSaveValue == bItemTwoHasSave)
762 pItem = pItems[1];
763 }
764 pItems.RemoveAll();
765 return pItem->CountChildren(XFA_Element::Unknown);
766 }
767
GetChoiceListItem(CFX_WideString & wsText,int32_t nIndex,bool bSaveValue)768 bool CXFA_WidgetData::GetChoiceListItem(CFX_WideString& wsText,
769 int32_t nIndex,
770 bool bSaveValue) {
771 wsText.clear();
772 CXFA_NodeArray pItemsArray;
773 CXFA_Node* pItems = nullptr;
774 int32_t iCount = 0;
775 CXFA_Node* pNode = m_pNode->GetNodeItem(XFA_NODEITEM_FirstChild);
776 for (; pNode; pNode = pNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
777 if (pNode->GetElementType() != XFA_Element::Items)
778 continue;
779
780 iCount++;
781 pItemsArray.Add(pNode);
782 if (iCount == 2)
783 break;
784 }
785 if (iCount == 0)
786 return false;
787
788 pItems = pItemsArray[0];
789 if (iCount > 1) {
790 bool bItemOneHasSave = pItemsArray[0]->GetBoolean(XFA_ATTRIBUTE_Save);
791 bool bItemTwoHasSave = pItemsArray[1]->GetBoolean(XFA_ATTRIBUTE_Save);
792 if (bItemOneHasSave != bItemTwoHasSave && bSaveValue == bItemTwoHasSave)
793 pItems = pItemsArray[1];
794 }
795 if (pItems) {
796 CXFA_Node* pItem = pItems->GetChild(nIndex, XFA_Element::Unknown);
797 if (pItem) {
798 pItem->TryContent(wsText);
799 return true;
800 }
801 }
802 return false;
803 }
804
GetChoiceListItems(std::vector<CFX_WideString> & wsTextArray,bool bSaveValue)805 void CXFA_WidgetData::GetChoiceListItems(
806 std::vector<CFX_WideString>& wsTextArray,
807 bool bSaveValue) {
808 CXFA_NodeArray pItems;
809 CXFA_Node* pItem = nullptr;
810 int32_t iCount = 0;
811 CXFA_Node* pNode = m_pNode->GetNodeItem(XFA_NODEITEM_FirstChild);
812 for (; pNode; pNode = pNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
813 if (pNode->GetElementType() != XFA_Element::Items)
814 continue;
815
816 iCount++;
817 pItems.Add(pNode);
818 if (iCount == 2)
819 break;
820 }
821 if (iCount == 0)
822 return;
823
824 pItem = pItems[0];
825 if (iCount > 1) {
826 bool bItemOneHasSave = pItems[0]->GetBoolean(XFA_ATTRIBUTE_Save);
827 bool bItemTwoHasSave = pItems[1]->GetBoolean(XFA_ATTRIBUTE_Save);
828 if (bItemOneHasSave != bItemTwoHasSave && bSaveValue == bItemTwoHasSave)
829 pItem = pItems[1];
830 }
831 pItems.RemoveAll();
832 pNode = pItem->GetNodeItem(XFA_NODEITEM_FirstChild);
833 for (; pNode; pNode = pNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
834 wsTextArray.emplace_back();
835 pNode->TryContent(wsTextArray.back());
836 }
837 }
838
CountSelectedItems()839 int32_t CXFA_WidgetData::CountSelectedItems() {
840 std::vector<CFX_WideString> wsValueArray;
841 GetSelectedItemsValue(wsValueArray);
842 if (IsListBox() || !IsChoiceListAllowTextEntry())
843 return pdfium::CollectionSize<int32_t>(wsValueArray);
844
845 int32_t iSelected = 0;
846 std::vector<CFX_WideString> wsSaveTextArray;
847 GetChoiceListItems(wsSaveTextArray, true);
848 int32_t iValues = pdfium::CollectionSize<int32_t>(wsValueArray);
849 for (int32_t i = 0; i < iValues; i++) {
850 int32_t iSaves = pdfium::CollectionSize<int32_t>(wsSaveTextArray);
851 for (int32_t j = 0; j < iSaves; j++) {
852 if (wsValueArray[i] == wsSaveTextArray[j]) {
853 iSelected++;
854 break;
855 }
856 }
857 }
858 return iSelected;
859 }
860
GetSelectedItem(int32_t nIndex)861 int32_t CXFA_WidgetData::GetSelectedItem(int32_t nIndex) {
862 std::vector<CFX_WideString> wsValueArray;
863 GetSelectedItemsValue(wsValueArray);
864 std::vector<CFX_WideString> wsSaveTextArray;
865 GetChoiceListItems(wsSaveTextArray, true);
866 int32_t iSaves = pdfium::CollectionSize<int32_t>(wsSaveTextArray);
867 for (int32_t j = 0; j < iSaves; j++) {
868 if (wsValueArray[nIndex] == wsSaveTextArray[j])
869 return j;
870 }
871 return -1;
872 }
873
GetSelectedItems(CFX_ArrayTemplate<int32_t> & iSelArray)874 void CXFA_WidgetData::GetSelectedItems(CFX_ArrayTemplate<int32_t>& iSelArray) {
875 std::vector<CFX_WideString> wsValueArray;
876 GetSelectedItemsValue(wsValueArray);
877 int32_t iValues = pdfium::CollectionSize<int32_t>(wsValueArray);
878 if (iValues < 1)
879 return;
880
881 std::vector<CFX_WideString> wsSaveTextArray;
882 GetChoiceListItems(wsSaveTextArray, true);
883 int32_t iSaves = pdfium::CollectionSize<int32_t>(wsSaveTextArray);
884 for (int32_t i = 0; i < iValues; i++) {
885 for (int32_t j = 0; j < iSaves; j++) {
886 if (wsValueArray[i] == wsSaveTextArray[j]) {
887 iSelArray.Add(j);
888 break;
889 }
890 }
891 }
892 }
893
GetSelectedItemsValue(std::vector<CFX_WideString> & wsSelTextArray)894 void CXFA_WidgetData::GetSelectedItemsValue(
895 std::vector<CFX_WideString>& wsSelTextArray) {
896 CFX_WideString wsValue = GetRawValue();
897 if (GetChoiceListOpen() == XFA_ATTRIBUTEENUM_MultiSelect) {
898 if (!wsValue.IsEmpty()) {
899 int32_t iStart = 0;
900 int32_t iLength = wsValue.GetLength();
901 int32_t iEnd = wsValue.Find(L'\n', iStart);
902 iEnd = (iEnd == -1) ? iLength : iEnd;
903 while (iEnd >= iStart) {
904 wsSelTextArray.push_back(wsValue.Mid(iStart, iEnd - iStart));
905 iStart = iEnd + 1;
906 if (iStart >= iLength)
907 break;
908
909 iEnd = wsValue.Find(L'\n', iStart);
910 if (iEnd < 0)
911 wsSelTextArray.push_back(wsValue.Mid(iStart, iLength - iStart));
912 }
913 }
914 } else {
915 wsSelTextArray.push_back(wsValue);
916 }
917 }
918
GetItemState(int32_t nIndex)919 bool CXFA_WidgetData::GetItemState(int32_t nIndex) {
920 if (nIndex < 0)
921 return false;
922
923 std::vector<CFX_WideString> wsSaveTextArray;
924 GetChoiceListItems(wsSaveTextArray, true);
925 if (pdfium::CollectionSize<int32_t>(wsSaveTextArray) <= nIndex)
926 return false;
927
928 std::vector<CFX_WideString> wsValueArray;
929 GetSelectedItemsValue(wsValueArray);
930 int32_t iValues = pdfium::CollectionSize<int32_t>(wsValueArray);
931 for (int32_t j = 0; j < iValues; j++) {
932 if (wsValueArray[j] == wsSaveTextArray[nIndex])
933 return true;
934 }
935 return false;
936 }
937
SetItemState(int32_t nIndex,bool bSelected,bool bNotify,bool bScriptModify,bool bSyncData)938 void CXFA_WidgetData::SetItemState(int32_t nIndex,
939 bool bSelected,
940 bool bNotify,
941 bool bScriptModify,
942 bool bSyncData) {
943 if (nIndex < 0)
944 return;
945
946 std::vector<CFX_WideString> wsSaveTextArray;
947 GetChoiceListItems(wsSaveTextArray, true);
948 if (pdfium::CollectionSize<int32_t>(wsSaveTextArray) <= nIndex)
949 return;
950
951 int32_t iSel = -1;
952 std::vector<CFX_WideString> wsValueArray;
953 GetSelectedItemsValue(wsValueArray);
954 int32_t iValues = pdfium::CollectionSize<int32_t>(wsValueArray);
955 for (int32_t j = 0; j < iValues; j++) {
956 if (wsValueArray[j] == wsSaveTextArray[nIndex]) {
957 iSel = j;
958 break;
959 }
960 }
961 if (GetChoiceListOpen() == XFA_ATTRIBUTEENUM_MultiSelect) {
962 if (bSelected) {
963 if (iSel < 0) {
964 CFX_WideString wsValue = GetRawValue();
965 if (!wsValue.IsEmpty()) {
966 wsValue += L"\n";
967 }
968 wsValue += wsSaveTextArray[nIndex];
969 m_pNode->SetContent(wsValue, wsValue, bNotify, bScriptModify,
970 bSyncData);
971 }
972 } else if (iSel >= 0) {
973 CFX_ArrayTemplate<int32_t> iSelArray;
974 GetSelectedItems(iSelArray);
975 for (int32_t i = 0; i < iSelArray.GetSize(); i++) {
976 if (iSelArray[i] == nIndex) {
977 iSelArray.RemoveAt(i);
978 break;
979 }
980 }
981 SetSelectedItems(iSelArray, bNotify, bScriptModify, bSyncData);
982 }
983 } else {
984 if (bSelected) {
985 if (iSel < 0) {
986 CFX_WideString wsSaveText = wsSaveTextArray[nIndex];
987 CFX_WideString wsFormatText(wsSaveText);
988 GetFormatDataValue(wsSaveText, wsFormatText);
989 m_pNode->SetContent(wsSaveText, wsFormatText, bNotify, bScriptModify,
990 bSyncData);
991 }
992 } else if (iSel >= 0) {
993 m_pNode->SetContent(CFX_WideString(), CFX_WideString(), bNotify,
994 bScriptModify, bSyncData);
995 }
996 }
997 }
998
SetSelectedItems(CFX_ArrayTemplate<int32_t> & iSelArray,bool bNotify,bool bScriptModify,bool bSyncData)999 void CXFA_WidgetData::SetSelectedItems(CFX_ArrayTemplate<int32_t>& iSelArray,
1000 bool bNotify,
1001 bool bScriptModify,
1002 bool bSyncData) {
1003 CFX_WideString wsValue;
1004 int32_t iSize = iSelArray.GetSize();
1005 if (iSize >= 1) {
1006 std::vector<CFX_WideString> wsSaveTextArray;
1007 GetChoiceListItems(wsSaveTextArray, true);
1008 CFX_WideString wsItemValue;
1009 for (int32_t i = 0; i < iSize; i++) {
1010 wsItemValue = (iSize == 1) ? wsSaveTextArray[iSelArray[i]]
1011 : wsSaveTextArray[iSelArray[i]] + L"\n";
1012 wsValue += wsItemValue;
1013 }
1014 }
1015 CFX_WideString wsFormat(wsValue);
1016 if (GetChoiceListOpen() != XFA_ATTRIBUTEENUM_MultiSelect)
1017 GetFormatDataValue(wsValue, wsFormat);
1018
1019 m_pNode->SetContent(wsValue, wsFormat, bNotify, bScriptModify, bSyncData);
1020 }
1021
ClearAllSelections()1022 void CXFA_WidgetData::ClearAllSelections() {
1023 CXFA_Node* pBind = m_pNode->GetBindData();
1024 if (!pBind || GetChoiceListOpen() != XFA_ATTRIBUTEENUM_MultiSelect) {
1025 SyncValue(CFX_WideString(), false);
1026 return;
1027 }
1028
1029 while (CXFA_Node* pChildNode = pBind->GetNodeItem(XFA_NODEITEM_FirstChild))
1030 pBind->RemoveChild(pChildNode);
1031 }
1032
InsertItem(const CFX_WideString & wsLabel,const CFX_WideString & wsValue,int32_t nIndex,bool bNotify)1033 void CXFA_WidgetData::InsertItem(const CFX_WideString& wsLabel,
1034 const CFX_WideString& wsValue,
1035 int32_t nIndex,
1036 bool bNotify) {
1037 CFX_WideString wsNewValue(wsValue);
1038 if (wsNewValue.IsEmpty())
1039 wsNewValue = wsLabel;
1040
1041 CXFA_NodeArray listitems;
1042 int32_t iCount = 0;
1043 CXFA_Node* pItemNode = m_pNode->GetNodeItem(XFA_NODEITEM_FirstChild);
1044 for (; pItemNode;
1045 pItemNode = pItemNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
1046 if (pItemNode->GetElementType() != XFA_Element::Items)
1047 continue;
1048
1049 listitems.Add(pItemNode);
1050 iCount++;
1051 }
1052 if (iCount < 1) {
1053 CXFA_Node* pItems = m_pNode->CreateSamePacketNode(XFA_Element::Items);
1054 m_pNode->InsertChild(-1, pItems);
1055 InsertListTextItem(pItems, wsLabel, nIndex);
1056 CXFA_Node* pSaveItems = m_pNode->CreateSamePacketNode(XFA_Element::Items);
1057 m_pNode->InsertChild(-1, pSaveItems);
1058 pSaveItems->SetBoolean(XFA_ATTRIBUTE_Save, true);
1059 InsertListTextItem(pSaveItems, wsNewValue, nIndex);
1060 } else if (iCount > 1) {
1061 for (int32_t i = 0; i < 2; i++) {
1062 CXFA_Node* pNode = listitems[i];
1063 bool bHasSave = pNode->GetBoolean(XFA_ATTRIBUTE_Save);
1064 if (bHasSave)
1065 InsertListTextItem(pNode, wsNewValue, nIndex);
1066 else
1067 InsertListTextItem(pNode, wsLabel, nIndex);
1068 }
1069 } else {
1070 CXFA_Node* pNode = listitems[0];
1071 pNode->SetBoolean(XFA_ATTRIBUTE_Save, false);
1072 pNode->SetEnum(XFA_ATTRIBUTE_Presence, XFA_ATTRIBUTEENUM_Visible);
1073 CXFA_Node* pSaveItems = m_pNode->CreateSamePacketNode(XFA_Element::Items);
1074 m_pNode->InsertChild(-1, pSaveItems);
1075 pSaveItems->SetBoolean(XFA_ATTRIBUTE_Save, true);
1076 pSaveItems->SetEnum(XFA_ATTRIBUTE_Presence, XFA_ATTRIBUTEENUM_Hidden);
1077 listitems.RemoveAll();
1078 CXFA_Node* pListNode = pNode->GetNodeItem(XFA_NODEITEM_FirstChild);
1079 int32_t i = 0;
1080 while (pListNode) {
1081 CFX_WideString wsOldValue;
1082 pListNode->TryContent(wsOldValue);
1083 InsertListTextItem(pSaveItems, wsOldValue, i);
1084 i++;
1085 pListNode = pListNode->GetNodeItem(XFA_NODEITEM_NextSibling);
1086 }
1087 InsertListTextItem(pNode, wsLabel, nIndex);
1088 InsertListTextItem(pSaveItems, wsNewValue, nIndex);
1089 }
1090 if (!bNotify)
1091 return;
1092
1093 m_pNode->GetDocument()->GetNotify()->OnWidgetListItemAdded(
1094 this, wsLabel.c_str(), wsValue.c_str(), nIndex);
1095 }
1096
GetItemLabel(const CFX_WideStringC & wsValue,CFX_WideString & wsLabel)1097 void CXFA_WidgetData::GetItemLabel(const CFX_WideStringC& wsValue,
1098 CFX_WideString& wsLabel) {
1099 int32_t iCount = 0;
1100 CXFA_NodeArray listitems;
1101 CXFA_Node* pItems = m_pNode->GetNodeItem(XFA_NODEITEM_FirstChild);
1102 for (; pItems; pItems = pItems->GetNodeItem(XFA_NODEITEM_NextSibling)) {
1103 if (pItems->GetElementType() != XFA_Element::Items)
1104 continue;
1105
1106 iCount++;
1107 listitems.Add(pItems);
1108 }
1109 if (iCount <= 1) {
1110 wsLabel = wsValue;
1111 } else {
1112 CXFA_Node* pLabelItems = listitems[0];
1113 bool bSave = pLabelItems->GetBoolean(XFA_ATTRIBUTE_Save);
1114 CXFA_Node* pSaveItems = nullptr;
1115 if (bSave) {
1116 pSaveItems = pLabelItems;
1117 pLabelItems = listitems[1];
1118 } else {
1119 pSaveItems = listitems[1];
1120 }
1121 iCount = 0;
1122 int32_t iSearch = -1;
1123 CFX_WideString wsContent;
1124 CXFA_Node* pChildItem = pSaveItems->GetNodeItem(XFA_NODEITEM_FirstChild);
1125 for (; pChildItem;
1126 pChildItem = pChildItem->GetNodeItem(XFA_NODEITEM_NextSibling)) {
1127 pChildItem->TryContent(wsContent);
1128 if (wsContent == wsValue) {
1129 iSearch = iCount;
1130 break;
1131 }
1132 iCount++;
1133 }
1134 if (iSearch < 0)
1135 return;
1136 if (CXFA_Node* pText =
1137 pLabelItems->GetChild(iSearch, XFA_Element::Unknown)) {
1138 pText->TryContent(wsLabel);
1139 }
1140 }
1141 }
1142
GetItemValue(const CFX_WideStringC & wsLabel,CFX_WideString & wsValue)1143 void CXFA_WidgetData::GetItemValue(const CFX_WideStringC& wsLabel,
1144 CFX_WideString& wsValue) {
1145 int32_t iCount = 0;
1146 CXFA_NodeArray listitems;
1147 CXFA_Node* pItems = m_pNode->GetNodeItem(XFA_NODEITEM_FirstChild);
1148 for (; pItems; pItems = pItems->GetNodeItem(XFA_NODEITEM_NextSibling)) {
1149 if (pItems->GetElementType() != XFA_Element::Items)
1150 continue;
1151
1152 iCount++;
1153 listitems.Add(pItems);
1154 }
1155 if (iCount <= 1) {
1156 wsValue = wsLabel;
1157 } else {
1158 CXFA_Node* pLabelItems = listitems[0];
1159 bool bSave = pLabelItems->GetBoolean(XFA_ATTRIBUTE_Save);
1160 CXFA_Node* pSaveItems = nullptr;
1161 if (bSave) {
1162 pSaveItems = pLabelItems;
1163 pLabelItems = listitems[1];
1164 } else {
1165 pSaveItems = listitems[1];
1166 }
1167 iCount = 0;
1168 int32_t iSearch = -1;
1169 CFX_WideString wsContent;
1170 CXFA_Node* pChildItem = pLabelItems->GetNodeItem(XFA_NODEITEM_FirstChild);
1171 for (; pChildItem;
1172 pChildItem = pChildItem->GetNodeItem(XFA_NODEITEM_NextSibling)) {
1173 pChildItem->TryContent(wsContent);
1174 if (wsContent == wsLabel) {
1175 iSearch = iCount;
1176 break;
1177 }
1178 iCount++;
1179 }
1180 if (iSearch < 0)
1181 return;
1182 if (CXFA_Node* pText = pSaveItems->GetChild(iSearch, XFA_Element::Unknown))
1183 pText->TryContent(wsValue);
1184 }
1185 }
1186
DeleteItem(int32_t nIndex,bool bNotify,bool bScriptModify,bool bSyncData)1187 bool CXFA_WidgetData::DeleteItem(int32_t nIndex,
1188 bool bNotify,
1189 bool bScriptModify,
1190 bool bSyncData) {
1191 bool bSetValue = false;
1192 CXFA_Node* pItems = m_pNode->GetNodeItem(XFA_NODEITEM_FirstChild);
1193 for (; pItems; pItems = pItems->GetNodeItem(XFA_NODEITEM_NextSibling)) {
1194 if (pItems->GetElementType() != XFA_Element::Items)
1195 continue;
1196
1197 if (nIndex < 0) {
1198 while (CXFA_Node* pNode = pItems->GetNodeItem(XFA_NODEITEM_FirstChild)) {
1199 pItems->RemoveChild(pNode);
1200 }
1201 } else {
1202 if (!bSetValue && pItems->GetBoolean(XFA_ATTRIBUTE_Save)) {
1203 SetItemState(nIndex, false, true, bScriptModify, bSyncData);
1204 bSetValue = true;
1205 }
1206 int32_t i = 0;
1207 CXFA_Node* pNode = pItems->GetNodeItem(XFA_NODEITEM_FirstChild);
1208 while (pNode) {
1209 if (i == nIndex) {
1210 pItems->RemoveChild(pNode);
1211 break;
1212 }
1213 i++;
1214 pNode = pNode->GetNodeItem(XFA_NODEITEM_NextSibling);
1215 }
1216 }
1217 }
1218 if (bNotify)
1219 m_pNode->GetDocument()->GetNotify()->OnWidgetListItemRemoved(this, nIndex);
1220 return true;
1221 }
1222
GetHorizontalScrollPolicy()1223 int32_t CXFA_WidgetData::GetHorizontalScrollPolicy() {
1224 CXFA_Node* pUIChild = GetUIChild();
1225 if (pUIChild)
1226 return pUIChild->GetEnum(XFA_ATTRIBUTE_HScrollPolicy);
1227 return XFA_ATTRIBUTEENUM_Auto;
1228 }
1229
GetNumberOfCells()1230 int32_t CXFA_WidgetData::GetNumberOfCells() {
1231 CXFA_Node* pUIChild = GetUIChild();
1232 if (!pUIChild)
1233 return -1;
1234 if (CXFA_Node* pNode = pUIChild->GetChild(0, XFA_Element::Comb))
1235 return pNode->GetInteger(XFA_ATTRIBUTE_NumberOfCells);
1236 return -1;
1237 }
1238
GetBarcodeType()1239 CFX_WideString CXFA_WidgetData::GetBarcodeType() {
1240 CXFA_Node* pUIChild = GetUIChild();
1241 return pUIChild ? CFX_WideString(pUIChild->GetCData(XFA_ATTRIBUTE_Type))
1242 : CFX_WideString();
1243 }
1244
GetBarcodeAttribute_CharEncoding(int32_t & val)1245 bool CXFA_WidgetData::GetBarcodeAttribute_CharEncoding(int32_t& val) {
1246 CXFA_Node* pUIChild = GetUIChild();
1247 CFX_WideString wsCharEncoding;
1248 if (pUIChild->TryCData(XFA_ATTRIBUTE_CharEncoding, wsCharEncoding)) {
1249 if (wsCharEncoding.CompareNoCase(L"UTF-16")) {
1250 val = CHAR_ENCODING_UNICODE;
1251 return true;
1252 }
1253 if (wsCharEncoding.CompareNoCase(L"UTF-8")) {
1254 val = CHAR_ENCODING_UTF8;
1255 return true;
1256 }
1257 }
1258 return false;
1259 }
1260
GetBarcodeAttribute_Checksum(bool & val)1261 bool CXFA_WidgetData::GetBarcodeAttribute_Checksum(bool& val) {
1262 CXFA_Node* pUIChild = GetUIChild();
1263 XFA_ATTRIBUTEENUM eChecksum;
1264 if (pUIChild->TryEnum(XFA_ATTRIBUTE_Checksum, eChecksum)) {
1265 switch (eChecksum) {
1266 case XFA_ATTRIBUTEENUM_None:
1267 val = false;
1268 return true;
1269 case XFA_ATTRIBUTEENUM_Auto:
1270 val = true;
1271 return true;
1272 case XFA_ATTRIBUTEENUM_1mod10:
1273 break;
1274 case XFA_ATTRIBUTEENUM_1mod10_1mod11:
1275 break;
1276 case XFA_ATTRIBUTEENUM_2mod10:
1277 break;
1278 default:
1279 break;
1280 }
1281 }
1282 return false;
1283 }
1284
GetBarcodeAttribute_DataLength(int32_t & val)1285 bool CXFA_WidgetData::GetBarcodeAttribute_DataLength(int32_t& val) {
1286 CXFA_Node* pUIChild = GetUIChild();
1287 CFX_WideString wsDataLength;
1288 if (pUIChild->TryCData(XFA_ATTRIBUTE_DataLength, wsDataLength)) {
1289 val = FXSYS_wtoi(wsDataLength.c_str());
1290 return true;
1291 }
1292 return false;
1293 }
1294
GetBarcodeAttribute_StartChar(FX_CHAR & val)1295 bool CXFA_WidgetData::GetBarcodeAttribute_StartChar(FX_CHAR& val) {
1296 CXFA_Node* pUIChild = GetUIChild();
1297 CFX_WideStringC wsStartEndChar;
1298 if (pUIChild->TryCData(XFA_ATTRIBUTE_StartChar, wsStartEndChar)) {
1299 if (wsStartEndChar.GetLength()) {
1300 val = (FX_CHAR)wsStartEndChar.GetAt(0);
1301 return true;
1302 }
1303 }
1304 return false;
1305 }
1306
GetBarcodeAttribute_EndChar(FX_CHAR & val)1307 bool CXFA_WidgetData::GetBarcodeAttribute_EndChar(FX_CHAR& val) {
1308 CXFA_Node* pUIChild = GetUIChild();
1309 CFX_WideStringC wsStartEndChar;
1310 if (pUIChild->TryCData(XFA_ATTRIBUTE_EndChar, wsStartEndChar)) {
1311 if (wsStartEndChar.GetLength()) {
1312 val = (FX_CHAR)wsStartEndChar.GetAt(0);
1313 return true;
1314 }
1315 }
1316 return false;
1317 }
1318
GetBarcodeAttribute_ECLevel(int32_t & val)1319 bool CXFA_WidgetData::GetBarcodeAttribute_ECLevel(int32_t& val) {
1320 CXFA_Node* pUIChild = GetUIChild();
1321 CFX_WideString wsECLevel;
1322 if (pUIChild->TryCData(XFA_ATTRIBUTE_ErrorCorrectionLevel, wsECLevel)) {
1323 val = FXSYS_wtoi(wsECLevel.c_str());
1324 return true;
1325 }
1326 return false;
1327 }
1328
GetBarcodeAttribute_ModuleWidth(int32_t & val)1329 bool CXFA_WidgetData::GetBarcodeAttribute_ModuleWidth(int32_t& val) {
1330 CXFA_Node* pUIChild = GetUIChild();
1331 CXFA_Measurement mModuleWidthHeight;
1332 if (pUIChild->TryMeasure(XFA_ATTRIBUTE_ModuleWidth, mModuleWidthHeight)) {
1333 val = (int32_t)mModuleWidthHeight.ToUnit(XFA_UNIT_Pt);
1334 return true;
1335 }
1336 return false;
1337 }
1338
GetBarcodeAttribute_ModuleHeight(int32_t & val)1339 bool CXFA_WidgetData::GetBarcodeAttribute_ModuleHeight(int32_t& val) {
1340 CXFA_Node* pUIChild = GetUIChild();
1341 CXFA_Measurement mModuleWidthHeight;
1342 if (pUIChild->TryMeasure(XFA_ATTRIBUTE_ModuleHeight, mModuleWidthHeight)) {
1343 val = (int32_t)mModuleWidthHeight.ToUnit(XFA_UNIT_Pt);
1344 return true;
1345 }
1346 return false;
1347 }
1348
GetBarcodeAttribute_PrintChecksum(bool & val)1349 bool CXFA_WidgetData::GetBarcodeAttribute_PrintChecksum(bool& val) {
1350 CXFA_Node* pUIChild = GetUIChild();
1351 bool bPrintCheckDigit;
1352 if (pUIChild->TryBoolean(XFA_ATTRIBUTE_PrintCheckDigit, bPrintCheckDigit)) {
1353 val = bPrintCheckDigit;
1354 return true;
1355 }
1356 return false;
1357 }
1358
GetBarcodeAttribute_TextLocation(int32_t & val)1359 bool CXFA_WidgetData::GetBarcodeAttribute_TextLocation(int32_t& val) {
1360 CXFA_Node* pUIChild = GetUIChild();
1361 XFA_ATTRIBUTEENUM eTextLocation;
1362 if (pUIChild->TryEnum(XFA_ATTRIBUTE_TextLocation, eTextLocation)) {
1363 switch (eTextLocation) {
1364 case XFA_ATTRIBUTEENUM_None:
1365 val = BC_TEXT_LOC_NONE;
1366 return true;
1367 case XFA_ATTRIBUTEENUM_Above:
1368 val = BC_TEXT_LOC_ABOVE;
1369 return true;
1370 case XFA_ATTRIBUTEENUM_Below:
1371 val = BC_TEXT_LOC_BELOW;
1372 return true;
1373 case XFA_ATTRIBUTEENUM_AboveEmbedded:
1374 val = BC_TEXT_LOC_ABOVEEMBED;
1375 return true;
1376 case XFA_ATTRIBUTEENUM_BelowEmbedded:
1377 val = BC_TEXT_LOC_BELOWEMBED;
1378 return true;
1379 default:
1380 break;
1381 }
1382 }
1383 return false;
1384 }
1385
GetBarcodeAttribute_Truncate(bool & val)1386 bool CXFA_WidgetData::GetBarcodeAttribute_Truncate(bool& val) {
1387 CXFA_Node* pUIChild = GetUIChild();
1388 bool bTruncate;
1389 if (pUIChild->TryBoolean(XFA_ATTRIBUTE_Truncate, bTruncate)) {
1390 val = bTruncate;
1391 return true;
1392 }
1393 return false;
1394 }
1395
GetBarcodeAttribute_WideNarrowRatio(FX_FLOAT & val)1396 bool CXFA_WidgetData::GetBarcodeAttribute_WideNarrowRatio(FX_FLOAT& val) {
1397 CXFA_Node* pUIChild = GetUIChild();
1398 CFX_WideString wsWideNarrowRatio;
1399 if (pUIChild->TryCData(XFA_ATTRIBUTE_WideNarrowRatio, wsWideNarrowRatio)) {
1400 FX_STRSIZE ptPos = wsWideNarrowRatio.Find(':');
1401 FX_FLOAT fRatio = 0;
1402 if (ptPos >= 0) {
1403 fRatio = (FX_FLOAT)FXSYS_wtoi(wsWideNarrowRatio.c_str());
1404 } else {
1405 int32_t fA, fB;
1406 fA = FXSYS_wtoi(wsWideNarrowRatio.Left(ptPos).c_str());
1407 fB = FXSYS_wtoi(wsWideNarrowRatio.Mid(ptPos + 1).c_str());
1408 if (fB)
1409 fRatio = (FX_FLOAT)fA / fB;
1410 }
1411 val = fRatio;
1412 return true;
1413 }
1414 return false;
1415 }
1416
GetPasswordChar(CFX_WideString & wsPassWord)1417 void CXFA_WidgetData::GetPasswordChar(CFX_WideString& wsPassWord) {
1418 CXFA_Node* pUIChild = GetUIChild();
1419 if (pUIChild) {
1420 pUIChild->TryCData(XFA_ATTRIBUTE_PasswordChar, wsPassWord);
1421 } else {
1422 wsPassWord = GetAttributeDefaultValue_Cdata(XFA_Element::PasswordEdit,
1423 XFA_ATTRIBUTE_PasswordChar,
1424 XFA_XDPPACKET_Form);
1425 }
1426 }
1427
IsMultiLine()1428 bool CXFA_WidgetData::IsMultiLine() {
1429 CXFA_Node* pUIChild = GetUIChild();
1430 if (pUIChild)
1431 return pUIChild->GetBoolean(XFA_ATTRIBUTE_MultiLine);
1432 return GetAttributeDefaultValue_Boolean(
1433 XFA_Element::TextEdit, XFA_ATTRIBUTE_MultiLine, XFA_XDPPACKET_Form);
1434 }
1435
GetVerticalScrollPolicy()1436 int32_t CXFA_WidgetData::GetVerticalScrollPolicy() {
1437 CXFA_Node* pUIChild = GetUIChild();
1438 if (pUIChild)
1439 return pUIChild->GetEnum(XFA_ATTRIBUTE_VScrollPolicy);
1440 return GetAttributeDefaultValue_Enum(
1441 XFA_Element::TextEdit, XFA_ATTRIBUTE_VScrollPolicy, XFA_XDPPACKET_Form);
1442 }
1443
GetMaxChars(XFA_Element & eType)1444 int32_t CXFA_WidgetData::GetMaxChars(XFA_Element& eType) {
1445 if (CXFA_Node* pNode = m_pNode->GetChild(0, XFA_Element::Value)) {
1446 if (CXFA_Node* pChild = pNode->GetNodeItem(XFA_NODEITEM_FirstChild)) {
1447 switch (pChild->GetElementType()) {
1448 case XFA_Element::Text:
1449 eType = XFA_Element::Text;
1450 return pChild->GetInteger(XFA_ATTRIBUTE_MaxChars);
1451 case XFA_Element::ExData: {
1452 eType = XFA_Element::ExData;
1453 int32_t iMax = pChild->GetInteger(XFA_ATTRIBUTE_MaxLength);
1454 return iMax < 0 ? 0 : iMax;
1455 }
1456 default:
1457 break;
1458 }
1459 }
1460 }
1461 return 0;
1462 }
1463
GetFracDigits(int32_t & iFracDigits)1464 bool CXFA_WidgetData::GetFracDigits(int32_t& iFracDigits) {
1465 if (CXFA_Node* pNode = m_pNode->GetChild(0, XFA_Element::Value)) {
1466 if (CXFA_Node* pChild = pNode->GetChild(0, XFA_Element::Decimal))
1467 return pChild->TryInteger(XFA_ATTRIBUTE_FracDigits, iFracDigits);
1468 }
1469 iFracDigits = -1;
1470 return false;
1471 }
1472
GetLeadDigits(int32_t & iLeadDigits)1473 bool CXFA_WidgetData::GetLeadDigits(int32_t& iLeadDigits) {
1474 if (CXFA_Node* pNode = m_pNode->GetChild(0, XFA_Element::Value)) {
1475 if (CXFA_Node* pChild = pNode->GetChild(0, XFA_Element::Decimal))
1476 return pChild->TryInteger(XFA_ATTRIBUTE_LeadDigits, iLeadDigits);
1477 }
1478 iLeadDigits = -1;
1479 return false;
1480 }
1481
SetValue(const CFX_WideString & wsValue,XFA_VALUEPICTURE eValueType)1482 bool CXFA_WidgetData::SetValue(const CFX_WideString& wsValue,
1483 XFA_VALUEPICTURE eValueType) {
1484 if (wsValue.IsEmpty()) {
1485 SyncValue(wsValue, true);
1486 return true;
1487 }
1488 m_bPreNull = m_bIsNull;
1489 m_bIsNull = false;
1490 CFX_WideString wsNewText(wsValue);
1491 CFX_WideString wsPicture;
1492 GetPictureContent(wsPicture, eValueType);
1493 bool bValidate = true;
1494 bool bSyncData = false;
1495 CXFA_Node* pNode = GetUIChild();
1496 if (!pNode)
1497 return true;
1498
1499 XFA_Element eType = pNode->GetElementType();
1500 if (!wsPicture.IsEmpty()) {
1501 CXFA_LocaleMgr* pLocalMgr = m_pNode->GetDocument()->GetLocalMgr();
1502 IFX_Locale* pLocale = GetLocal();
1503 CXFA_LocaleValue widgetValue = XFA_GetLocaleValue(this);
1504 bValidate =
1505 widgetValue.ValidateValue(wsValue, wsPicture, pLocale, &wsPicture);
1506 if (bValidate) {
1507 widgetValue = CXFA_LocaleValue(widgetValue.GetType(), wsNewText,
1508 wsPicture, pLocale, pLocalMgr);
1509 wsNewText = widgetValue.GetValue();
1510 if (eType == XFA_Element::NumericEdit) {
1511 int32_t iLeadDigits = 0;
1512 int32_t iFracDigits = 0;
1513 GetLeadDigits(iLeadDigits);
1514 GetFracDigits(iFracDigits);
1515 wsNewText = NumericLimit(wsNewText, iLeadDigits, iFracDigits);
1516 }
1517 bSyncData = true;
1518 }
1519 } else {
1520 if (eType == XFA_Element::NumericEdit) {
1521 if (wsNewText != L"0") {
1522 int32_t iLeadDigits = 0;
1523 int32_t iFracDigits = 0;
1524 GetLeadDigits(iLeadDigits);
1525 GetFracDigits(iFracDigits);
1526 wsNewText = NumericLimit(wsNewText, iLeadDigits, iFracDigits);
1527 }
1528 bSyncData = true;
1529 }
1530 }
1531 if (eType != XFA_Element::NumericEdit || bSyncData)
1532 SyncValue(wsNewText, true);
1533
1534 return bValidate;
1535 }
1536
GetPictureContent(CFX_WideString & wsPicture,XFA_VALUEPICTURE ePicture)1537 bool CXFA_WidgetData::GetPictureContent(CFX_WideString& wsPicture,
1538 XFA_VALUEPICTURE ePicture) {
1539 if (ePicture == XFA_VALUEPICTURE_Raw)
1540 return false;
1541
1542 CXFA_LocaleValue widgetValue = XFA_GetLocaleValue(this);
1543 switch (ePicture) {
1544 case XFA_VALUEPICTURE_Display: {
1545 if (CXFA_Node* pFormat = m_pNode->GetChild(0, XFA_Element::Format)) {
1546 if (CXFA_Node* pPicture = pFormat->GetChild(0, XFA_Element::Picture)) {
1547 if (pPicture->TryContent(wsPicture))
1548 return true;
1549 }
1550 }
1551 CFX_WideString wsDataPicture, wsTimePicture;
1552 IFX_Locale* pLocale = GetLocal();
1553 if (!pLocale)
1554 return false;
1555
1556 uint32_t dwType = widgetValue.GetType();
1557 switch (dwType) {
1558 case XFA_VT_DATE:
1559 pLocale->GetDatePattern(FX_LOCALEDATETIMESUBCATEGORY_Medium,
1560 wsPicture);
1561 break;
1562 case XFA_VT_TIME:
1563 pLocale->GetTimePattern(FX_LOCALEDATETIMESUBCATEGORY_Medium,
1564 wsPicture);
1565 break;
1566 case XFA_VT_DATETIME:
1567 pLocale->GetDatePattern(FX_LOCALEDATETIMESUBCATEGORY_Medium,
1568 wsDataPicture);
1569 pLocale->GetTimePattern(FX_LOCALEDATETIMESUBCATEGORY_Medium,
1570 wsTimePicture);
1571 wsPicture = wsDataPicture + L"T" + wsTimePicture;
1572 break;
1573 case XFA_VT_DECIMAL:
1574 case XFA_VT_FLOAT:
1575 break;
1576 default:
1577 break;
1578 }
1579 return true;
1580 }
1581
1582 case XFA_VALUEPICTURE_Edit: {
1583 CXFA_Node* pUI = m_pNode->GetChild(0, XFA_Element::Ui);
1584 if (pUI) {
1585 if (CXFA_Node* pPicture = pUI->GetChild(0, XFA_Element::Picture)) {
1586 if (pPicture->TryContent(wsPicture))
1587 return true;
1588 }
1589 }
1590 {
1591 CFX_WideString wsDataPicture, wsTimePicture;
1592 IFX_Locale* pLocale = GetLocal();
1593 if (!pLocale) {
1594 return false;
1595 }
1596 uint32_t dwType = widgetValue.GetType();
1597 switch (dwType) {
1598 case XFA_VT_DATE:
1599 pLocale->GetDatePattern(FX_LOCALEDATETIMESUBCATEGORY_Short,
1600 wsPicture);
1601 break;
1602 case XFA_VT_TIME:
1603 pLocale->GetTimePattern(FX_LOCALEDATETIMESUBCATEGORY_Short,
1604 wsPicture);
1605 break;
1606 case XFA_VT_DATETIME:
1607 pLocale->GetDatePattern(FX_LOCALEDATETIMESUBCATEGORY_Short,
1608 wsDataPicture);
1609 pLocale->GetTimePattern(FX_LOCALEDATETIMESUBCATEGORY_Short,
1610 wsTimePicture);
1611 wsPicture = wsDataPicture + L"T" + wsTimePicture;
1612 break;
1613 default:
1614 break;
1615 }
1616 }
1617 return true;
1618 }
1619 case XFA_VALUEPICTURE_DataBind: {
1620 if (CXFA_Bind bind = GetBind()) {
1621 bind.GetPicture(wsPicture);
1622 return true;
1623 }
1624 break;
1625 }
1626 default:
1627 break;
1628 }
1629 return false;
1630 }
1631
GetLocal()1632 IFX_Locale* CXFA_WidgetData::GetLocal() {
1633 if (!m_pNode)
1634 return nullptr;
1635
1636 CFX_WideString wsLocaleName;
1637 if (!m_pNode->GetLocaleName(wsLocaleName))
1638 return nullptr;
1639 if (wsLocaleName == L"ambient")
1640 return m_pNode->GetDocument()->GetLocalMgr()->GetDefLocale();
1641 return m_pNode->GetDocument()->GetLocalMgr()->GetLocaleByName(wsLocaleName);
1642 }
1643
GetValue(CFX_WideString & wsValue,XFA_VALUEPICTURE eValueType)1644 bool CXFA_WidgetData::GetValue(CFX_WideString& wsValue,
1645 XFA_VALUEPICTURE eValueType) {
1646 wsValue = m_pNode->GetContent();
1647
1648 if (eValueType == XFA_VALUEPICTURE_Display)
1649 GetItemLabel(wsValue.AsStringC(), wsValue);
1650
1651 CFX_WideString wsPicture;
1652 GetPictureContent(wsPicture, eValueType);
1653 CXFA_Node* pNode = GetUIChild();
1654 if (!pNode)
1655 return true;
1656
1657 switch (GetUIChild()->GetElementType()) {
1658 case XFA_Element::ChoiceList: {
1659 if (eValueType == XFA_VALUEPICTURE_Display) {
1660 int32_t iSelItemIndex = GetSelectedItem(0);
1661 if (iSelItemIndex >= 0) {
1662 GetChoiceListItem(wsValue, iSelItemIndex);
1663 wsPicture.clear();
1664 }
1665 }
1666 } break;
1667 case XFA_Element::NumericEdit:
1668 if (eValueType != XFA_VALUEPICTURE_Raw && wsPicture.IsEmpty()) {
1669 IFX_Locale* pLocale = GetLocal();
1670 if (eValueType == XFA_VALUEPICTURE_Display && pLocale) {
1671 CFX_WideString wsOutput;
1672 NormalizeNumStr(wsValue, wsOutput);
1673 FormatNumStr(wsOutput, pLocale, wsOutput);
1674 wsValue = wsOutput;
1675 }
1676 }
1677 break;
1678 default:
1679 break;
1680 }
1681 if (wsPicture.IsEmpty())
1682 return true;
1683
1684 if (IFX_Locale* pLocale = GetLocal()) {
1685 CXFA_LocaleValue widgetValue = XFA_GetLocaleValue(this);
1686 CXFA_LocaleMgr* pLocalMgr = m_pNode->GetDocument()->GetLocalMgr();
1687 switch (widgetValue.GetType()) {
1688 case XFA_VT_DATE: {
1689 CFX_WideString wsDate, wsTime;
1690 if (SplitDateTime(wsValue, wsDate, wsTime)) {
1691 CXFA_LocaleValue date(XFA_VT_DATE, wsDate, pLocalMgr);
1692 if (date.FormatPatterns(wsValue, wsPicture, pLocale, eValueType))
1693 return true;
1694 }
1695 break;
1696 }
1697 case XFA_VT_TIME: {
1698 CFX_WideString wsDate, wsTime;
1699 if (SplitDateTime(wsValue, wsDate, wsTime)) {
1700 CXFA_LocaleValue time(XFA_VT_TIME, wsTime, pLocalMgr);
1701 if (time.FormatPatterns(wsValue, wsPicture, pLocale, eValueType))
1702 return true;
1703 }
1704 break;
1705 }
1706 default:
1707 break;
1708 }
1709 widgetValue.FormatPatterns(wsValue, wsPicture, pLocale, eValueType);
1710 }
1711 return true;
1712 }
1713
GetNormalizeDataValue(const CFX_WideString & wsValue,CFX_WideString & wsNormalizeValue)1714 bool CXFA_WidgetData::GetNormalizeDataValue(const CFX_WideString& wsValue,
1715 CFX_WideString& wsNormalizeValue) {
1716 wsNormalizeValue = wsValue;
1717 if (wsValue.IsEmpty())
1718 return true;
1719
1720 CFX_WideString wsPicture;
1721 GetPictureContent(wsPicture, XFA_VALUEPICTURE_DataBind);
1722 if (wsPicture.IsEmpty())
1723 return true;
1724
1725 ASSERT(GetNode());
1726 CXFA_LocaleMgr* pLocalMgr = GetNode()->GetDocument()->GetLocalMgr();
1727 IFX_Locale* pLocale = GetLocal();
1728 CXFA_LocaleValue widgetValue = XFA_GetLocaleValue(this);
1729 if (widgetValue.ValidateValue(wsValue, wsPicture, pLocale, &wsPicture)) {
1730 widgetValue = CXFA_LocaleValue(widgetValue.GetType(), wsNormalizeValue,
1731 wsPicture, pLocale, pLocalMgr);
1732 wsNormalizeValue = widgetValue.GetValue();
1733 return true;
1734 }
1735 return false;
1736 }
1737
GetFormatDataValue(const CFX_WideString & wsValue,CFX_WideString & wsFormattedValue)1738 bool CXFA_WidgetData::GetFormatDataValue(const CFX_WideString& wsValue,
1739 CFX_WideString& wsFormattedValue) {
1740 wsFormattedValue = wsValue;
1741 if (wsValue.IsEmpty())
1742 return true;
1743
1744 CFX_WideString wsPicture;
1745 GetPictureContent(wsPicture, XFA_VALUEPICTURE_DataBind);
1746 if (wsPicture.IsEmpty())
1747 return true;
1748
1749 if (IFX_Locale* pLocale = GetLocal()) {
1750 ASSERT(GetNode());
1751 CXFA_Node* pNodeValue = GetNode()->GetChild(0, XFA_Element::Value);
1752 if (!pNodeValue)
1753 return false;
1754
1755 CXFA_Node* pValueChild = pNodeValue->GetNodeItem(XFA_NODEITEM_FirstChild);
1756 if (!pValueChild)
1757 return false;
1758
1759 int32_t iVTType = XFA_VT_NULL;
1760 switch (pValueChild->GetElementType()) {
1761 case XFA_Element::Decimal:
1762 iVTType = XFA_VT_DECIMAL;
1763 break;
1764 case XFA_Element::Float:
1765 iVTType = XFA_VT_FLOAT;
1766 break;
1767 case XFA_Element::Date:
1768 iVTType = XFA_VT_DATE;
1769 break;
1770 case XFA_Element::Time:
1771 iVTType = XFA_VT_TIME;
1772 break;
1773 case XFA_Element::DateTime:
1774 iVTType = XFA_VT_DATETIME;
1775 break;
1776 case XFA_Element::Boolean:
1777 iVTType = XFA_VT_BOOLEAN;
1778 break;
1779 case XFA_Element::Integer:
1780 iVTType = XFA_VT_INTEGER;
1781 break;
1782 case XFA_Element::Text:
1783 iVTType = XFA_VT_TEXT;
1784 break;
1785 default:
1786 iVTType = XFA_VT_NULL;
1787 break;
1788 }
1789 CXFA_LocaleMgr* pLocalMgr = GetNode()->GetDocument()->GetLocalMgr();
1790 CXFA_LocaleValue widgetValue(iVTType, wsValue, pLocalMgr);
1791 switch (widgetValue.GetType()) {
1792 case XFA_VT_DATE: {
1793 CFX_WideString wsDate, wsTime;
1794 if (SplitDateTime(wsValue, wsDate, wsTime)) {
1795 CXFA_LocaleValue date(XFA_VT_DATE, wsDate, pLocalMgr);
1796 if (date.FormatPatterns(wsFormattedValue, wsPicture, pLocale,
1797 XFA_VALUEPICTURE_DataBind)) {
1798 return true;
1799 }
1800 }
1801 break;
1802 }
1803 case XFA_VT_TIME: {
1804 CFX_WideString wsDate, wsTime;
1805 if (SplitDateTime(wsValue, wsDate, wsTime)) {
1806 CXFA_LocaleValue time(XFA_VT_TIME, wsTime, pLocalMgr);
1807 if (time.FormatPatterns(wsFormattedValue, wsPicture, pLocale,
1808 XFA_VALUEPICTURE_DataBind)) {
1809 return true;
1810 }
1811 }
1812 break;
1813 }
1814 default:
1815 break;
1816 }
1817 widgetValue.FormatPatterns(wsFormattedValue, wsPicture, pLocale,
1818 XFA_VALUEPICTURE_DataBind);
1819 }
1820 return false;
1821 }
1822
NormalizeNumStr(const CFX_WideString & wsValue,CFX_WideString & wsOutput)1823 void CXFA_WidgetData::NormalizeNumStr(const CFX_WideString& wsValue,
1824 CFX_WideString& wsOutput) {
1825 if (wsValue.IsEmpty())
1826 return;
1827
1828 wsOutput = wsValue;
1829 wsOutput.TrimLeft('0');
1830 int32_t dot_index = wsOutput.Find('.');
1831 int32_t iFracDigits = 0;
1832 if (!wsOutput.IsEmpty() && dot_index >= 0 &&
1833 (!GetFracDigits(iFracDigits) || iFracDigits != -1)) {
1834 wsOutput.TrimRight(L"0");
1835 wsOutput.TrimRight(L".");
1836 }
1837 if (wsOutput.IsEmpty() || wsOutput[0] == '.')
1838 wsOutput.Insert(0, '0');
1839 }
1840
FormatNumStr(const CFX_WideString & wsValue,IFX_Locale * pLocale,CFX_WideString & wsOutput)1841 void CXFA_WidgetData::FormatNumStr(const CFX_WideString& wsValue,
1842 IFX_Locale* pLocale,
1843 CFX_WideString& wsOutput) {
1844 if (wsValue.IsEmpty())
1845 return;
1846
1847 CFX_WideString wsSrcNum = wsValue;
1848 CFX_WideString wsGroupSymbol;
1849 pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_Grouping, wsGroupSymbol);
1850 bool bNeg = false;
1851 if (wsSrcNum[0] == '-') {
1852 bNeg = true;
1853 wsSrcNum.Delete(0, 1);
1854 }
1855 int32_t len = wsSrcNum.GetLength();
1856 int32_t dot_index = wsSrcNum.Find('.');
1857 if (dot_index == -1)
1858 dot_index = len;
1859
1860 int32_t cc = dot_index - 1;
1861 if (cc >= 0) {
1862 int nPos = dot_index % 3;
1863 wsOutput.clear();
1864 for (int32_t i = 0; i < dot_index; i++) {
1865 if (i % 3 == nPos && i != 0)
1866 wsOutput += wsGroupSymbol;
1867
1868 wsOutput += wsSrcNum[i];
1869 }
1870 if (dot_index < len) {
1871 CFX_WideString wsSymbol;
1872 pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_Decimal, wsSymbol);
1873 wsOutput += wsSymbol;
1874 wsOutput += wsSrcNum.Right(len - dot_index - 1);
1875 }
1876 if (bNeg) {
1877 CFX_WideString wsMinusymbol;
1878 pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_Minus, wsMinusymbol);
1879 wsOutput = wsMinusymbol + wsOutput;
1880 }
1881 }
1882 }
1883
SyncValue(const CFX_WideString & wsValue,bool bNotify)1884 void CXFA_WidgetData::SyncValue(const CFX_WideString& wsValue, bool bNotify) {
1885 if (!m_pNode)
1886 return;
1887
1888 CFX_WideString wsFormatValue(wsValue);
1889 CXFA_WidgetData* pContainerWidgetData = m_pNode->GetContainerWidgetData();
1890 if (pContainerWidgetData)
1891 pContainerWidgetData->GetFormatDataValue(wsValue, wsFormatValue);
1892
1893 m_pNode->SetContent(wsValue, wsFormatValue, bNotify);
1894 }
1895
InsertListTextItem(CXFA_Node * pItems,const CFX_WideString & wsText,int32_t nIndex)1896 void CXFA_WidgetData::InsertListTextItem(CXFA_Node* pItems,
1897 const CFX_WideString& wsText,
1898 int32_t nIndex) {
1899 CXFA_Node* pText = pItems->CreateSamePacketNode(XFA_Element::Text);
1900 pItems->InsertChild(nIndex, pText);
1901 pText->SetContent(wsText, wsText, false, false, false);
1902 }
1903
NumericLimit(const CFX_WideString & wsValue,int32_t iLead,int32_t iTread) const1904 CFX_WideString CXFA_WidgetData::NumericLimit(const CFX_WideString& wsValue,
1905 int32_t iLead,
1906 int32_t iTread) const {
1907 if ((iLead == -1) && (iTread == -1))
1908 return wsValue;
1909
1910 CFX_WideString wsRet;
1911 int32_t iLead_ = 0, iTread_ = -1;
1912 int32_t iCount = wsValue.GetLength();
1913 if (iCount == 0)
1914 return wsValue;
1915
1916 int32_t i = 0;
1917 if (wsValue[i] == L'-') {
1918 wsRet += L'-';
1919 i++;
1920 }
1921 for (; i < iCount; i++) {
1922 FX_WCHAR wc = wsValue[i];
1923 if (FXSYS_isDecimalDigit(wc)) {
1924 if (iLead >= 0) {
1925 iLead_++;
1926 if (iLead_ > iLead)
1927 return L"0";
1928 } else if (iTread_ >= 0) {
1929 iTread_++;
1930 if (iTread_ > iTread) {
1931 if (iTread != -1) {
1932 CFX_Decimal wsDeci = CFX_Decimal(wsValue.AsStringC());
1933 wsDeci.SetScale(iTread);
1934 wsRet = wsDeci;
1935 }
1936 return wsRet;
1937 }
1938 }
1939 } else if (wc == L'.') {
1940 iTread_ = 0;
1941 iLead = -1;
1942 }
1943 wsRet += wc;
1944 }
1945 return wsRet;
1946 }
1947