2d6cc750463f33c4be73ab1806da11ca78955908
[pdfium.git] / xfa / src / fxfa / src / app / xfa_ffnotify.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_common.h"\r
9 #include "xfa_fwladapter.h"\r
10 #include "xfa_ffdocview.h"\r
11 #include "xfa_ffpageview.h"\r
12 #include "xfa_ffwidgethandler.h"\r
13 #include "xfa_ffdoc.h"\r
14 #include "xfa_ffwidget.h"\r
15 #include "xfa_fffield.h"\r
16 #include "xfa_ffpushbutton.h"\r
17 #include "xfa_ffcheckbutton.h"\r
18 #include "xfa_ffchoicelist.h"\r
19 #include "xfa_ffimageedit.h"\r
20 #include "xfa_fftextedit.h"\r
21 #include "xfa_ffbarcode.h"\r
22 #include "xfa_ffdraw.h"\r
23 #include "xfa_fftext.h"\r
24 #include "xfa_ffpath.h"\r
25 #include "xfa_ffimage.h"\r
26 #include "xfa_ffexclgroup.h"\r
27 #include "xfa_ffsubform.h"\r
28 #include "xfa_ffsignature.h"\r
29 #include "xfa_ffapp.h"\r
30 #include "xfa_textlayout.h"\r
31 #include "xfa_ffwidgetacc.h"\r
32 #include "xfa_ffnotify.h"\r
33 static void XFA_FFDeleteWidgetAcc(FX_LPVOID pData)\r
34 {\r
35     if (pData) {\r
36         delete (CXFA_WidgetAcc*)pData;\r
37     }\r
38 }\r
39 static XFA_MAPDATABLOCKCALLBACKINFO gs_XFADeleteWidgetAcc = {XFA_FFDeleteWidgetAcc, NULL};\r
40 CXFA_FFNotify::CXFA_FFNotify(CXFA_FFDoc* pDoc)\r
41     : m_pDoc(pDoc)\r
42 {\r
43 }\r
44 CXFA_FFNotify::~CXFA_FFNotify()\r
45 {\r
46 }\r
47 void CXFA_FFNotify::OnPageEvent(IXFA_LayoutPage *pSender, XFA_PAGEEVENT eEvent, FX_LPVOID pParam)\r
48 {\r
49     CXFA_FFDocView* pDocView = m_pDoc->GetDocView(pSender->GetLayout());\r
50     if (!pDocView) {\r
51         return;\r
52     }\r
53     pDocView->OnPageEvent(pSender, eEvent, (FX_INT32)(FX_UINTPTR)pParam);\r
54 }\r
55 void CXFA_FFNotify::OnNodeEvent(CXFA_Node *pSender, XFA_NODEEVENT eEvent, FX_LPVOID pParam , FX_LPVOID pParam2 , FX_LPVOID pParam3, FX_LPVOID pParam4)\r
56 {\r
57     switch (eEvent) {\r
58         case XFA_NODEEVENT_Ready:\r
59             OnNodeReady(pSender);\r
60             break;\r
61         case XFA_NODEEVENT_ValueChanging:\r
62             OnValueChanging(pSender, pParam, pParam2);\r
63             break;\r
64         case XFA_NODEEVENT_ValueChanged:\r
65             OnValueChanged(pSender, pParam, pParam2, pParam3, pParam4);\r
66             break;\r
67         case XFA_NODEEVENT_ChildAdded:\r
68             OnChildAdded(pSender, pParam, pParam2);\r
69             break;\r
70         case XFA_NODEEVENT_ChildRemoved:\r
71             OnChildRemoved(pSender, pParam, pParam2);\r
72             break;\r
73     }\r
74 }\r
75 void CXFA_FFNotify::OnWidgetDataEvent(CXFA_WidgetData* pSender, FX_DWORD dwEvent, FX_LPVOID pParam , FX_LPVOID pAdditional , FX_LPVOID pAdditional2 )\r
76 {\r
77     CXFA_WidgetAcc* pWidgetAcc = (CXFA_WidgetAcc*)pSender;\r
78     switch (dwEvent) {\r
79         case XFA_WIDGETEVENT_ListItemAdded: {\r
80                 if (pWidgetAcc->GetUIType() != XFA_ELEMENT_ChoiceList) {\r
81                     return;\r
82                 }\r
83                 FX_BOOL bStaticNotify = pWidgetAcc->GetDocView()->IsStaticNotify();\r
84                 CXFA_FFWidget* pWidget = pWidgetAcc->GetNextWidget(NULL);\r
85                 if (!pWidget) {\r
86                     if (bStaticNotify) {\r
87                         pWidgetAcc->GetDoc()->GetDocProvider()->WidgetEvent((XFA_HWIDGET)pWidget, pWidgetAcc, XFA_WIDGETEVENT_ListItemAdded, pParam, pAdditional);\r
88                     }\r
89                     return;\r
90                 }\r
91                 while (pWidget) {\r
92                     if (pWidget->IsLoaded()) {\r
93                         if (pWidgetAcc->IsListBox()) {\r
94                             ((CXFA_FFListBox*)pWidget)->InsertItem((FX_WSTR)(FX_LPCWSTR)pParam, (FX_INT32)(FX_UINTPTR)pAdditional2);\r
95                         } else {\r
96                             ((CXFA_FFComboBox*)pWidget)->InsertItem((FX_WSTR)(FX_LPCWSTR)pParam, (FX_INT32)(FX_UINTPTR)pAdditional2);\r
97                         }\r
98                     }\r
99                     if (bStaticNotify) {\r
100                         pWidgetAcc->GetDoc()->GetDocProvider()->WidgetEvent((XFA_HWIDGET)pWidget, pWidgetAcc, XFA_WIDGETEVENT_ListItemAdded, pParam, pAdditional);\r
101                     }\r
102                     pWidget = pWidgetAcc->GetNextWidget(pWidget);\r
103                 }\r
104             }\r
105             break;\r
106         case XFA_WIDGETEVENT_ListItemRemoved: {\r
107                 if (pWidgetAcc->GetUIType() != XFA_ELEMENT_ChoiceList) {\r
108                     return;\r
109                 }\r
110                 FX_BOOL bStaticNotify = pWidgetAcc->GetDocView()->IsStaticNotify();\r
111                 CXFA_FFWidget* pWidget = pWidgetAcc->GetNextWidget(NULL);\r
112                 if (!pWidget) {\r
113                     if (bStaticNotify) {\r
114                         pWidgetAcc->GetDoc()->GetDocProvider()->WidgetEvent((XFA_HWIDGET)pWidget, pWidgetAcc, XFA_WIDGETEVENT_ListItemRemoved, pParam, pAdditional);\r
115                     }\r
116                     return;\r
117                 }\r
118                 while (pWidget) {\r
119                     if (pWidget->IsLoaded()) {\r
120                         if (pWidgetAcc->IsListBox()) {\r
121                             ((CXFA_FFListBox*)pWidget)->DeleteItem((FX_INT32)(FX_UINTPTR)pParam);\r
122                         } else {\r
123                             ((CXFA_FFComboBox*)pWidget)->DeleteItem((FX_INT32)(FX_UINTPTR)pParam);\r
124                         }\r
125                     }\r
126                     if (bStaticNotify) {\r
127                         pWidgetAcc->GetDoc()->GetDocProvider()->WidgetEvent((XFA_HWIDGET)pWidget, pWidgetAcc, XFA_WIDGETEVENT_ListItemRemoved, pParam, pAdditional);\r
128                     }\r
129                     pWidget = pWidgetAcc->GetNextWidget(pWidget);\r
130                 }\r
131             }\r
132             break;\r
133     }\r
134 }\r
135 CXFA_LayoutItem* CXFA_FFNotify::OnCreateLayoutItem(CXFA_Node* pNode)\r
136 {\r
137     IXFA_DocLayout* pLayout = m_pDoc->GetXFADoc()->GetDocLayout();\r
138     CXFA_FFDocView* pDocView = m_pDoc->GetDocView(pLayout);\r
139     XFA_ELEMENT eType = pNode->GetClassID();\r
140     if (eType == XFA_ELEMENT_PageArea) {\r
141         return (CXFA_LayoutItem*)(FX_NEW CXFA_FFPageView(pDocView, pNode));\r
142     } else if (eType == XFA_ELEMENT_ContentArea) {\r
143         return (CXFA_LayoutItem*)(FX_NEW CXFA_ContainerLayoutItemImpl(pNode));\r
144     }\r
145     CXFA_WidgetAcc* pAcc = (CXFA_WidgetAcc*)pNode->GetWidgetData();\r
146     if (!pAcc) {\r
147         return (CXFA_LayoutItem*)(FX_NEW CXFA_ContentLayoutItemImpl(pNode));\r
148     }\r
149     CXFA_FFPageView* pPageView = NULL;\r
150     CXFA_FFWidget* pWidget = NULL;\r
151     switch(pAcc->GetUIType()) {\r
152         case XFA_ELEMENT_Barcode:\r
153             pWidget = FX_NEW CXFA_FFBarcode(pPageView, pAcc);\r
154             break;\r
155         case XFA_ELEMENT_Button:\r
156             pWidget = FX_NEW CXFA_FFPushButton(pPageView, pAcc);\r
157             break;\r
158         case XFA_ELEMENT_CheckButton:\r
159             pWidget = FX_NEW CXFA_FFCheckButton(pPageView, pAcc);\r
160             break;\r
161         case XFA_ELEMENT_ChoiceList: {\r
162                 if (pAcc->IsListBox()) {\r
163                     pWidget = FX_NEW CXFA_FFListBox(pPageView, pAcc);\r
164                 } else {\r
165                     pWidget = FX_NEW CXFA_FFComboBox(pPageView, pAcc);\r
166                 }\r
167             }\r
168             break;\r
169         case XFA_ELEMENT_DateTimeEdit:\r
170             pWidget = FX_NEW CXFA_FFDateTimeEdit(pPageView, pAcc);\r
171             break;\r
172         case XFA_ELEMENT_ImageEdit:\r
173             pWidget = FX_NEW CXFA_FFImageEdit(pPageView, pAcc);\r
174             break;\r
175         case XFA_ELEMENT_NumericEdit:\r
176             pWidget = FX_NEW CXFA_FFNumericEdit(pPageView, pAcc);\r
177             break;\r
178         case XFA_ELEMENT_PasswordEdit:\r
179             pWidget = FX_NEW CXFA_FFPasswordEdit(pPageView, pAcc);\r
180             break;\r
181         case XFA_ELEMENT_Signature:\r
182             pWidget = FX_NEW CXFA_FFSignature(pPageView, pAcc);\r
183             break;\r
184         case XFA_ELEMENT_TextEdit:\r
185             pWidget = FX_NEW CXFA_FFTextEdit(pPageView, pAcc);\r
186             break;\r
187         case XFA_ELEMENT_Arc:\r
188             pWidget = FX_NEW CXFA_FFArc(pPageView, pAcc);\r
189             break;\r
190         case XFA_ELEMENT_Line:\r
191             pWidget = FX_NEW CXFA_FFLine(pPageView, pAcc);\r
192             break;\r
193         case XFA_ELEMENT_Rectangle:\r
194             pWidget = FX_NEW CXFA_FFRectangle(pPageView, pAcc);\r
195             break;\r
196         case XFA_ELEMENT_Text:\r
197             pWidget = FX_NEW CXFA_FFText(pPageView, pAcc);\r
198             break;\r
199         case XFA_ELEMENT_Image:\r
200             pWidget = FX_NEW CXFA_FFImage(pPageView, pAcc);\r
201             break;\r
202         case XFA_ELEMENT_Draw:\r
203             pWidget = FX_NEW CXFA_FFDraw(pPageView, pAcc);\r
204             break;\r
205         case XFA_ELEMENT_Subform:\r
206             pWidget = FX_NEW CXFA_FFSubForm(pPageView, pAcc);\r
207             break;\r
208         case XFA_ELEMENT_ExclGroup:\r
209             pWidget = FX_NEW CXFA_FFExclGroup(pPageView, pAcc);\r
210             break;\r
211         case XFA_ELEMENT_DefaultUi:\r
212         default:\r
213             pWidget = NULL;\r
214             break;\r
215     }\r
216     if (!pWidget) {\r
217         return NULL;\r
218     }\r
219     pWidget->SetDocView(pDocView);\r
220     return pWidget->GetLayoutItem();\r
221 }\r
222 void CXFA_FFNotify::OnLayoutEvent(IXFA_DocLayout *pLayout, CXFA_LayoutItem *pSender, XFA_LAYOUTEVENT eEvent, FX_LPVOID pParam , FX_LPVOID pParam2 )\r
223 {\r
224     CXFA_FFDocView* pDocView = m_pDoc->GetDocView(pLayout);\r
225     if (!pDocView || !XFA_GetWidgetFromLayoutItem(pSender)) {\r
226         return;\r
227     }\r
228     switch (eEvent) {\r
229         case XFA_LAYOUTEVENT_ItemAdded:\r
230             OnLayoutItemAdd(pDocView, pLayout, pSender, pParam, pParam2);\r
231             break;\r
232         case XFA_LAYOUTEVENT_ItemRemoving:\r
233             OnLayoutItemRemoving(pDocView, pLayout, pSender, pParam, pParam2);\r
234             break;\r
235         case XFA_LAYOUTEVENT_RectChanged:\r
236             OnLayoutItemRectChanged(pDocView, pLayout, pSender, pParam, pParam2);\r
237             break;\r
238         case XFA_LAYOUTEVENT_StatusChanged:\r
239             OnLayoutItemStatustChanged(pDocView, pLayout, pSender, pParam, pParam2);\r
240             break;\r
241     }\r
242 }\r
243 void CXFA_FFNotify::StartFieldDrawLayout(CXFA_Node *pItem, FX_FLOAT &fCalcWidth, FX_FLOAT &fCalcHeight)\r
244 {\r
245     CXFA_WidgetAcc *pAcc = (CXFA_WidgetAcc*)pItem->GetWidgetData();\r
246     if (!pAcc) {\r
247         return;\r
248     }\r
249     pAcc->StartWidgetLayout(fCalcWidth, fCalcHeight);\r
250 }\r
251 FX_BOOL CXFA_FFNotify::FindSplitPos(CXFA_Node *pItem, FX_INT32 iBlockIndex, FX_FLOAT &fCalcHeightPos)\r
252 {\r
253     CXFA_WidgetAcc *pAcc = (CXFA_WidgetAcc*)pItem->GetWidgetData();\r
254     if (!pAcc) {\r
255         return FALSE;\r
256     }\r
257     return (XFA_LAYOUTRESULT)pAcc->FindSplitPos(iBlockIndex, fCalcHeightPos);\r
258 }\r
259 FX_BOOL CXFA_FFNotify::RunScript(CXFA_Node* pScript, CXFA_Node* pFormItem)\r
260 {\r
261     FX_BOOL bRet = FALSE;\r
262     CXFA_FFDocView* pDocView = m_pDoc->GetDocView();\r
263     if (!pDocView) {\r
264         return bRet;\r
265     }\r
266     CXFA_WidgetAcc* pWidgetAcc = (CXFA_WidgetAcc*)pFormItem->GetWidgetData();\r
267     if (!pWidgetAcc) {\r
268         return bRet;\r
269     }\r
270     CXFA_EventParam EventParam;\r
271     EventParam.m_eType = XFA_EVENT_Unknown;\r
272     FXJSE_HVALUE pRetValue = NULL;\r
273     FX_INT32 iRet = pWidgetAcc->ExecuteScript(CXFA_Script(pScript), &EventParam, &pRetValue);\r
274     if (iRet == XFA_EVENTERROR_Sucess && pRetValue) {\r
275         bRet = FXJSE_Value_ToBoolean(pRetValue);\r
276         FXJSE_Value_Release(pRetValue);\r
277     }\r
278     return bRet;\r
279 }\r
280 FX_INT32 CXFA_FFNotify::ExecEventByDeepFirst(CXFA_Node* pFormNode, XFA_EVENTTYPE eEventType, FX_BOOL bIsFormReady, FX_BOOL bRecursive, CXFA_WidgetAcc* pExclude)\r
281 {\r
282     CXFA_FFDocView* pDocView = m_pDoc->GetDocView();\r
283     if (!pDocView) {\r
284         return XFA_EVENTERROR_NotExist;\r
285     }\r
286     return pDocView->ExecEventActivityByDeepFirst(pFormNode, eEventType, bIsFormReady, bRecursive, pExclude ? pExclude->GetNode() : NULL);\r
287 }\r
288 void CXFA_FFNotify::AddCalcValidate(CXFA_Node* pNode)\r
289 {\r
290     CXFA_FFDocView* pDocView = m_pDoc->GetDocView();\r
291     if (!pDocView) {\r
292         return;\r
293     }\r
294     CXFA_WidgetAcc* pWidgetAcc = (CXFA_WidgetAcc*)pNode->GetWidgetData();\r
295     if (!pWidgetAcc) {\r
296         return;\r
297     }\r
298     pDocView->AddCalculateWidgetAcc(pWidgetAcc);\r
299     pDocView->AddValidateWidget(pWidgetAcc);\r
300 }\r
301 IXFA_Doc* CXFA_FFNotify::GetHDOC()\r
302 {\r
303     return m_pDoc;\r
304 }\r
305 IXFA_DocProvider* CXFA_FFNotify::GetDocProvider()\r
306 {\r
307     return m_pDoc->GetDocProvider();\r
308 }\r
309 IXFA_AppProvider* CXFA_FFNotify::GetAppProvider()\r
310 {\r
311     return m_pDoc->GetApp()->GetAppProvider();\r
312 }\r
313 IXFA_WidgetHandler* CXFA_FFNotify::GetWidgetHandler()\r
314 {\r
315     CXFA_FFDocView* pDocView = m_pDoc->GetDocView();\r
316     return pDocView ? pDocView->GetWidgetHandler() : NULL;\r
317 }\r
318 XFA_HWIDGET     CXFA_FFNotify::GetHWidget(CXFA_LayoutItem* pLayoutItem)\r
319 {\r
320     return (XFA_HWIDGET)XFA_GetWidgetFromLayoutItem(pLayoutItem);\r
321 }\r
322 void CXFA_FFNotify::OpenDropDownList(XFA_HWIDGET hWidget)\r
323 {\r
324     CXFA_FFWidget* pWidget = (CXFA_FFWidget*)hWidget;\r
325     if (pWidget->GetDataAcc()->GetUIType() != XFA_ELEMENT_ChoiceList) {\r
326         return;\r
327     }\r
328     CXFA_FFDocView* pDocView = m_pDoc->GetDocView();\r
329     pDocView->LockUpdate();\r
330     ((CXFA_FFComboBox*)pWidget)->OpenDropDownList();\r
331     pDocView->UnlockUpdate();\r
332     pDocView->UpdateDocView();\r
333 }\r
334 CFX_WideString CXFA_FFNotify::GetCurrentDateTime()\r
335 {\r
336     CFX_Unitime dataTime;\r
337     dataTime.Now();\r
338     CFX_WideString wsDateTime;\r
339     wsDateTime.Format(L"%d%02d%02dT%02d%02d%02d", dataTime.GetYear(), dataTime.GetMonth(), dataTime.GetDay(), dataTime.GetHour(), dataTime.GetMinute(), dataTime.GetSecond());\r
340     return wsDateTime;\r
341 }\r
342 void CXFA_FFNotify::ResetData(CXFA_WidgetData* pWidgetData)\r
343 {\r
344     CXFA_FFDocView* pDocView = m_pDoc->GetDocView();\r
345     if (!pDocView) {\r
346         return;\r
347     }\r
348     pDocView->ResetWidgetData((CXFA_WidgetAcc*)pWidgetData);\r
349 }\r
350 FX_INT32 CXFA_FFNotify::GetLayoutStatus()\r
351 {\r
352     CXFA_FFDocView* pDocView = m_pDoc->GetDocView();\r
353     return pDocView ? pDocView->GetLayoutStatus() : 0;\r
354 }\r
355 void CXFA_FFNotify::RunNodeInitialize(CXFA_Node* pNode)\r
356 {\r
357     CXFA_FFDocView* pDocView = m_pDoc->GetDocView();\r
358     if (!pDocView) {\r
359         return;\r
360     }\r
361     pDocView->AddNewFormNode(pNode);\r
362 }\r
363 void CXFA_FFNotify::RunSubformIndexChange(CXFA_Node* pSubformNode)\r
364 {\r
365     CXFA_FFDocView* pDocView = m_pDoc->GetDocView();\r
366     if (!pDocView) {\r
367         return;\r
368     }\r
369     pDocView->AddIndexChangedSubform(pSubformNode);\r
370 }\r
371 CXFA_Node* CXFA_FFNotify::GetFocusWidgetNode()\r
372 {\r
373     CXFA_FFDocView* pDocView = m_pDoc->GetDocView();\r
374     if (!pDocView) {\r
375         return NULL;\r
376     }\r
377     CXFA_WidgetAcc* pAcc = pDocView->GetFocusWidgetAcc();\r
378     return pAcc ? pAcc->GetNode() : NULL;\r
379 }\r
380 void CXFA_FFNotify::SetFocusWidgetNode(CXFA_Node* pNode)\r
381 {\r
382     CXFA_FFDocView* pDocView = m_pDoc->GetDocView();\r
383     if (!pDocView) {\r
384         return;\r
385     }\r
386     CXFA_WidgetAcc* pAcc = pNode ? (CXFA_WidgetAcc*)pNode->GetWidgetData() : NULL;\r
387     pDocView->SetFocusWidgetAcc(pAcc);\r
388 }\r
389 void CXFA_FFNotify::OnNodeReady(CXFA_Node *pNode)\r
390 {\r
391     CXFA_FFDocView* pDocView = m_pDoc->GetDocView();\r
392     if (!pDocView) {\r
393         return;\r
394     }\r
395     XFA_ELEMENT iType = pNode->GetClassID();\r
396     if (XFA_IsCreateWidget(iType)) {\r
397         CXFA_WidgetAcc* pAcc = FX_NEW CXFA_WidgetAcc(pDocView, (CXFA_Node*)pNode);\r
398         pNode->SetObject(XFA_ATTRIBUTE_WidgetData, pAcc, &gs_XFADeleteWidgetAcc);\r
399         return;\r
400     }\r
401     switch (iType) {\r
402         case XFA_ELEMENT_BindItems:\r
403             pDocView->m_bindItems.Add(pNode);\r
404             break;\r
405         case XFA_ELEMENT_Validate: {\r
406                 pNode->SetFlag(XFA_NODEFLAG_NeedsInitApp, TRUE, FALSE);\r
407             }\r
408             break;\r
409         default:\r
410             break;\r
411     }\r
412 }\r
413 void CXFA_FFNotify::OnValueChanging(CXFA_Node *pSender, FX_LPVOID pParam, FX_LPVOID pParam2)\r
414 {\r
415     CXFA_FFDocView* pDocView = m_pDoc->GetDocView();\r
416     if (!pDocView) {\r
417         return;\r
418     }\r
419     if (pDocView->GetLayoutStatus() < XFA_DOCVIEW_LAYOUTSTATUS_End) {\r
420         return;\r
421     }\r
422     FX_DWORD dwPacket = pSender->GetPacketID();\r
423     if (dwPacket & XFA_XDPPACKET_Datasets) {\r
424     } else if (pSender->IsFormContainer()) {\r
425         XFA_ATTRIBUTE eAttr = (XFA_ATTRIBUTE)(FX_UINTPTR)pParam;\r
426         if (eAttr == XFA_ATTRIBUTE_Presence) {\r
427             CXFA_WidgetAcc* pWidgetAcc = (CXFA_WidgetAcc*)pSender->GetWidgetData();\r
428             if (!pWidgetAcc) {\r
429                 return;\r
430             }\r
431             CXFA_FFWidget* pWidget = NULL;\r
432             while ((pWidget = pWidgetAcc->GetNextWidget(pWidget)) != NULL) {\r
433                 if (pWidget->IsLoaded()) {\r
434                     pWidget->AddInvalidateRect();\r
435                 }\r
436             }\r
437         }\r
438     }\r
439 }\r
440 void CXFA_FFNotify::OnValueChanged(CXFA_Node *pSender, FX_LPVOID pParam, FX_LPVOID pParam2, FX_LPVOID pParam3, FX_LPVOID pParam4)\r
441 {\r
442     CXFA_FFDocView* pDocView = m_pDoc->GetDocView();\r
443     if (!pDocView) {\r
444         return;\r
445     }\r
446     FX_DWORD dwPacket = pSender->GetPacketID();\r
447     XFA_ATTRIBUTE eAttr = (XFA_ATTRIBUTE)(FX_UINTPTR)pParam;\r
448     if (dwPacket & XFA_XDPPACKET_Form) {\r
449         CXFA_Node* pParentNode = (CXFA_Node*)pParam3;\r
450         CXFA_Node* pWidgetNode = (CXFA_Node*)pParam4;\r
451         XFA_ELEMENT ePType = pParentNode->GetClassID();\r
452         FX_BOOL bIsContainerNode = pParentNode->IsContainerNode();\r
453         CXFA_WidgetAcc* pWidgetAcc = (CXFA_WidgetAcc*)pWidgetNode->GetWidgetData();\r
454         if (!pWidgetAcc) {\r
455             return;\r
456         }\r
457         FX_BOOL bUpdateProperty = FALSE;\r
458         pDocView->SetChangeMark();\r
459         switch (ePType) {\r
460             case XFA_ELEMENT_Caption: {\r
461                     CXFA_TextLayout* pCapOut = pWidgetAcc->GetCaptionTextLayout();\r
462                     if (!pCapOut) {\r
463                         return;\r
464                     }\r
465                     pCapOut->Unload();\r
466                 }\r
467                 break;\r
468             case XFA_ELEMENT_Ui:\r
469             case XFA_ELEMENT_Para:\r
470                 bUpdateProperty = TRUE;\r
471                 break;\r
472             case XFA_ELEMENT_Font:\r
473             case XFA_ELEMENT_Margin:\r
474             case XFA_ELEMENT_Value:\r
475             case XFA_ELEMENT_Items:\r
476                 break;\r
477             default:\r
478                 break;\r
479         }\r
480         if (bIsContainerNode && eAttr == XFA_ATTRIBUTE_Access) {\r
481             bUpdateProperty = TRUE;\r
482             FX_BOOL bNotify = pDocView->IsStaticNotify();\r
483             if (bNotify) {\r
484                 pWidgetAcc->NotifyEvent(XFA_WIDGETEVENT_AccessChanged, NULL, pParam2, NULL);\r
485             }\r
486         }\r
487         if (eAttr == XFA_ATTRIBUTE_Value) {\r
488             pDocView->AddCalculateNodeNotify(pSender);\r
489             if (ePType == XFA_ELEMENT_Value || bIsContainerNode) {\r
490                 FX_BOOL bNotify = pDocView->IsStaticNotify();\r
491                 if (bIsContainerNode) {\r
492                     pWidgetAcc->UpdateUIDisplay();\r
493                     pDocView->AddCalculateWidgetAcc(pWidgetAcc);\r
494                     pDocView->AddValidateWidget(pWidgetAcc);\r
495                 } else if (pWidgetNode->GetNodeItem(XFA_NODEITEM_Parent)->GetClassID() == XFA_ELEMENT_ExclGroup) {\r
496                     pWidgetAcc->UpdateUIDisplay();\r
497                 }\r
498                 if (bNotify) {\r
499                     pWidgetAcc->NotifyEvent(XFA_WIDGETEVENT_PostContentChanged, NULL, NULL, NULL);\r
500                 }\r
501                 return;\r
502             }\r
503         }\r
504         CXFA_FFWidget* pWidget = NULL;\r
505         while ((pWidget = pWidgetAcc->GetNextWidget(pWidget)) != NULL) {\r
506             if (!pWidget->IsLoaded()) {\r
507                 continue;\r
508             }\r
509             if (bUpdateProperty) {\r
510                 pWidget->UpdateWidgetProperty();\r
511             }\r
512             pWidget->LayoutWidget();\r
513             pWidget->AddInvalidateRect();\r
514         }\r
515     } else {\r
516         if (eAttr == XFA_ATTRIBUTE_Value) {\r
517             pDocView->AddCalculateNodeNotify(pSender);\r
518         }\r
519     }\r
520 }\r
521 void CXFA_FFNotify::OnChildAdded(CXFA_Node *pSender, FX_LPVOID pParam, FX_LPVOID pParam2)\r
522 {\r
523     if (!pSender->IsFormContainer()) {\r
524         return;\r
525     }\r
526     CXFA_FFDocView* pDocView = m_pDoc->GetDocView();\r
527     if (!pDocView) {\r
528         return;\r
529     }\r
530     FX_BOOL bLayoutReady = !(pDocView->m_bInLayoutStatus) && (pDocView->GetLayoutStatus() >= XFA_DOCVIEW_LAYOUTSTATUS_End);\r
531     if (bLayoutReady) {\r
532         m_pDoc->GetDocProvider()->SetChangeMark(m_pDoc);\r
533     }\r
534 }\r
535 void CXFA_FFNotify::OnChildRemoved(CXFA_Node *pSender, FX_LPVOID pParam, FX_LPVOID pParam2)\r
536 {\r
537     if (CXFA_FFDocView* pDocView = m_pDoc->GetDocView()) {\r
538         FX_BOOL bLayoutReady = !(pDocView->m_bInLayoutStatus) && (pDocView->GetLayoutStatus() >= XFA_DOCVIEW_LAYOUTSTATUS_End);\r
539         if (bLayoutReady) {\r
540             m_pDoc->GetDocProvider()->SetChangeMark(m_pDoc);\r
541         }\r
542     }\r
543 }\r
544 void CXFA_FFNotify::OnLayoutItemAdd(CXFA_FFDocView* pDocView, IXFA_DocLayout *pLayout, CXFA_LayoutItem *pSender, FX_LPVOID pParam, FX_LPVOID pParam2)\r
545 {\r
546     CXFA_FFWidget* pWidget = (CXFA_FFWidget*)(CXFA_ContentLayoutItemImpl*)pSender;\r
547     FX_INT32 iPageIdx = (FX_INT32)(FX_UINTPTR)pParam;\r
548     IXFA_PageView* pNewPageView = pDocView->GetPageView(iPageIdx);\r
549     FX_DWORD dwStatus = (FX_DWORD)(FX_UINTPTR)pParam2;\r
550     FX_DWORD dwFilter = XFA_WIDGETSTATUS_Visible | XFA_WIDGETSTATUS_Viewable | XFA_WIDGETSTATUS_Printable;\r
551     pWidget->ModifyStatus(dwStatus, dwFilter);\r
552     if (pDocView->GetLayoutStatus() >= XFA_DOCVIEW_LAYOUTSTATUS_End) {\r
553         IXFA_PageView* pPrePageView = pWidget->GetPageView();\r
554         if (pPrePageView != pNewPageView || (dwStatus & (XFA_WIDGETSTATUS_Visible | XFA_WIDGETSTATUS_Viewable)) == (XFA_WIDGETSTATUS_Visible | XFA_WIDGETSTATUS_Viewable)) {\r
555             pWidget->SetPageView(pNewPageView);\r
556             m_pDoc->GetDocProvider()->WidgetEvent((XFA_HWIDGET)pWidget, pWidget->GetDataAcc(), XFA_WIDGETEVENT_PostAdded, pNewPageView, pPrePageView);\r
557         }\r
558         if ((dwStatus & XFA_WIDGETSTATUS_Visible) == 0) {\r
559             return;\r
560         }\r
561         if (pWidget->IsLoaded()) {\r
562             CFX_RectF rtOld;\r
563             pWidget->GetWidgetRect(rtOld);\r
564             CFX_RectF rtNew = pWidget->ReCacheWidgetRect();\r
565             if(rtOld != rtNew) {\r
566                 pWidget->LayoutWidget();\r
567             }\r
568         } else {\r
569             pWidget->LoadWidget();\r
570         }\r
571         pWidget->AddInvalidateRect(NULL);\r
572     } else {\r
573         pWidget->SetPageView(pNewPageView);\r
574     }\r
575 }\r
576 void CXFA_FFNotify::OnLayoutItemRemoving(CXFA_FFDocView* pDocView, IXFA_DocLayout *pLayout, CXFA_LayoutItem *pSender, FX_LPVOID pParam, FX_LPVOID pParam2)\r
577 {\r
578     CXFA_FFWidget* pWidget = (CXFA_FFWidget*)pSender;\r
579     pDocView->DeleteLayoutItem(pWidget);\r
580     if (pDocView->GetLayoutStatus() < XFA_DOCVIEW_LAYOUTSTATUS_End) {\r
581         return;\r
582     }\r
583     m_pDoc->GetDocProvider()->WidgetEvent((XFA_HWIDGET)pWidget, pWidget->GetDataAcc(), XFA_WIDGETEVENT_PreRemoved, NULL, NULL);\r
584     pWidget->AddInvalidateRect(NULL);\r
585 }\r
586 void CXFA_FFNotify::OnLayoutItemRectChanged(CXFA_FFDocView* pDocView, IXFA_DocLayout *pLayout, CXFA_LayoutItem *pSender, FX_LPVOID pParam, FX_LPVOID pParam2)\r
587 {\r
588 }\r
589 void CXFA_FFNotify::OnLayoutItemStatustChanged(CXFA_FFDocView* pDocView, IXFA_DocLayout *pLayout, CXFA_LayoutItem *pSender, FX_LPVOID pParam, FX_LPVOID pParam2)\r
590 {\r
591     CXFA_FFWidget* pWidget = (CXFA_FFWidget*)(CXFA_ContentLayoutItemImpl*)pSender;\r
592     if (!pWidget) {\r
593         return;\r
594     }\r
595     FX_DWORD dwStatus = (FX_DWORD)(FX_UINTPTR)pParam;\r
596     if (dwStatus == 0) {\r
597         CXFA_LayoutItem* pPreItem = pSender->GetPrev();\r
598         if (pPreItem) {\r
599             CXFA_FFWidget* pPreWidget = (CXFA_FFWidget*)(CXFA_ContentLayoutItemImpl*)pPreItem;\r
600             if (pPreWidget) {\r
601                 dwStatus = pPreWidget->GetStatus();\r
602             }\r
603         }\r
604     }\r
605     FX_DWORD dwOldStatus = pWidget->GetStatus();\r
606     FX_DWORD dwFilter = XFA_WIDGETSTATUS_Visible | XFA_WIDGETSTATUS_Viewable | XFA_WIDGETSTATUS_Printable;\r
607     if ((dwOldStatus & dwFilter) == dwStatus) {\r
608         return;\r
609     }\r
610     pWidget->ModifyStatus(dwStatus, dwFilter);\r
611 }\r