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