Merge XFA to PDFium master at 4dc95e7 on 10/28/2014
[pdfium.git] / xfa / src / fxfa / src / parser / xfa_document_datamerger_imp.cpp
1 // Copyright 2014 PDFium Authors. All rights reserved.\r
2 // Use of this source code is governed by a BSD-style license that can be\r
3 // found in the LICENSE file.\r
4 \r
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com\r
6 \r
7 #include "../../../foxitlib.h"\r
8 #include "../common/xfa_utils.h"\r
9 #include "../common/xfa_object.h"\r
10 #include "../common/xfa_document.h"\r
11 #include "../common/xfa_parser.h"\r
12 #include "../common/xfa_script.h"\r
13 #include "../common/xfa_docdata.h"\r
14 #include "../common/xfa_doclayout.h"\r
15 #include "../common/xfa_debug.h"\r
16 #include "../common/xfa_localemgr.h"\r
17 #include "../common/xfa_fm2jsapi.h"\r
18 #include "xfa_debug_parser.h"\r
19 #include "xfa_basic_imp.h"\r
20 #include "xfa_document_imp.h"\r
21 #include "xfa_document_datadescription_imp.h"\r
22 #include "xfa_document_datamerger_imp.h"\r
23 #include "xfa_document_layout_imp.h"\r
24 static FX_BOOL XFA_GetOccurInfo(CXFA_Node* pOccurNode, FX_INT32& iMin, FX_INT32& iMax, FX_INT32& iInit)\r
25 {\r
26     if(!pOccurNode) {\r
27         return FALSE;\r
28     }\r
29     CXFA_Occur occur(pOccurNode);\r
30     return occur.GetOccurInfo(iMin, iMax, iInit);\r
31 }\r
32 struct XFA_DataMerge_RecurseRecord {\r
33     CXFA_Node *pTemplateChild;\r
34     CXFA_Node *pDataChild;\r
35 };\r
36 static CXFA_Node* XFA_DataMerge_FormValueNode_CreateChild(CXFA_Node* pValueNode, XFA_ELEMENT iType = XFA_ELEMENT_UNKNOWN)\r
37 {\r
38     CXFA_Node * pChildNode = pValueNode->GetNodeItem(XFA_NODEITEM_FirstChild);\r
39     if (!pChildNode) {\r
40         if (iType == XFA_ELEMENT_UNKNOWN) {\r
41             return FALSE;\r
42         }\r
43         pChildNode = pValueNode->GetProperty(0, iType);\r
44     }\r
45     return pChildNode;\r
46 }\r
47 static void XFA_DataMerge_FormValueNode_MatchNoneCreateChild(CXFA_Node* pFormNode)\r
48 {\r
49     CXFA_WidgetData* pWidgetData = pFormNode->GetWidgetData();\r
50     FXSYS_assert(pWidgetData);\r
51     XFA_ELEMENT eUIType = pWidgetData->GetUIType();\r
52 }\r
53 static FX_BOOL XFA_DataMerge_FormValueNode_SetChildContent(CXFA_Node* pValueNode, const CFX_WideString& wsContent, XFA_ELEMENT iType = XFA_ELEMENT_UNKNOWN)\r
54 {\r
55     if (!pValueNode) {\r
56         return FALSE;\r
57     }\r
58     FXSYS_assert(pValueNode->GetPacketID() == XFA_XDPPACKET_Form);\r
59     CXFA_Node* pChildNode = XFA_DataMerge_FormValueNode_CreateChild(pValueNode, iType);\r
60     if (!pChildNode) {\r
61         return FALSE;\r
62     }\r
63     XFA_OBJECTTYPE objectType = pChildNode->GetObjectType();\r
64     switch (objectType) {\r
65         case XFA_OBJECTTYPE_ContentNode: {\r
66                 CXFA_Node *pContentRawDataNode = pChildNode->GetNodeItem(XFA_NODEITEM_FirstChild);\r
67                 if (!pContentRawDataNode) {\r
68                     XFA_ELEMENT element = XFA_ELEMENT_Sharptext;\r
69                     if (pChildNode->GetClassID() == XFA_ELEMENT_ExData) {\r
70                         CFX_WideString wsContentType;\r
71                         pChildNode->GetAttribute(XFA_ATTRIBUTE_ContentType, wsContentType, FALSE);\r
72                         if (wsContentType.Equal(FX_WSTRC(L"text/html"))) {\r
73                             element = XFA_ELEMENT_SharpxHTML;\r
74                         } else if (wsContentType.Equal(FX_WSTRC(L"text/xml"))) {\r
75                             element = XFA_ELEMENT_Sharpxml;\r
76                         }\r
77                     }\r
78                     pContentRawDataNode = pChildNode->CreateSamePacketNode(element);\r
79                     pChildNode->InsertChild(pContentRawDataNode);\r
80                 }\r
81                 pContentRawDataNode->SetCData(XFA_ATTRIBUTE_Value, wsContent);\r
82             }\r
83             break;\r
84         case XFA_OBJECTTYPE_NodeC:\r
85         case XFA_OBJECTTYPE_TextNode:\r
86         case XFA_OBJECTTYPE_NodeV: {\r
87                 pChildNode->SetCData(XFA_ATTRIBUTE_Value, wsContent);\r
88             }\r
89             break;\r
90         default:\r
91             FXSYS_assert(FALSE);\r
92             break;\r
93     }\r
94     return TRUE;\r
95 }\r
96 static void XFA_DataMerge_CreateDataBinding(CXFA_Node* pFormNode, CXFA_Node* pDataNode, FX_BOOL bDataToForm = TRUE)\r
97 {\r
98     pFormNode->SetObject(XFA_ATTRIBUTE_BindingNode, pDataNode);\r
99     pDataNode->AddBindItem(pFormNode);\r
100     XFA_ELEMENT eClass = pFormNode->GetClassID();\r
101     if (eClass != XFA_ELEMENT_Field && eClass != XFA_ELEMENT_ExclGroup) {\r
102         return;\r
103     }\r
104     CXFA_WidgetData* pWidgetData = pFormNode->GetWidgetData();\r
105     FXSYS_assert(pWidgetData);\r
106     FX_BOOL bNotify = FALSE;\r
107     XFA_ELEMENT eUIType = pWidgetData->GetUIType();\r
108     CXFA_Value defValue = pFormNode->GetProperty(0, XFA_ELEMENT_Value);\r
109     if(!bDataToForm) {\r
110         CFX_WideString wsValue;\r
111         CFX_WideString wsFormatedValue;\r
112         switch (eUIType) {\r
113             case XFA_ELEMENT_ImageEdit: {\r
114                     CXFA_Image image = defValue.GetImage();\r
115                     CFX_WideString wsContentType;\r
116                     CFX_WideString wsHref;\r
117                     if (image) {\r
118                         image.GetContent(wsValue);\r
119                         image.GetContentType(wsContentType);\r
120                         image.GetHref(wsHref);\r
121                     }\r
122                     IFDE_XMLElement *pXMLDataElement = (IFDE_XMLElement *)(pDataNode->GetXMLMappingNode());\r
123                     FXSYS_assert(pXMLDataElement);\r
124                     pWidgetData->GetFormatDataValue(wsValue, wsFormatedValue);\r
125                     pDataNode->SetAttributeValue(wsValue, wsFormatedValue);\r
126                     pDataNode->SetCData(XFA_ATTRIBUTE_ContentType, wsContentType);\r
127                     if (!wsHref.IsEmpty()) {\r
128                         pXMLDataElement->SetString(FX_WSTRC(L"href"), wsHref);\r
129                     }\r
130                 }\r
131                 break;\r
132             case XFA_ELEMENT_ChoiceList:\r
133                 defValue.GetChildValueContent(wsValue);\r
134                 if (pWidgetData->GetChoiceListOpen() == XFA_ATTRIBUTEENUM_MultiSelect) {\r
135                     CFX_WideStringArray wsSelTextArray;\r
136                     pWidgetData->GetSelectedItemsValue(wsSelTextArray);\r
137                     FX_INT32 iSize = wsSelTextArray.GetSize();\r
138                     if (iSize >= 1) {\r
139                         CXFA_Node *pValue = NULL;\r
140                         IFDE_XMLNode *pValueXMLNode = NULL;\r
141                         for (FX_INT32 i = 0; i < iSize; i++) {\r
142                             pValue = pDataNode->CreateSamePacketNode(XFA_ELEMENT_DataValue);\r
143                             pValue->SetCData(XFA_ATTRIBUTE_Name, FX_WSTRC(L"value"));\r
144                             pValueXMLNode = pValue->CreateXMLMappingNode();\r
145                             pDataNode->InsertChild(pValue);\r
146                             pValue->SetCData(XFA_ATTRIBUTE_Value, wsSelTextArray[i]);\r
147                         }\r
148                     } else {\r
149                         IFDE_XMLNode *pXMLNode = pDataNode->GetXMLMappingNode();\r
150                         FXSYS_assert(pXMLNode->GetType() == FDE_XMLNODE_Element);\r
151                         ((IFDE_XMLElement *)pXMLNode)->SetString(FX_WSTRC(L"xfa:dataNode"), FX_WSTRC(L"dataGroup"));\r
152                     }\r
153                 } else if (!wsValue.IsEmpty()) {\r
154                     pWidgetData->GetFormatDataValue(wsValue, wsFormatedValue);\r
155                     pDataNode->SetAttributeValue(wsValue, wsFormatedValue);\r
156                 }\r
157                 break;\r
158             case XFA_ELEMENT_CheckButton:\r
159                 defValue.GetChildValueContent(wsValue);\r
160                 if (wsValue.IsEmpty()) {\r
161                     break;\r
162                 }\r
163                 pWidgetData->GetFormatDataValue(wsValue, wsFormatedValue);\r
164                 pDataNode->SetAttributeValue(wsValue, wsFormatedValue);\r
165                 break;\r
166             case XFA_ELEMENT_ExclGroup: {\r
167                     CXFA_Node* pChecked = NULL;\r
168                     XFA_ELEMENT eValueType = XFA_ELEMENT_UNKNOWN;\r
169                     CXFA_Node* pChild = pFormNode->GetNodeItem(XFA_NODEITEM_FirstChild);\r
170                     for ( ; pChild; pChild = pChild->GetNodeItem(XFA_NODEITEM_NextSibling)) {\r
171                         if (pChild->GetClassID() != XFA_ELEMENT_Field) {\r
172                             continue;\r
173                         }\r
174                         CXFA_Node* pValue = pChild->GetChild(0, XFA_ELEMENT_Value);\r
175                         if (!pValue) {\r
176                             continue;\r
177                         }\r
178                         CXFA_Value valueChild(pValue);\r
179                         valueChild.GetChildValueContent(wsValue);\r
180                         if (wsValue.IsEmpty()) {\r
181                             continue;\r
182                         }\r
183                         CXFA_Node* pItems = pChild->GetChild(0, XFA_ELEMENT_Items);\r
184                         if (!pItems) {\r
185                             continue;\r
186                         }\r
187                         CXFA_Node* pText = pItems->GetNodeItem(XFA_NODEITEM_FirstChild);\r
188                         if (!pText) {\r
189                             continue;\r
190                         }\r
191                         CFX_WideString wsContent;\r
192                         if (pText->TryContent(wsContent) && (wsContent == wsValue)) {\r
193                             pChecked = pChild;\r
194                             eValueType = pText->GetClassID();\r
195                             wsFormatedValue = wsValue;\r
196                             pDataNode->SetAttributeValue(wsValue, wsFormatedValue);\r
197                             pFormNode->SetCData(XFA_ATTRIBUTE_Value, wsContent);\r
198                             break;\r
199                         }\r
200                     }\r
201                     if (!pChecked) {\r
202                         break;\r
203                     }\r
204                     pChild = pFormNode->GetNodeItem(XFA_NODEITEM_FirstChild);\r
205                     for ( ; pChild; pChild = pChild->GetNodeItem(XFA_NODEITEM_NextSibling)) {\r
206                         if (pChild == pChecked) {\r
207                             continue;\r
208                         }\r
209                         if (pChild->GetClassID() != XFA_ELEMENT_Field) {\r
210                             continue;\r
211                         }\r
212                         CXFA_Node* pValue = pChild->GetProperty(0, XFA_ELEMENT_Value);\r
213                         CXFA_Node* pItems = pChild->GetChild(0, XFA_ELEMENT_Items);\r
214                         CXFA_Node* pText = pItems ? pItems->GetNodeItem(XFA_NODEITEM_FirstChild) : NULL;\r
215                         if (pText) {\r
216                             pText = pText->GetNodeItem(XFA_NODEITEM_NextSibling);\r
217                         }\r
218                         CFX_WideString wsContent;\r
219                         if (pText) {\r
220                             pText->TryContent(wsContent);\r
221                         }\r
222                         XFA_DataMerge_FormValueNode_SetChildContent(pValue, wsContent, XFA_ELEMENT_Text);\r
223                     }\r
224                 }\r
225                 break;\r
226             case XFA_ELEMENT_NumericEdit: {\r
227                     defValue.GetChildValueContent(wsValue);\r
228                     if (wsValue.IsEmpty()) {\r
229                         break;\r
230                     }\r
231                     CFX_WideString wsOutput;\r
232                     pWidgetData->NormalizeNumStr(wsValue, wsOutput);\r
233                     wsValue = wsOutput;\r
234                     pWidgetData->GetFormatDataValue(wsValue, wsFormatedValue);\r
235                     pDataNode->SetAttributeValue(wsValue, wsFormatedValue);\r
236                     CXFA_Node* pValue = pFormNode->GetProperty(0, XFA_ELEMENT_Value);\r
237                     XFA_DataMerge_FormValueNode_SetChildContent(pValue, wsValue, XFA_ELEMENT_Float);\r
238                 }\r
239                 break;\r
240             default:\r
241                 defValue.GetChildValueContent(wsValue);\r
242                 if (wsValue.IsEmpty()) {\r
243                     break;\r
244                 }\r
245                 pWidgetData->GetFormatDataValue(wsValue, wsFormatedValue);\r
246                 pDataNode->SetAttributeValue(wsValue, wsFormatedValue);\r
247                 break;\r
248         }\r
249     } else {\r
250         CFX_WideString wsXMLValue;\r
251         pDataNode->TryContent(wsXMLValue);\r
252         CFX_WideString wsNormailizeValue;\r
253         pWidgetData->GetNormalizeDataValue(wsXMLValue, wsNormailizeValue);\r
254         pDataNode->SetAttributeValue(wsNormailizeValue, wsXMLValue);\r
255         switch (eUIType) {\r
256             case XFA_ELEMENT_ImageEdit: {\r
257                     XFA_DataMerge_FormValueNode_SetChildContent(defValue.GetNode(), wsNormailizeValue, XFA_ELEMENT_Image);\r
258                     CXFA_Image image = defValue.GetImage();\r
259                     if (image) {\r
260                         IFDE_XMLElement *pXMLDataElement = (IFDE_XMLElement *)(pDataNode->GetXMLMappingNode());\r
261                         FXSYS_assert(pXMLDataElement);\r
262                         CFX_WideString wsContentType;\r
263                         CFX_WideString wsHref;\r
264                         pXMLDataElement->GetString((FX_LPCWSTR)L"xfa:contentType", wsContentType);\r
265                         if (!wsContentType.IsEmpty()) {\r
266                             pDataNode->SetCData(XFA_ATTRIBUTE_ContentType, wsContentType);\r
267                             image.SetContentType(wsContentType);\r
268                         }\r
269                         pXMLDataElement->GetString((FX_LPCWSTR)L"href", wsHref);\r
270                         if (!wsHref.IsEmpty()) {\r
271                             image.SetHref(wsHref);\r
272                         }\r
273                     }\r
274                 }\r
275                 break;\r
276             case XFA_ELEMENT_ChoiceList:\r
277                 if (pWidgetData->GetChoiceListOpen() == XFA_ATTRIBUTEENUM_MultiSelect) {\r
278                     CXFA_NodeArray items;\r
279                     pDataNode->GetNodeList(items);\r
280                     FX_INT32 iCounts = items.GetSize();\r
281                     if (iCounts > 0) {\r
282                         wsNormailizeValue.Empty();\r
283                         CFX_WideString wsItem;\r
284                         for (FX_INT32 i = 0; i < iCounts; i++) {\r
285                             items[i]->TryContent(wsItem);\r
286                             wsItem = (iCounts == 1) ? wsItem : wsItem + FX_WSTRC(L"\n");\r
287                             wsNormailizeValue += wsItem;\r
288                         }\r
289                         CXFA_ExData exData = defValue.GetExData();\r
290                         FXSYS_assert(exData != NULL);\r
291                         exData.SetContentType((iCounts == 1) ? FX_WSTRC(L"text/plain") : FX_WSTRC(L"text/xml"));\r
292                     }\r
293                     XFA_DataMerge_FormValueNode_SetChildContent(defValue.GetNode(), wsNormailizeValue, XFA_ELEMENT_ExData);\r
294                 } else {\r
295                     XFA_DataMerge_FormValueNode_SetChildContent(defValue.GetNode(), wsNormailizeValue, XFA_ELEMENT_Text);\r
296                 }\r
297                 break;\r
298             case XFA_ELEMENT_CheckButton:\r
299                 XFA_DataMerge_FormValueNode_SetChildContent(defValue.GetNode(), wsNormailizeValue, XFA_ELEMENT_Text);\r
300                 break;\r
301             case XFA_ELEMENT_ExclGroup: {\r
302                     pWidgetData->SetSelectedMemberByValue(wsNormailizeValue, bNotify, FALSE, FALSE);\r
303                 }\r
304                 break;\r
305             case XFA_ELEMENT_DateTimeEdit:\r
306                 XFA_DataMerge_FormValueNode_SetChildContent(defValue.GetNode(), wsNormailizeValue, XFA_ELEMENT_DateTime);\r
307                 break;\r
308             case XFA_ELEMENT_NumericEdit: {\r
309                     CFX_WideString wsPicture;\r
310                     pWidgetData->GetPictureContent(wsPicture, XFA_VALUEPICTURE_DataBind);\r
311                     if(wsPicture.IsEmpty()) {\r
312                         CFX_WideString wsOutput;\r
313                         pWidgetData->NormalizeNumStr(wsNormailizeValue, wsOutput);\r
314                         wsNormailizeValue = wsOutput;\r
315                     }\r
316                     XFA_DataMerge_FormValueNode_SetChildContent(defValue.GetNode(), wsNormailizeValue, XFA_ELEMENT_Float);\r
317                 }\r
318                 break;\r
319             case XFA_ELEMENT_Barcode:\r
320             case XFA_ELEMENT_Button:\r
321             case XFA_ELEMENT_PasswordEdit:\r
322             case XFA_ELEMENT_Signature:\r
323             case XFA_ELEMENT_TextEdit:\r
324             default:\r
325                 XFA_DataMerge_FormValueNode_SetChildContent(defValue.GetNode(), wsNormailizeValue, XFA_ELEMENT_Text);\r
326                 break;\r
327         }\r
328     }\r
329 }\r
330 static CXFA_Node* XFA_DataMerge_GetGlobalBinding(CXFA_Document* pDocument, FX_DWORD dwNameHash)\r
331 {\r
332     CXFA_Node* pNode = NULL;\r
333     pDocument->m_rgGlobalBinding.Lookup(dwNameHash, pNode);\r
334     return pNode;\r
335 }\r
336 static void XFA_DataMerge_RegisterGlobalBinding(CXFA_Document* pDocument, FX_DWORD dwNameHash, CXFA_Node* pDataNode)\r
337 {\r
338     pDocument->m_rgGlobalBinding.SetAt(dwNameHash, pDataNode);\r
339 }\r
340 static void XFA_DataMerge_ClearGlobalBinding(CXFA_Document* pDocument)\r
341 {\r
342     pDocument->m_rgGlobalBinding.RemoveAll();\r
343 }\r
344 static CXFA_Node* XFA_DataMerge_ScopeMatchGlobalBinding(CXFA_Node* pDataScope, FX_DWORD dwNameHash, XFA_ELEMENT eMatchDataNodeType, FX_BOOL bUpLevel = TRUE)\r
345 {\r
346     for(CXFA_Node *pCurDataScope = pDataScope, *pLastDataScope = NULL;\r
347             pCurDataScope && pCurDataScope->GetPacketID() == XFA_XDPPACKET_Datasets;\r
348             pLastDataScope = pCurDataScope, pCurDataScope = pCurDataScope->GetNodeItem(XFA_NODEITEM_Parent)) {\r
349         for(CXFA_Node* pDataChild = pCurDataScope->GetFirstChildByName(dwNameHash); pDataChild; pDataChild = pDataChild->GetNextSameNameSibling(dwNameHash)) {\r
350             if(pDataChild == pLastDataScope || (eMatchDataNodeType != XFA_ELEMENT_DataModel && pDataChild->GetClassID() != eMatchDataNodeType) || pDataChild->HasBindItem()) {\r
351                 continue;\r
352             }\r
353             return pDataChild;\r
354         }\r
355         for(CXFA_Node* pDataChild = pCurDataScope->GetFirstChildByClass(XFA_ELEMENT_DataGroup); pDataChild; pDataChild = pDataChild->GetNextSameClassSibling(XFA_ELEMENT_DataGroup)) {\r
356             CXFA_Node* pDataNode = XFA_DataMerge_ScopeMatchGlobalBinding(pDataChild, dwNameHash, eMatchDataNodeType, FALSE);\r
357             if(pDataNode)       {\r
358                 return pDataNode;\r
359             }\r
360         }\r
361         if(!bUpLevel) {\r
362             break;\r
363         }\r
364     }\r
365     return NULL;\r
366 }\r
367 static CXFA_Node* XFA_DataMerge_FindGlobalDataNode(CXFA_Document* pDocument, CFX_WideStringC wsName, CXFA_Node* pDataScope, XFA_ELEMENT eMatchNodeType)\r
368 {\r
369     FX_DWORD dwNameHash = wsName.IsEmpty() ? 0 : FX_HashCode_String_GetW(wsName.GetPtr(), wsName.GetLength());\r
370     if (dwNameHash != 0) {\r
371         CXFA_Node *pBounded = XFA_DataMerge_GetGlobalBinding(pDocument, dwNameHash);\r
372         if(!pBounded) {\r
373             pBounded = XFA_DataMerge_ScopeMatchGlobalBinding(pDataScope, dwNameHash, eMatchNodeType);\r
374             if(pBounded) {\r
375                 XFA_DataMerge_RegisterGlobalBinding(pDocument, dwNameHash, pBounded);\r
376             }\r
377         }\r
378         return pBounded;\r
379     }\r
380     return NULL;\r
381 }\r
382 static CXFA_Node* XFA_DataMerge_FindOnceDataNode(CXFA_Document* pDocument, CFX_WideStringC wsName, CXFA_Node* pDataScope, XFA_ELEMENT eMatchNodeType)\r
383 {\r
384     FX_DWORD dwNameHash = wsName.IsEmpty() ? 0 : FX_HashCode_String_GetW(wsName.GetPtr(), wsName.GetLength());\r
385     if (dwNameHash != 0) {\r
386         for(CXFA_Node *pCurDataScope = pDataScope, *pLastDataScope = NULL;\r
387                 pCurDataScope && pCurDataScope->GetPacketID() == XFA_XDPPACKET_Datasets;\r
388                 pLastDataScope = pCurDataScope, pCurDataScope = pCurDataScope->GetNodeItem(XFA_NODEITEM_Parent)) {\r
389             for(CXFA_Node* pDataChild = pCurDataScope->GetFirstChildByName(dwNameHash); pDataChild; pDataChild = pDataChild->GetNextSameNameSibling(dwNameHash)) {\r
390                 if(pDataChild == pLastDataScope || (eMatchNodeType != XFA_ELEMENT_DataModel && pDataChild->GetClassID() != eMatchNodeType) || pDataChild->HasBindItem()) {\r
391                     continue;\r
392                 }\r
393                 return pDataChild;\r
394             }\r
395         }\r
396     }\r
397     return NULL;\r
398 }\r
399 static CXFA_Node* XFA_DataMerge_FindDataRefDataNode(CXFA_Document* pDocument, CFX_WideStringC wsRef, CXFA_Node* pDataScope, XFA_ELEMENT eMatchNodeType, CXFA_Node* pTemplateNode, FX_BOOL bForceBind, FX_BOOL bUpLevel = TRUE)\r
400 {\r
401     FX_DWORD dFlags = XFA_RESOLVENODE_Children | XFA_RESOLVENODE_BindNew;\r
402     if (bUpLevel || wsRef != FX_WSTRC(L"name")) {\r
403         dFlags |= (XFA_RESOLVENODE_Parent | XFA_RESOLVENODE_Siblings);\r
404     }\r
405     XFA_RESOLVENODE_RS rs;\r
406     pDocument->GetScriptContext()->ResolveObjects(pDataScope, wsRef, rs, dFlags, pTemplateNode);\r
407     if (rs.dwFlags == XFA_RESOLVENODE_RSTYPE_CreateNodeAll || rs.dwFlags == XFA_RESOLVENODE_RSTYPE_CreateNodeMidAll || rs.nodes.GetSize() > 1) {\r
408         return pDocument->GetNotBindNode(rs.nodes);\r
409     } else if (rs.dwFlags == XFA_RESOLVENODE_RSTYPE_CreateNodeOne) {\r
410         CXFA_Object* pObject = (rs.nodes.GetSize() > 0) ? rs.nodes[0] : NULL;\r
411         CXFA_Node *pNode = (pObject && pObject->IsNode()) ? (CXFA_Node*)pObject : NULL;\r
412         if (!bForceBind && (pNode != NULL) && pNode->HasBindItem()) {\r
413             pNode = NULL;\r
414         }\r
415         return pNode;\r
416     }\r
417     return NULL;\r
418 }\r
419 CXFA_Node* XFA_DataMerge_FindFormDOMInstance(CXFA_Document* pDocument, XFA_ELEMENT eClassID, FX_DWORD dwNameHash, CXFA_Node* pFormParent)\r
420 {\r
421     CXFA_Node* pFormChild = pFormParent->GetNodeItem(XFA_NODEITEM_FirstChild);\r
422     for(; pFormChild; pFormChild = pFormChild->GetNodeItem(XFA_NODEITEM_NextSibling)) {\r
423         if(pFormChild->GetClassID() == eClassID && pFormChild->GetNameHash() == dwNameHash && pFormChild->HasFlag(XFA_NODEFLAG_UnusedNode)) {\r
424             return pFormChild;\r
425         }\r
426     }\r
427     return NULL;\r
428 }\r
429 static FX_BOOL XFA_NeedGenerateForm(CXFA_Node* pTemplateChild, FX_BOOL bUseInstanceManager = TRUE)\r
430 {\r
431     XFA_ELEMENT eType = pTemplateChild->GetClassID();\r
432     if (eType == XFA_ELEMENT_Variables) {\r
433         return TRUE;\r
434     }\r
435     if(pTemplateChild->GetObjectType() == XFA_OBJECTTYPE_ContainerNode) {\r
436         return FALSE;\r
437     }\r
438     if (eType == XFA_ELEMENT_Proto || (bUseInstanceManager && eType == XFA_ELEMENT_Occur)) {\r
439         return FALSE;\r
440     }\r
441     return TRUE;\r
442 }\r
443 CXFA_Node* XFA_NodeMerge_CloneOrMergeContainer(CXFA_Document* pDocument, CXFA_Node* pFormParent, CXFA_Node* pTemplateNode, FX_BOOL bRecursive, CXFA_NodeArray* pSubformArray)\r
444 {\r
445     CXFA_Node* pExistingNode = NULL;\r
446     if (pSubformArray == NULL) {\r
447         pExistingNode = XFA_DataMerge_FindFormDOMInstance(pDocument, pTemplateNode->GetClassID(), pTemplateNode->GetNameHash(), pFormParent);\r
448     } else if (pSubformArray->GetSize() > 0) {\r
449         pExistingNode = pSubformArray->GetAt(0);\r
450         pSubformArray->RemoveAt(0);\r
451     }\r
452     if(pExistingNode) {\r
453         if (pSubformArray) {\r
454             pFormParent->InsertChild(pExistingNode);\r
455         } else if (pExistingNode->IsContainerNode()) {\r
456             pFormParent->RemoveChild(pExistingNode);\r
457             pFormParent->InsertChild(pExistingNode);\r
458         }\r
459         pExistingNode->SetFlag(XFA_NODEFLAG_UnusedNode, FALSE);\r
460         pExistingNode->SetTemplateNode(pTemplateNode);\r
461         if(bRecursive && pExistingNode->GetClassID() != XFA_ELEMENT_Items) {\r
462             for (CXFA_Node *pTemplateChild = pTemplateNode->GetNodeItem(XFA_NODEITEM_FirstChild); pTemplateChild; pTemplateChild = pTemplateChild->GetNodeItem(XFA_NODEITEM_NextSibling)) {\r
463                 if(XFA_NeedGenerateForm(pTemplateChild)) {\r
464                     XFA_NodeMerge_CloneOrMergeContainer(pDocument, pExistingNode, pTemplateChild, bRecursive);\r
465                 }\r
466             }\r
467         }\r
468         pExistingNode->SetFlag(XFA_NODEFLAG_Initialized);\r
469         return pExistingNode;\r
470     }\r
471     CXFA_Node* pNewNode = pTemplateNode->CloneTemplateToForm(FALSE);\r
472     pFormParent->InsertChild(pNewNode, NULL);\r
473     if(bRecursive) {\r
474         for (CXFA_Node *pTemplateChild = pTemplateNode->GetNodeItem(XFA_NODEITEM_FirstChild); pTemplateChild; pTemplateChild = pTemplateChild->GetNodeItem(XFA_NODEITEM_NextSibling)) {\r
475             if(XFA_NeedGenerateForm(pTemplateChild)) {\r
476                 CXFA_Node* pNewChild = pTemplateChild->CloneTemplateToForm(TRUE);\r
477                 pNewNode->InsertChild(pNewChild, NULL);\r
478             }\r
479         }\r
480     }\r
481     return pNewNode;\r
482 }\r
483 static CXFA_Node* XFA_NodeMerge_CloneOrMergeInstanceManager(CXFA_Document* pDocument, CXFA_Node* pFormParent, CXFA_Node* pTemplateNode, CXFA_NodeArray& subforms)\r
484 {\r
485     CFX_WideStringC wsSubformName = pTemplateNode->GetCData(XFA_ATTRIBUTE_Name);\r
486     CFX_WideString wsInstMgrNodeName = FX_WSTRC(L"_") + wsSubformName;\r
487     FX_DWORD dwInstNameHash = FX_HashCode_String_GetW(wsInstMgrNodeName, wsInstMgrNodeName.GetLength());\r
488     CXFA_Node* pExistingNode = XFA_DataMerge_FindFormDOMInstance(pDocument, XFA_ELEMENT_InstanceManager, dwInstNameHash, pFormParent);\r
489     if(pExistingNode) {\r
490         FX_DWORD dwNameHash = pTemplateNode->GetNameHash();\r
491         for(CXFA_Node* pNode = pExistingNode->GetNodeItem(XFA_NODEITEM_NextSibling); pNode; ) {\r
492             XFA_ELEMENT eCurType = pNode->GetClassID();\r
493             if (eCurType == XFA_ELEMENT_InstanceManager) {\r
494                 break;\r
495             }\r
496             if ((eCurType != XFA_ELEMENT_Subform) && (eCurType != XFA_ELEMENT_SubformSet)) {\r
497                 pNode = pNode->GetNodeItem(XFA_NODEITEM_NextSibling);\r
498                 continue;\r
499             }\r
500             if (dwNameHash != pNode->GetNameHash()) {\r
501                 break;\r
502             }\r
503             CXFA_Node* pNextNode = pNode->GetNodeItem(XFA_NODEITEM_NextSibling);\r
504             pFormParent->RemoveChild(pNode);\r
505             subforms.Add(pNode);\r
506             pNode = pNextNode;\r
507         }\r
508         pFormParent->RemoveChild(pExistingNode);\r
509         pFormParent->InsertChild(pExistingNode);\r
510         pExistingNode->SetFlag(XFA_NODEFLAG_UnusedNode, FALSE);\r
511         pExistingNode->SetTemplateNode(pTemplateNode);\r
512         return pExistingNode;\r
513     }\r
514     CXFA_Node* pNewNode = pDocument->GetParser()->GetFactory()->CreateNode(XFA_XDPPACKET_Form, XFA_ELEMENT_InstanceManager);\r
515     FXSYS_assert(pNewNode);\r
516     wsInstMgrNodeName = FX_WSTRC(L"_") + pTemplateNode->GetCData(XFA_ATTRIBUTE_Name);\r
517     pNewNode->SetCData(XFA_ATTRIBUTE_Name, wsInstMgrNodeName);\r
518     pFormParent->InsertChild(pNewNode, NULL);\r
519     pNewNode->SetTemplateNode(pTemplateNode);\r
520     return pNewNode;\r
521 }\r
522 static CXFA_Node* XFA_DataMerge_FindMatchingDataNode(CXFA_Document* pDocument, CXFA_Node* pTemplateNode, CXFA_Node* pDataScope, FX_BOOL& bAccessedDataDOM, FX_BOOL bForceBind, CXFA_NodeIteratorTemplate<CXFA_Node, CXFA_TraverseStrategy_XFAContainerNode>* pIterator, FX_BOOL& bSelfMatch, XFA_ATTRIBUTEENUM& eBindMatch, FX_BOOL bUpLevel = TRUE)\r
523 {\r
524     FX_BOOL bOwnIterator = FALSE;\r
525     if(!pIterator) {\r
526         bOwnIterator = TRUE;\r
527         pIterator = FX_NEW CXFA_NodeIteratorTemplate<CXFA_Node, CXFA_TraverseStrategy_XFAContainerNode>(pTemplateNode);\r
528     }\r
529     CXFA_Node* pResult = NULL;\r
530     for(CXFA_Node* pCurTemplateNode = pIterator->GetCurrent(); pCurTemplateNode; ) {\r
531         XFA_ELEMENT eMatchNodeType;\r
532         switch(pCurTemplateNode->GetClassID()) {\r
533             case XFA_ELEMENT_Subform:\r
534                 eMatchNodeType = XFA_ELEMENT_DataGroup;\r
535                 break;\r
536             case XFA_ELEMENT_Field: {\r
537                     eMatchNodeType = XFA_FieldIsMultiListBox(pCurTemplateNode) ? XFA_ELEMENT_DataGroup : XFA_ELEMENT_DataValue;\r
538                 }\r
539                 break;\r
540             case XFA_ELEMENT_ExclGroup:\r
541                 eMatchNodeType = XFA_ELEMENT_DataValue;\r
542                 break;\r
543             default:\r
544                 pCurTemplateNode = pIterator->MoveToNext();\r
545                 continue;\r
546         }\r
547         CXFA_Node* pTemplateNodeOccur = pCurTemplateNode->GetFirstChildByClass(XFA_ELEMENT_Occur);\r
548         FX_INT32 iMin, iMax, iInit;\r
549         if(pTemplateNodeOccur && XFA_GetOccurInfo(pTemplateNodeOccur, iMin, iMax, iInit) && iMax == 0) {\r
550             pCurTemplateNode = pIterator->MoveToNext();\r
551             continue;\r
552         }\r
553         CXFA_Node* pTemplateNodeBind = pCurTemplateNode->GetFirstChildByClass(XFA_ELEMENT_Bind);\r
554         XFA_ATTRIBUTEENUM eMatch = pTemplateNodeBind ? pTemplateNodeBind->GetEnum(XFA_ATTRIBUTE_Match) : XFA_ATTRIBUTEENUM_Once;\r
555         eBindMatch = eMatch;\r
556         switch(eMatch) {\r
557             case XFA_ATTRIBUTEENUM_None:\r
558                 pCurTemplateNode = pIterator->MoveToNext();\r
559                 continue;\r
560             case XFA_ATTRIBUTEENUM_Global:\r
561                 bAccessedDataDOM = TRUE;\r
562                 if(!bForceBind) {\r
563                     pCurTemplateNode = pIterator->MoveToNext();\r
564                     continue;\r
565                 }\r
566                 if (eMatchNodeType == XFA_ELEMENT_DataValue || (eMatchNodeType == XFA_ELEMENT_DataGroup && XFA_FieldIsMultiListBox(pTemplateNodeBind))) {\r
567                     CXFA_Node* pGlobalBindNode = XFA_DataMerge_FindGlobalDataNode(pDocument, pCurTemplateNode->GetCData(XFA_ATTRIBUTE_Name), pDataScope, eMatchNodeType);\r
568                     if(!pGlobalBindNode) {\r
569                         pCurTemplateNode = pIterator->MoveToNext();\r
570                         continue;\r
571                     }\r
572                     pResult = pGlobalBindNode;\r
573                     break;\r
574                 }\r
575             case XFA_ATTRIBUTEENUM_Once: {\r
576                     bAccessedDataDOM = TRUE;\r
577                     CXFA_Node* pOnceBindNode = XFA_DataMerge_FindOnceDataNode(pDocument, pCurTemplateNode->GetCData(XFA_ATTRIBUTE_Name), pDataScope, eMatchNodeType);\r
578                     if(!pOnceBindNode) {\r
579                         pCurTemplateNode = pIterator->MoveToNext();\r
580                         continue;\r
581                     }\r
582                     pResult = pOnceBindNode;\r
583                 }\r
584                 break;\r
585             case XFA_ATTRIBUTEENUM_DataRef: {\r
586                     bAccessedDataDOM = TRUE;\r
587                     CXFA_Node* pDataRefBindNode = XFA_DataMerge_FindDataRefDataNode(pDocument, pTemplateNodeBind->GetCData(XFA_ATTRIBUTE_Ref), pDataScope, eMatchNodeType, pTemplateNode, bForceBind, bUpLevel);\r
588                     if(pDataRefBindNode && pDataRefBindNode->GetClassID() == eMatchNodeType) {\r
589                         pResult = pDataRefBindNode;\r
590                     }\r
591                     if(!pResult) {\r
592                         pCurTemplateNode = pIterator->SkipChildrenAndMoveToNext();\r
593                         continue;\r
594                     }\r
595                 }\r
596                 break;\r
597             default:\r
598                 break;\r
599         }\r
600         if(pCurTemplateNode == pTemplateNode && pResult != NULL) {\r
601             bSelfMatch = TRUE;\r
602         }\r
603         break;\r
604     }\r
605     if(bOwnIterator) {\r
606         delete pIterator;\r
607     }\r
608     return pResult;\r
609 }\r
610 static void XFA_DataMerge_SortRecurseRecord(CFX_ArrayTemplate<XFA_DataMerge_RecurseRecord>& rgRecords, CXFA_Node* pDataScope, FX_BOOL bChoiceMode = FALSE)\r
611 {\r
612     FX_INT32 iCount = rgRecords.GetSize();\r
613     CFX_ArrayTemplate<XFA_DataMerge_RecurseRecord> rgResultRecord;\r
614     for (CXFA_Node* pChildNode = pDataScope->GetNodeItem(XFA_NODEITEM_FirstChild); pChildNode; pChildNode = pChildNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {\r
615         for(FX_INT32 i = 0; i < iCount; i ++) {\r
616             CXFA_Node* pNode = rgRecords[i].pDataChild;\r
617             if (pChildNode == pNode) {\r
618                 XFA_DataMerge_RecurseRecord sNewRecord = {rgRecords[i].pTemplateChild, pNode};\r
619                 rgResultRecord.Add(sNewRecord);\r
620                 rgRecords.RemoveAt(i);\r
621                 iCount--;\r
622                 break;\r
623             }\r
624         }\r
625         if (bChoiceMode && rgResultRecord.GetSize() > 0) {\r
626             break;\r
627         }\r
628     }\r
629     if (rgResultRecord.GetSize() > 0) {\r
630         if (!bChoiceMode) {\r
631             for (FX_INT32 i = 0; i < iCount; i++) {\r
632                 XFA_DataMerge_RecurseRecord sNewRecord = {rgRecords[i].pTemplateChild, rgRecords[i].pDataChild};\r
633                 rgResultRecord.Add(sNewRecord);\r
634             }\r
635         }\r
636         rgRecords.RemoveAll();\r
637         rgRecords.Copy(rgResultRecord);\r
638     }\r
639 }\r
640 static CXFA_Node* XFA_DataMerge_CopyContainer_SubformSet(CXFA_Document* pDocument, CXFA_Node* pTemplateNode, CXFA_Node* pFormParentNode, CXFA_Node* pDataScope, FX_BOOL bOneInstance, FX_BOOL bDataMerge)\r
641 {\r
642     XFA_ELEMENT eElement = pTemplateNode->GetClassID();\r
643     CXFA_Node *pOccurNode = NULL;\r
644     CXFA_Node *pFirstInstance = NULL;\r
645     FX_BOOL bUseInstanceManager = pFormParentNode->GetClassID() != XFA_ELEMENT_Area;\r
646     CXFA_Node* pInstMgrNode = NULL;\r
647     CXFA_NodeArray subformArray;\r
648     CXFA_NodeArray* pSearchArray = NULL;\r
649     if (!bOneInstance && (eElement == XFA_ELEMENT_SubformSet || eElement == XFA_ELEMENT_Subform)) {\r
650         pInstMgrNode = bUseInstanceManager ? XFA_NodeMerge_CloneOrMergeInstanceManager(pDocument, pFormParentNode, pTemplateNode, subformArray) : NULL;\r
651         if(CXFA_Node* pOccurTemplateNode = pTemplateNode->GetFirstChildByClass(XFA_ELEMENT_Occur)) {\r
652             pOccurNode = pInstMgrNode != NULL ? XFA_NodeMerge_CloneOrMergeContainer(pDocument, pInstMgrNode, pOccurTemplateNode, FALSE) : pOccurTemplateNode;\r
653         } else if (pInstMgrNode) {\r
654             pOccurNode = pInstMgrNode->GetFirstChildByClass(XFA_ELEMENT_Occur);\r
655             if (pOccurNode) {\r
656                 pOccurNode->SetFlag(XFA_NODEFLAG_UnusedNode, FALSE);\r
657             }\r
658         }\r
659         if (pInstMgrNode) {\r
660             pInstMgrNode->SetFlag(XFA_NODEFLAG_Initialized);\r
661             pSearchArray = &subformArray;\r
662             if (pFormParentNode->GetClassID() == XFA_ELEMENT_PageArea) {\r
663                 bOneInstance = TRUE;\r
664                 if (subformArray.GetSize() < 1) {\r
665                     pSearchArray = NULL;\r
666                 }\r
667             } else if ((pTemplateNode->GetNameHash() == 0) && (subformArray.GetSize() < 1)) {\r
668                 pSearchArray = NULL;\r
669             }\r
670         }\r
671     }\r
672     FX_INT32 iMax = 1, iInit = 1, iMin = 1;\r
673     if(!bOneInstance) {\r
674         XFA_GetOccurInfo(pOccurNode, iMin, iMax, iInit);\r
675     }\r
676     XFA_ATTRIBUTEENUM   eRelation = eElement == XFA_ELEMENT_SubformSet ? pTemplateNode->GetEnum(XFA_ATTRIBUTE_Relation) : XFA_ATTRIBUTEENUM_Ordered;\r
677     FX_INT32 iCurRepeatIndex = 0;\r
678     XFA_ATTRIBUTEENUM eParentBindMatch = XFA_ATTRIBUTEENUM_None;\r
679     if (bDataMerge) {\r
680         CXFA_NodeIteratorTemplate<CXFA_Node, CXFA_TraverseStrategy_XFAContainerNode> sNodeIterator(pTemplateNode);\r
681         FX_BOOL bAccessedDataDOM = FALSE;\r
682         if (eElement == XFA_ELEMENT_SubformSet || eElement == XFA_ELEMENT_Area) {\r
683             sNodeIterator.MoveToNext();\r
684         } else {\r
685             CFX_MapPtrTemplate<CXFA_Node*, CXFA_Node*> subformMapArray;\r
686             CXFA_NodeArray subformArray;\r
687             for (; iMax < 0 || iCurRepeatIndex < iMax; iCurRepeatIndex++) {\r
688                 FX_BOOL bSelfMatch = FALSE;\r
689                 XFA_ATTRIBUTEENUM eBindMatch = XFA_ATTRIBUTEENUM_None;\r
690                 CXFA_Node* pDataNode = XFA_DataMerge_FindMatchingDataNode(pDocument, pTemplateNode, pDataScope, bAccessedDataDOM, FALSE, &sNodeIterator, bSelfMatch, eBindMatch);\r
691                 if(!pDataNode || sNodeIterator.GetCurrent() != pTemplateNode) {\r
692                     break;\r
693                 }\r
694                 eParentBindMatch = eBindMatch;\r
695                 CXFA_Node* pSubformNode = XFA_NodeMerge_CloneOrMergeContainer(pDocument, pFormParentNode, pTemplateNode, FALSE, pSearchArray);\r
696                 if(!pFirstInstance) {\r
697                     pFirstInstance = pSubformNode;\r
698                 }\r
699                 XFA_DataMerge_CreateDataBinding(pSubformNode, pDataNode);\r
700                 FXSYS_assert(pSubformNode);\r
701                 subformMapArray.SetAt(pSubformNode, pDataNode);\r
702                 subformArray.Add(pSubformNode);\r
703             }\r
704             FX_POSITION position = subformMapArray.GetStartPosition();\r
705             for(FX_INT32 iIndex = 0; iIndex < subformArray.GetSize(); iIndex ++) {\r
706                 CXFA_Node* pSubform = subformArray[iIndex];\r
707                 CXFA_Node* pDataNode = (CXFA_Node*)subformMapArray.GetValueAt(pSubform);\r
708                 for (CXFA_Node *pTemplateChild = pTemplateNode->GetNodeItem(XFA_NODEITEM_FirstChild); pTemplateChild; pTemplateChild = pTemplateChild->GetNodeItem(XFA_NODEITEM_NextSibling)) {\r
709                     if (XFA_NeedGenerateForm(pTemplateChild, bUseInstanceManager)) {\r
710                         XFA_NodeMerge_CloneOrMergeContainer(pDocument, pSubform, pTemplateChild, TRUE);\r
711                     } else if (pTemplateChild->GetObjectType() == XFA_OBJECTTYPE_ContainerNode) {\r
712                         pDocument->DataMerge_CopyContainer(pTemplateChild, pSubform, pDataNode, FALSE, TRUE, FALSE);\r
713                     }\r
714                 }\r
715             }\r
716             subformMapArray.RemoveAll();\r
717         }\r
718         for (; iMax < 0 || iCurRepeatIndex < iMax; iCurRepeatIndex++) {\r
719             FX_BOOL bSelfMatch = FALSE;\r
720             CXFA_Node* pOldNode = sNodeIterator.GetCurrent();\r
721             XFA_ATTRIBUTEENUM eBindMatch = XFA_ATTRIBUTEENUM_None;\r
722             if(!XFA_DataMerge_FindMatchingDataNode(pDocument, pTemplateNode, pDataScope, bAccessedDataDOM, FALSE, &sNodeIterator, bSelfMatch, eBindMatch)) {\r
723                 break;\r
724             }\r
725             if(eBindMatch == XFA_ATTRIBUTEENUM_DataRef && eParentBindMatch == XFA_ATTRIBUTEENUM_DataRef) {\r
726                 break;\r
727             }\r
728             if (eRelation ==  XFA_ATTRIBUTEENUM_Choice || eRelation == XFA_ATTRIBUTEENUM_Unordered) {\r
729                 CXFA_Node* pSubformSetNode = XFA_NodeMerge_CloneOrMergeContainer(pDocument, pFormParentNode, pTemplateNode, FALSE, pSearchArray);\r
730                 FXSYS_assert(pSubformSetNode);\r
731                 if(!pFirstInstance) {\r
732                     pFirstInstance = pSubformSetNode;\r
733                 }\r
734                 CFX_ArrayTemplate<XFA_DataMerge_RecurseRecord> rgItemMatchList;\r
735                 CFX_ArrayTemplate<CXFA_Node*> rgItemUnmatchList;\r
736                 for (CXFA_Node *pTemplateChild = pTemplateNode->GetNodeItem(XFA_NODEITEM_FirstChild); pTemplateChild; pTemplateChild = pTemplateChild->GetNodeItem(XFA_NODEITEM_NextSibling)) {\r
737                     if (XFA_NeedGenerateForm(pTemplateChild, bUseInstanceManager)) {\r
738                         XFA_NodeMerge_CloneOrMergeContainer(pDocument, pSubformSetNode, pTemplateChild, TRUE);\r
739                     } else if(pTemplateChild->GetObjectType() == XFA_OBJECTTYPE_ContainerNode) {\r
740                         CXFA_Node *pDataMatch;\r
741                         bSelfMatch = FALSE;\r
742                         eBindMatch = XFA_ATTRIBUTEENUM_None;\r
743                         if(eRelation != XFA_ATTRIBUTEENUM_Ordered && (pDataMatch = XFA_DataMerge_FindMatchingDataNode(pDocument, pTemplateChild, pDataScope, bAccessedDataDOM, FALSE, NULL, bSelfMatch, eBindMatch))) {\r
744                             XFA_DataMerge_RecurseRecord sNewRecord = {pTemplateChild, pDataMatch};\r
745                             if(bSelfMatch) {\r
746                                 rgItemMatchList.InsertAt(0, sNewRecord);\r
747                             } else {\r
748                                 rgItemMatchList.Add(sNewRecord);\r
749                             }\r
750                         } else {\r
751                             rgItemUnmatchList.Add(pTemplateChild);\r
752                         }\r
753                     }\r
754                 }\r
755                 switch(eRelation) {\r
756                     case XFA_ATTRIBUTEENUM_Choice: {\r
757                             FXSYS_assert(rgItemMatchList.GetSize());\r
758                             XFA_DataMerge_SortRecurseRecord(rgItemMatchList, pDataScope, TRUE);\r
759                             pDocument->DataMerge_CopyContainer(rgItemMatchList[0].pTemplateChild, pSubformSetNode, pDataScope);\r
760                         }\r
761                         break;\r
762                     case XFA_ATTRIBUTEENUM_Unordered: {\r
763                             if(rgItemMatchList.GetSize()) {\r
764                                 XFA_DataMerge_SortRecurseRecord(rgItemMatchList, pDataScope);\r
765                                 for(FX_INT32 i = 0, count = rgItemMatchList.GetSize(); i < count; i ++) {\r
766                                     pDocument->DataMerge_CopyContainer(rgItemMatchList[i].pTemplateChild, pSubformSetNode, pDataScope);\r
767                                 }\r
768                             }\r
769                             for(FX_INT32 i = 0, count = rgItemUnmatchList.GetSize(); i < count; i ++) {\r
770                                 pDocument->DataMerge_CopyContainer(rgItemUnmatchList[i], pSubformSetNode, pDataScope);\r
771                             }\r
772                         }\r
773                         break;\r
774                     default:\r
775                         break;\r
776                 }\r
777             } else {\r
778                 CXFA_Node* pSubformSetNode = XFA_NodeMerge_CloneOrMergeContainer(pDocument, pFormParentNode, pTemplateNode, FALSE, pSearchArray);\r
779                 FXSYS_assert(pSubformSetNode);\r
780                 if(!pFirstInstance) {\r
781                     pFirstInstance = pSubformSetNode;\r
782                 }\r
783                 for (CXFA_Node *pTemplateChild = pTemplateNode->GetNodeItem(XFA_NODEITEM_FirstChild); pTemplateChild; pTemplateChild = pTemplateChild->GetNodeItem(XFA_NODEITEM_NextSibling)) {\r
784                     if (XFA_NeedGenerateForm(pTemplateChild, bUseInstanceManager)) {\r
785                         XFA_NodeMerge_CloneOrMergeContainer(pDocument, pSubformSetNode, pTemplateChild, TRUE);\r
786                     } else if (pTemplateChild->GetObjectType() == XFA_OBJECTTYPE_ContainerNode) {\r
787                         pDocument->DataMerge_CopyContainer(pTemplateChild, pSubformSetNode, pDataScope);\r
788                     }\r
789                 }\r
790             }\r
791         }\r
792         if(iCurRepeatIndex == 0 && bAccessedDataDOM == FALSE) {\r
793             FX_INT32 iLimit = iMax;\r
794             if (pInstMgrNode && pTemplateNode->GetNameHash() == 0) {\r
795                 iLimit = subformArray.GetSize();\r
796                 if (iLimit < iMin) {\r
797                     iLimit = iInit;\r
798                 }\r
799             }\r
800             for (; (iLimit < 0 || iCurRepeatIndex < iLimit); iCurRepeatIndex++) {\r
801                 if (pInstMgrNode) {\r
802                     if (pSearchArray && pSearchArray->GetSize() < 1) {\r
803                         if (pTemplateNode->GetNameHash() != 0) {\r
804                             break;\r
805                         }\r
806                         pSearchArray = NULL;\r
807                     }\r
808                 } else if(!XFA_DataMerge_FindFormDOMInstance(pDocument, pTemplateNode->GetClassID(), pTemplateNode->GetNameHash(), pFormParentNode)) {\r
809                     break;\r
810                 }\r
811                 CXFA_Node* pSubformNode = XFA_NodeMerge_CloneOrMergeContainer(pDocument, pFormParentNode, pTemplateNode, FALSE, pSearchArray);\r
812                 FXSYS_assert(pSubformNode);\r
813                 if(!pFirstInstance) {\r
814                     pFirstInstance = pSubformNode;\r
815                 }\r
816                 for (CXFA_Node *pTemplateChild = pTemplateNode->GetNodeItem(XFA_NODEITEM_FirstChild); pTemplateChild; pTemplateChild = pTemplateChild->GetNodeItem(XFA_NODEITEM_NextSibling)) {\r
817                     if (XFA_NeedGenerateForm(pTemplateChild, bUseInstanceManager)) {\r
818                         XFA_NodeMerge_CloneOrMergeContainer(pDocument, pSubformNode, pTemplateChild, TRUE);\r
819                     } else if(pTemplateChild->GetObjectType() == XFA_OBJECTTYPE_ContainerNode) {\r
820                         pDocument->DataMerge_CopyContainer(pTemplateChild, pSubformNode, pDataScope);\r
821                     }\r
822                 }\r
823             }\r
824         }\r
825     }\r
826     FX_INT32 iMinimalLimit = iCurRepeatIndex == 0 ? iInit : iMin;\r
827     for (; iCurRepeatIndex < iMinimalLimit; iCurRepeatIndex++) {\r
828         CXFA_Node* pSubformSetNode = XFA_NodeMerge_CloneOrMergeContainer(pDocument, pFormParentNode, pTemplateNode, FALSE, pSearchArray);\r
829         FXSYS_assert(pSubformSetNode);\r
830         if(!pFirstInstance) {\r
831             pFirstInstance = pSubformSetNode;\r
832         }\r
833         FX_BOOL bFound = FALSE;\r
834         for (CXFA_Node *pTemplateChild = pTemplateNode->GetNodeItem(XFA_NODEITEM_FirstChild); pTemplateChild; pTemplateChild = pTemplateChild->GetNodeItem(XFA_NODEITEM_NextSibling)) {\r
835             if (XFA_NeedGenerateForm(pTemplateChild, bUseInstanceManager)) {\r
836                 XFA_NodeMerge_CloneOrMergeContainer(pDocument, pSubformSetNode, pTemplateChild, TRUE);\r
837             } else if(pTemplateChild->GetObjectType() == XFA_OBJECTTYPE_ContainerNode) {\r
838                 if(bFound && eRelation == XFA_ATTRIBUTEENUM_Choice) {\r
839                     continue;\r
840                 }\r
841                 pDocument->DataMerge_CopyContainer(pTemplateChild, pSubformSetNode, pDataScope, FALSE, bDataMerge);\r
842                 bFound = TRUE;\r
843             }\r
844         }\r
845     }\r
846     return pFirstInstance;\r
847 }\r
848 static CXFA_Node* XFA_DataMerge_CopyContainer_Field(CXFA_Document* pDocument, CXFA_Node* pTemplateNode, CXFA_Node* pFormNode, CXFA_Node* pDataScope, FX_BOOL bDataMerge, FX_BOOL bUpLevel = TRUE)\r
849 {\r
850     CXFA_Node* pFieldNode = XFA_NodeMerge_CloneOrMergeContainer(pDocument, pFormNode, pTemplateNode, FALSE);\r
851     FXSYS_assert(pFieldNode);\r
852     for (CXFA_Node *pTemplateChildNode = pTemplateNode->GetNodeItem(XFA_NODEITEM_FirstChild); pTemplateChildNode; pTemplateChildNode = pTemplateChildNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {\r
853         if(XFA_NeedGenerateForm(pTemplateChildNode)) {\r
854             XFA_NodeMerge_CloneOrMergeContainer(pDocument, pFieldNode, pTemplateChildNode, TRUE);\r
855         } else if (pTemplateNode->GetClassID() == XFA_ELEMENT_ExclGroup && pTemplateChildNode->IsContainerNode()) {\r
856             if (pTemplateChildNode->GetClassID() == XFA_ELEMENT_Field) {\r
857                 XFA_DataMerge_CopyContainer_Field(pDocument, pTemplateChildNode, pFieldNode, NULL, FALSE);\r
858             }\r
859         }\r
860     }\r
861     if(bDataMerge) {\r
862         FX_BOOL bAccessedDataDOM = FALSE;\r
863         FX_BOOL bSelfMatch = FALSE;\r
864         XFA_ATTRIBUTEENUM eBindMatch;\r
865         CXFA_Node* pDataNode = XFA_DataMerge_FindMatchingDataNode(pDocument, pTemplateNode, pDataScope, bAccessedDataDOM, TRUE, NULL, bSelfMatch, eBindMatch, bUpLevel);\r
866         if(pDataNode) {\r
867             XFA_DataMerge_CreateDataBinding(pFieldNode, pDataNode);\r
868         }\r
869     } else {\r
870         XFA_DataMerge_FormValueNode_MatchNoneCreateChild(pFieldNode);\r
871     }\r
872     return pFieldNode;\r
873 }\r
874 CXFA_Node* CXFA_Document::DataMerge_CopyContainer(CXFA_Node* pTemplateNode, CXFA_Node* pFormNode, CXFA_Node* pDataScope, FX_BOOL bOneInstance , FX_BOOL bDataMerge , FX_BOOL bUpLevel)\r
875 {\r
876     switch(pTemplateNode->GetClassID()) {\r
877         case XFA_ELEMENT_SubformSet:\r
878         case XFA_ELEMENT_Subform:\r
879         case XFA_ELEMENT_Area:\r
880         case XFA_ELEMENT_PageArea:\r
881             return XFA_DataMerge_CopyContainer_SubformSet(this, pTemplateNode, pFormNode, pDataScope, bOneInstance, bDataMerge);\r
882         case XFA_ELEMENT_ExclGroup:\r
883         case XFA_ELEMENT_Field:\r
884         case XFA_ELEMENT_Draw:\r
885         case XFA_ELEMENT_ContentArea:\r
886             return XFA_DataMerge_CopyContainer_Field(this, pTemplateNode, pFormNode, pDataScope, bDataMerge, bUpLevel);\r
887         case XFA_ELEMENT_PageSet:\r
888             break;\r
889         case XFA_ELEMENT_Variables:\r
890             break;\r
891         default:\r
892             FXSYS_assert(FALSE);\r
893             break;\r
894     }\r
895     return NULL;\r
896 }\r
897 #define XFA_DATAMERGE_UPDATEBINDINGRELATIONS_DFS\r
898 #ifdef XFA_DATAMERGE_UPDATEBINDINGRELATIONS_DFS\r
899 static void XFA_DataMerge_UpdateBindingRelations(CXFA_Document* pDocument, CXFA_Node* pFormNode, CXFA_Node* pDataScope, FX_BOOL bDataRef, FX_BOOL bParentDataRef)\r
900 {\r
901     FX_BOOL bMatchRef = TRUE;\r
902     XFA_ELEMENT eClassID = pFormNode->GetClassID();\r
903     CXFA_Node* pDataNode = pFormNode->GetBindData();\r
904     if(eClassID == XFA_ELEMENT_Subform || eClassID == XFA_ELEMENT_ExclGroup || eClassID == XFA_ELEMENT_Field) {\r
905         CXFA_Node *pTemplateNode = pFormNode->GetTemplateNode();\r
906         CXFA_Node *pTemplateNodeBind = pTemplateNode ? pTemplateNode->GetFirstChildByClass(XFA_ELEMENT_Bind) : NULL;\r
907         XFA_ATTRIBUTEENUM eMatch = pTemplateNodeBind ? pTemplateNodeBind->GetEnum(XFA_ATTRIBUTE_Match) : XFA_ATTRIBUTEENUM_Once;\r
908         switch(eMatch) {\r
909             case XFA_ATTRIBUTEENUM_None:\r
910                 if (!bDataRef || bParentDataRef) {\r
911                     XFA_DataMerge_FormValueNode_MatchNoneCreateChild(pFormNode);\r
912                 }\r
913                 break;\r
914             case XFA_ATTRIBUTEENUM_Once:\r
915                 if (!bDataRef || bParentDataRef) {\r
916                     if (!pDataNode) {\r
917                         if (pFormNode->GetNameHash() != 0 && pFormNode->GetEnum(XFA_ATTRIBUTE_Scope) != XFA_ATTRIBUTEENUM_None) {\r
918                             XFA_ELEMENT eDataNodeType = (eClassID == XFA_ELEMENT_Subform || XFA_FieldIsMultiListBox(pFormNode)) ? XFA_ELEMENT_DataGroup : XFA_ELEMENT_DataValue;\r
919                             pDataNode = XFA_DataDescription_MaybeCreateDataNode(pDocument, pDataScope, eDataNodeType, pFormNode->GetCData(XFA_ATTRIBUTE_Name));\r
920                             if(pDataNode) {\r
921                                 XFA_DataMerge_CreateDataBinding(pFormNode, pDataNode, FALSE);\r
922                             }\r
923                         }\r
924                         if (!pDataNode) {\r
925                             XFA_DataMerge_FormValueNode_MatchNoneCreateChild(pFormNode);\r
926                         }\r
927                     } else {\r
928                         CXFA_Node* pDataParent = pDataNode->GetNodeItem(XFA_NODEITEM_Parent);\r
929                         if(pDataParent != pDataScope) {\r
930                             FXSYS_assert(pDataParent);\r
931                             pDataParent->RemoveChild(pDataNode);\r
932                             pDataScope->InsertChild(pDataNode);\r
933                         }\r
934                     }\r
935                 }\r
936                 break;\r
937             case XFA_ATTRIBUTEENUM_Global:\r
938                 if (!bDataRef || bParentDataRef) {\r
939                     FX_DWORD dwNameHash = pFormNode->GetNameHash();\r
940                     if (dwNameHash != 0 && !pDataNode) {\r
941                         pDataNode = XFA_DataMerge_GetGlobalBinding(pDocument, dwNameHash);\r
942                         if(!pDataNode) {\r
943                             XFA_ELEMENT eDataNodeType = (eClassID == XFA_ELEMENT_Subform  || XFA_FieldIsMultiListBox(pFormNode)) ? XFA_ELEMENT_DataGroup : XFA_ELEMENT_DataValue;\r
944                             CXFA_Node* pRecordNode = (CXFA_Node*)pDocument->GetXFANode(XFA_HASHCODE_Record);\r
945                             pDataNode = XFA_DataDescription_MaybeCreateDataNode(pDocument, pRecordNode, eDataNodeType, pFormNode->GetCData(XFA_ATTRIBUTE_Name));\r
946                             if(pDataNode) {\r
947                                 XFA_DataMerge_CreateDataBinding(pFormNode, pDataNode, FALSE);\r
948                                 XFA_DataMerge_RegisterGlobalBinding(pDocument, pFormNode->GetNameHash(), pDataNode);\r
949                             }\r
950                         } else {\r
951                             XFA_DataMerge_CreateDataBinding(pFormNode, pDataNode);\r
952                         }\r
953                     }\r
954                     if (!pDataNode) {\r
955                         XFA_DataMerge_FormValueNode_MatchNoneCreateChild(pFormNode);\r
956                     }\r
957                 }\r
958                 break;\r
959             case XFA_ATTRIBUTEENUM_DataRef: {\r
960                     bMatchRef = bDataRef;\r
961                     bParentDataRef = TRUE;\r
962                     if (!pDataNode && bDataRef) {\r
963                         CFX_WideStringC wsRef = pTemplateNodeBind->GetCData(XFA_ATTRIBUTE_Ref);\r
964                         FX_DWORD dFlags = XFA_RESOLVENODE_Children\r
965                                           | XFA_RESOLVENODE_CreateNode;\r
966                         XFA_RESOLVENODE_RS rs;\r
967                         pDocument->GetScriptContext()->ResolveObjects(pDataScope, wsRef, rs, dFlags, pTemplateNode);\r
968                         CXFA_Object* pObject = (rs.nodes.GetSize() > 0) ? rs.nodes[0] : NULL;\r
969                         pDataNode = (pObject && pObject->IsNode()) ? (CXFA_Node*)pObject : NULL;\r
970                         if(pDataNode) {\r
971                             XFA_DataMerge_CreateDataBinding(pFormNode, pDataNode, rs.dwFlags == XFA_RESOVENODE_RSTYPE_ExistNodes ? TRUE : FALSE);\r
972                         } else {\r
973                             XFA_DataMerge_FormValueNode_MatchNoneCreateChild(pFormNode);\r
974                         }\r
975                     }\r
976                 }\r
977                 break;\r
978             default:\r
979                 break;\r
980         }\r
981     }\r
982     if(bMatchRef && (eClassID == XFA_ELEMENT_Subform || eClassID == XFA_ELEMENT_SubformSet || eClassID == XFA_ELEMENT_Area || eClassID == XFA_ELEMENT_PageArea || eClassID == XFA_ELEMENT_PageSet)) {\r
983         for(CXFA_Node* pFormChild = pFormNode->GetNodeItem(XFA_NODEITEM_FirstChild); pFormChild; pFormChild = pFormChild->GetNodeItem(XFA_NODEITEM_NextSibling)) {\r
984             if(pFormChild->GetObjectType() != XFA_OBJECTTYPE_ContainerNode) {\r
985                 continue;\r
986             }\r
987             if(pFormChild->HasFlag(XFA_NODEFLAG_UnusedNode)) {\r
988                 continue;\r
989             }\r
990             XFA_DataMerge_UpdateBindingRelations(pDocument, pFormChild, pDataNode ? pDataNode : pDataScope, bDataRef, bParentDataRef);\r
991         }\r
992     }\r
993 }\r
994 #else\r
995 static void XFA_DataMerge_UpdateBindingRelations(CXFA_Document* pDocument, CXFA_Node* pFormNode, CXFA_Node* pDataScope, CFX_PtrList& rgFormNodeList, CFX_PtrList& rgDataScopeList, FX_BOOL bD _DEBUG\r
996 #ifdef _DEBUG\r
997         CFX_WideString wsFormSOM; CFX_WideString wsDataScopeSOM;\r
998         pFormNode->GetSOMExpression(wsFormSOM); pDataScope->GetSOMExpression(wsDataScopeSOM);\r
999 #endif\r
1000         XFA_ELEMENT eClassID = pFormNode->GetClassID();\r
1001         CXFA_Node* pDataNode = pFormNode->GetBindData();\r
1002         if(eClassID == XFA_ELEMENT_Subform || eClassID == XFA_ELEMENT_ExclGroup || eClassID == XFA_ELEMENT_Field)\r
1003 {\r
1004 CXFA_Node *pTemplateNode = pFormNode->GetTemplateNode();\r
1005     CXFA_Node *pTemplateNodeBind = pTemplateNode ? pTemplateNode->GetFirstChildByClass(XFA_ELEMENT_Bind) : NULL;\r
1006     XFA_ATTRIBUTEENUM eMatch = pTemplateNodeBind ? pTemplateNodeBind->GetEnum(XFA_ATTRIBUTE_Match) : XFA_ATTRIBUTEENUM_Once;\r
1007     switch(eMatch) {\r
1008         case XFA_ATTRIBUTEENUM_None:\r
1009             break;\r
1010         case XFA_ATTRIBUTEENUM_Once: {\r
1011                 if (!pDataNode) {\r
1012                     if (pFormNode->GetNameHash() != 0 && pFormNode->GetEnum(XFA_ATTRIBUTE_Scope) != XFA_ATTRIBUTEENUM_None) {\r
1013                         XFA_ELEMENT eDataNodeType = eClassID == XFA_ELEMENT_Subform ? XFA_ELEMENT_DataGroup : XFA_ELEMENT_DataValue;\r
1014                         pDataNode = XFA_DataDescription_MaybeCreateDataNode(pDocument, pDataScope, eDataNodeType, pFormNode->GetCData(XFA_ATTRIBUTE_Name));\r
1015                         if(pDataNode) {\r
1016                             XFA_DataMerge_CreateDataBinding(pFormNode, pDataNode, FALSE);\r
1017                         }\r
1018                     }\r
1019                 } else {\r
1020                     CXFA_Node* pDataParent = pDataNode->GetNodeItem(XFA_NODEITEM_Parent);\r
1021                     if(pDataParent != pDataScope) {\r
1022                         FXSYS_assert(pDataParent);\r
1023                         pDataParent->RemoveChild(pDataNode);\r
1024                         pDataScope->InsertChild(pDataNode);\r
1025                     }\r
1026                 }\r
1027             }\r
1028             break;\r
1029         case XFA_ATTRIBUTEENUM_Global: {\r
1030                 FX_DWORD dwNameHash = pFormNode->GetNameHash();\r
1031                 if (dwNameHash != 0 && !pDataNode) {\r
1032                     pDataNode = XFA_DataMerge_GetGlobalBinding(pDocument, dwNameHash);\r
1033                     if(!pDataNode) {\r
1034                         XFA_ELEMENT eDataNodeType = eClassID == XFA_ELEMENT_Subform ? XFA_ELEMENT_DataGroup : XFA_ELEMENT_DataValue;\r
1035                         CXFA_Node* pRecordNode = (CXFA_Node*)pDocument->GetXFANode(XFA_HASHCODE_Record);\r
1036                         pDataNode = XFA_DataDescription_MaybeCreateDataNode(pDocument, pRecordNode, eDataNodeType, pFormNode->GetCData(XFA_ATTRIBUTE_Name));\r
1037                     }\r
1038                     if(pDataNode) {\r
1039                         XFA_DataMerge_CreateDataBinding(pFormNode, pDataNode, FALSE);\r
1040                         XFA_DataMerge_RegisterGlobalBinding(pDocument, pFormNode->GetNameHash(), pDataNode);\r
1041                     }\r
1042                 }\r
1043             }\r
1044             break;\r
1045         case XFA_ATTRIBUTEENUM_DataRef: {\r
1046                 if (!pDataNode) {\r
1047                     CFX_WideStringC wsRef = pTemplateNodeBind->GetCData(XFA_ATTRIBUTE_Ref);\r
1048                     FX_DWORD dFlags = XFA_RESOLVENODE_Children | XFA_RESOLVENODE_Attributes | XFA_RESOLVENODE_Siblings | XFA_RESOLVENODE_Parent\r
1049                                       | XFA_RESOLVENODE_CreateNode;\r
1050                     XFA_RESOLVENODE_RS rs;\r
1051                     pDocument->GetScriptContext()->ResolveObjects(pDataScope, wsRef, rs, dFlags, pTemplateNode);\r
1052                     CXFA_Object* pObject = (rs.nodes.GetSize() > 0) ? rs.nodes[0] : NULL;\r
1053                     pDataNode = (pObject && pObject->IsNode()) ? (CXFA_Node*)pObject : NULL;\r
1054                     if(pDataNode) {\r
1055                         XFA_DataMerge_CreateDataBinding(pFormNode, pDataNode, FALSE);\r
1056                     }\r
1057                 }\r
1058             }\r
1059             break;\r
1060     }\r
1061 }\r
1062 if(eClassID == XFA_ELEMENT_Subform || eClassID == XFA_ELEMENT_ExclGroup || eClassID == XFA_ELEMENT_SubformSet || eClassID == XFA_ELEMENT_Area || eClassID == XFA_ELEMENT_PageArea)\r
1063 {\r
1064 for(CXFA_Node* pFormChild = pFormNode->GetNodeItem(XFA_NODEITEM_FirstChild); pFormChild; pFormChild = pFormChild->GetNodeItem(XFA_NODEITEM_NextSibling)) {\r
1065         if(pFormChild->GetObjectType() != XFA_OBJECTTYPE_ContainerNode) {\r
1066             continue;\r
1067         }\r
1068         if(pFormChild->HasFlag(XFA_NODEFLAG_UnusedNode)) {\r
1069             continue;\r
1070         }\r
1071         rgFormNodeList.AddTail(pFormChild);\r
1072         rgDataScopeList.AddTail(pDataNode ? pDataNode : pDataScope);\r
1073     }\r
1074 }\r
1075 }\r
1076 #endif\r
1077 CXFA_Node* XFA_DataMerge_FindDataScope(CXFA_Node* pParentFormNode)\r
1078 {\r
1079     for(CXFA_Node* pRootBoundNode = pParentFormNode; pRootBoundNode && pRootBoundNode->GetObjectType() == XFA_OBJECTTYPE_ContainerNode; pRootBoundNode = pRootBoundNode->GetNodeItem(XFA_NODEITEM_Parent)) {\r
1080         CXFA_Node* pDataScope = pRootBoundNode->GetBindData();\r
1081         if(pDataScope) {\r
1082             return pDataScope;\r
1083         }\r
1084     }\r
1085     return (CXFA_Node*)pParentFormNode->GetDocument()->GetXFANode(XFA_HASHCODE_Data);\r
1086 }\r
1087 void CXFA_Document::DataMerge_UpdateBindingRelations(CXFA_Node* pFormUpdateRoot)\r
1088 {\r
1089     CXFA_Node* pDataScope = XFA_DataMerge_FindDataScope(pFormUpdateRoot->GetNodeItem(XFA_NODEITEM_Parent));\r
1090     if (!pDataScope) {\r
1091         return;\r
1092     }\r
1093 #ifdef XFA_DATAMERGE_UPDATEBINDINGRELATIONS_DFS\r
1094     XFA_DataMerge_UpdateBindingRelations(this, pFormUpdateRoot, pDataScope, FALSE, FALSE);\r
1095     XFA_DataMerge_UpdateBindingRelations(this, pFormUpdateRoot, pDataScope, TRUE, FALSE);\r
1096 #else\r
1097     CFX_PtrList rgFormNodeList, rgDataScopeList;\r
1098     rgFormNodeList.AddTail(pFormUpdateRoot);\r
1099     rgDataScopeList.AddTail(pDataScope);\r
1100     while(rgFormNodeList.GetCount()) {\r
1101         FX_POSITION pos;\r
1102         pos = rgFormNodeList.GetHeadPosition();\r
1103         CXFA_Node *pCurFormNode = (CXFA_Node*)rgFormNodeList.GetAt(pos);\r
1104         rgFormNodeList.RemoveAt(pos);\r
1105         pos = rgDataScopeList.GetHeadPosition();\r
1106         CXFA_Node *pCurDataScope = (CXFA_Node*)rgDataScopeList.GetAt(pos);\r
1107         rgDataScopeList.RemoveAt(pos);\r
1108         XFA_DataMerge_UpdateBindingRelations(this, pCurFormNode, pCurDataScope, rgFormNodeList, rgDataScopeList);\r
1109     }\r
1110 #endif\r
1111 }\r
1112 CXFA_Node *     CXFA_Document::GetNotBindNode(CXFA_ObjArray& arrayNodes)\r
1113 {\r
1114     for(FX_INT32 i = 0; i < arrayNodes.GetSize(); i++) {\r
1115         CXFA_Object* pObject = arrayNodes[i];\r
1116         if(!pObject->IsNode()) {\r
1117             continue;\r
1118         }\r
1119         if (((CXFA_Node*)pObject)->HasBindItem()) {\r
1120             continue;\r
1121         }\r
1122         return ((CXFA_Node*)pObject);\r
1123     }\r
1124     return NULL;\r
1125 }\r
1126 void CXFA_Document::DoDataMerge()\r
1127 {\r
1128     CXFA_Node* pTemplateRoot = m_pRootNode->GetFirstChildByClass(XFA_ELEMENT_Template);\r
1129     CXFA_Node* pDatasetsRoot = (CXFA_Node*)GetXFANode(XFA_HASHCODE_Datasets);\r
1130     if(!pDatasetsRoot) {\r
1131         IFDE_XMLElement* pDatasetsXMLNode = IFDE_XMLElement::Create(FX_WSTRC(L"xfa:datasets"));\r
1132         FXSYS_assert(pDatasetsXMLNode);\r
1133         pDatasetsXMLNode->SetString(FX_WSTRC(L"xmlns:xfa"), FX_WSTRC(L"http://www.xfa.org/schema/xfa-data/1.0/"));\r
1134         pDatasetsRoot = CreateNode(XFA_XDPPACKET_Datasets, XFA_ELEMENT_DataModel);\r
1135         pDatasetsRoot->SetCData(XFA_ATTRIBUTE_Name, FX_WSTRC(L"datasets"));\r
1136         m_pRootNode->GetXMLMappingNode()->InsertChildNode(pDatasetsXMLNode);\r
1137         m_pRootNode->InsertChild(pDatasetsRoot);\r
1138         pDatasetsRoot->SetXMLMappingNode(pDatasetsXMLNode);\r
1139     }\r
1140     CXFA_Node *pDataRoot = NULL, *pDDRoot = NULL;\r
1141     CFX_WideString wsDatasetsURI;\r
1142     pDatasetsRoot->TryNamespace(wsDatasetsURI);\r
1143     for(CXFA_Node *pChildNode = pDatasetsRoot->GetNodeItem(XFA_NODEITEM_FirstChild); pChildNode; pChildNode = pChildNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {\r
1144         if(pChildNode->GetClassID() != XFA_ELEMENT_DataGroup) {\r
1145             continue;\r
1146         }\r
1147         CFX_WideString wsNamespaceURI;\r
1148         if(!pDDRoot && pChildNode->GetNameHash() == XFA_HASHCODE_DataDescription) {\r
1149             if(!pChildNode->TryNamespace(wsNamespaceURI)) {\r
1150                 continue;\r
1151             }\r
1152             if(wsNamespaceURI == FX_WSTRC(L"http://ns.adobe.com/data-description/")) {\r
1153                 pDDRoot = pChildNode;\r
1154             }\r
1155         } else if(!pDataRoot && pChildNode->GetNameHash() == XFA_HASHCODE_Data) {\r
1156             if(!pChildNode->TryNamespace(wsNamespaceURI)) {\r
1157                 continue;\r
1158             }\r
1159             if(wsNamespaceURI == wsDatasetsURI) {\r
1160                 pDataRoot = pChildNode;\r
1161             }\r
1162         }\r
1163         if(pDataRoot && pDDRoot) {\r
1164             break;\r
1165         }\r
1166     }\r
1167     if(!pDataRoot) {\r
1168         IFDE_XMLElement* pDataRootXMLNode = IFDE_XMLElement::Create(FX_WSTRC(L"xfa:data"));\r
1169         FXSYS_assert(pDataRootXMLNode);\r
1170         pDataRoot = CreateNode(XFA_XDPPACKET_Datasets, XFA_ELEMENT_DataGroup);\r
1171         pDataRoot->SetCData(XFA_ATTRIBUTE_Name, FX_WSTRC(L"data"));\r
1172         pDataRoot->SetXMLMappingNode(pDataRootXMLNode);\r
1173         pDatasetsRoot->InsertChild(pDataRoot);\r
1174     }\r
1175     CXFA_Node* pDataTopLevel = pDataRoot->GetFirstChildByClass(XFA_ELEMENT_DataGroup);\r
1176     FX_DWORD dwNameHash = pDataTopLevel ? pDataTopLevel->GetNameHash() : 0;\r
1177     CXFA_Node* pTemplateChosen = dwNameHash != 0 ? pTemplateRoot->GetFirstChildByName(dwNameHash) : NULL;\r
1178     if(!pTemplateChosen || pTemplateChosen->GetClassID() != XFA_ELEMENT_Subform) {\r
1179         pTemplateChosen = pTemplateRoot->GetFirstChildByClass(XFA_ELEMENT_Subform);\r
1180     }\r
1181     if(!pTemplateChosen) {\r
1182         return;\r
1183     }\r
1184     CXFA_Node* pFormRoot = m_pRootNode->GetFirstChildByClass(XFA_ELEMENT_Form);\r
1185     FX_BOOL bEmptyForm = FALSE;\r
1186     if(!pFormRoot) {\r
1187         bEmptyForm = TRUE;\r
1188         pFormRoot = CreateNode(XFA_XDPPACKET_Form, XFA_ELEMENT_Form);\r
1189         FXSYS_assert(pFormRoot);\r
1190         pFormRoot->SetCData(XFA_ATTRIBUTE_Name, FX_WSTRC(L"form"));\r
1191         m_pRootNode->InsertChild(pFormRoot, NULL);\r
1192     } else {\r
1193         CXFA_NodeIteratorTemplate<CXFA_Node, CXFA_TraverseStrategy_XFANode> sIterator(pFormRoot);\r
1194         for(CXFA_Node *pNode = sIterator.MoveToNext(); pNode; pNode = sIterator.MoveToNext()) {\r
1195             pNode->SetFlag(XFA_NODEFLAG_UnusedNode);\r
1196         }\r
1197     }\r
1198     CXFA_Node* pSubformSetNode = XFA_NodeMerge_CloneOrMergeContainer(this, pFormRoot, pTemplateChosen, FALSE);\r
1199     FXSYS_assert(pSubformSetNode);\r
1200     if (!pDataTopLevel) {\r
1201         CFX_WideStringC wsFormName = pSubformSetNode->GetCData(XFA_ATTRIBUTE_Name);\r
1202         CFX_WideString wsDataTopLevelName = wsFormName.IsEmpty() ? FX_WSTRC(L"form") : wsFormName;\r
1203         IFDE_XMLElement* pDataTopLevelXMLNode = IFDE_XMLElement::Create(wsDataTopLevelName);\r
1204         FXSYS_assert(pDataTopLevelXMLNode);\r
1205         pDataTopLevel = CreateNode(XFA_XDPPACKET_Datasets, XFA_ELEMENT_DataGroup);\r
1206         pDataTopLevel->SetCData(XFA_ATTRIBUTE_Name, wsDataTopLevelName);\r
1207         pDataTopLevel->SetXMLMappingNode(pDataTopLevelXMLNode);\r
1208         CXFA_Node* pBeforeNode = pDataRoot->GetNodeItem(XFA_NODEITEM_FirstChild);\r
1209         pDataRoot->InsertChild(pDataTopLevel, pBeforeNode);\r
1210     }\r
1211     FXSYS_assert(pDataTopLevel);\r
1212     XFA_DataMerge_CreateDataBinding(pSubformSetNode, pDataTopLevel);\r
1213     for (CXFA_Node *pTemplateChild = pTemplateChosen->GetNodeItem(XFA_NODEITEM_FirstChild); pTemplateChild; pTemplateChild = pTemplateChild->GetNodeItem(XFA_NODEITEM_NextSibling)) {\r
1214         if (XFA_NeedGenerateForm(pTemplateChild)) {\r
1215             XFA_NodeMerge_CloneOrMergeContainer(this, pSubformSetNode, pTemplateChild, TRUE);\r
1216         } else if(pTemplateChild->GetObjectType() == XFA_OBJECTTYPE_ContainerNode) {\r
1217             DataMerge_CopyContainer(pTemplateChild, pSubformSetNode, pDataTopLevel);\r
1218         }\r
1219     }\r
1220     if(pDDRoot) {\r
1221         XFA_DataDescription_UpdateDataRelation(pDataRoot, pDDRoot);\r
1222     }\r
1223     DataMerge_UpdateBindingRelations(pSubformSetNode);\r
1224     CXFA_Node* pPageSetNode = pSubformSetNode->GetFirstChildByClass(XFA_ELEMENT_PageSet);\r
1225     while (pPageSetNode) {\r
1226         m_pPendingPageSet.Add(pPageSetNode);\r
1227         CXFA_Node* pNextPageSetNode = pPageSetNode->GetNextSameClassSibling(XFA_ELEMENT_PageSet);\r
1228         pSubformSetNode->RemoveChild(pPageSetNode);\r
1229         pPageSetNode = pNextPageSetNode;\r
1230     }\r
1231     if(!bEmptyForm) {\r
1232         CXFA_NodeIteratorTemplate<CXFA_Node, CXFA_TraverseStrategy_XFANode> sIterator(pFormRoot);\r
1233         CXFA_Node *pNode = sIterator.MoveToNext();\r
1234         while(pNode) {\r
1235             if(pNode->HasFlag(XFA_NODEFLAG_UnusedNode)) {\r
1236                 if(pNode->GetObjectType() == XFA_OBJECTTYPE_ContainerNode || pNode->GetClassID() == XFA_ELEMENT_InstanceManager) {\r
1237                     CXFA_Node* pNext = sIterator.SkipChildrenAndMoveToNext();\r
1238                     pNode->GetNodeItem(XFA_NODEITEM_Parent)->RemoveChild(pNode);\r
1239                     pNode = pNext;\r
1240                 } else {\r
1241                     pNode->SetFlag(XFA_NODEFLAG_UnusedNode, FALSE);\r
1242                     pNode->SetFlag(XFA_NODEFLAG_Initialized);\r
1243                     pNode = sIterator.MoveToNext();\r
1244                 }\r
1245             } else {\r
1246                 pNode->SetFlag(XFA_NODEFLAG_Initialized);\r
1247                 pNode = sIterator.MoveToNext();\r
1248             }\r
1249         }\r
1250     }\r
1251 }\r
1252 void CXFA_Document::DoDataRemerge(FX_BOOL bDoDataMerge)\r
1253 {\r
1254     CXFA_Node* pFormRoot = (CXFA_Node*)this->GetXFANode(XFA_HASHCODE_Form);\r
1255     if(pFormRoot) {\r
1256         while(CXFA_Node* pNode = pFormRoot->GetNodeItem(XFA_NODEITEM_FirstChild)) {\r
1257             pFormRoot->RemoveChild(pNode);\r
1258         }\r
1259         pFormRoot->SetObject(XFA_ATTRIBUTE_BindingNode, NULL);\r
1260     }\r
1261     XFA_DataMerge_ClearGlobalBinding(this);\r
1262     if (bDoDataMerge) {\r
1263         DoDataMerge();\r
1264     }\r
1265     CXFA_LayoutProcessor* pLayoutProcessor = GetLayoutProcessor();\r
1266     pLayoutProcessor->SetForceReLayout(TRUE);\r
1267 }\r