• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2014 PDFium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6 
7 #include "xfa/fxfa/cxfa_ffnotify.h"
8 
9 #include <memory>
10 #include <utility>
11 
12 #include "xfa/fxfa/cxfa_ffapp.h"
13 #include "xfa/fxfa/cxfa_ffarc.h"
14 #include "xfa/fxfa/cxfa_ffbarcode.h"
15 #include "xfa/fxfa/cxfa_ffcheckbutton.h"
16 #include "xfa/fxfa/cxfa_ffcombobox.h"
17 #include "xfa/fxfa/cxfa_ffdatetimeedit.h"
18 #include "xfa/fxfa/cxfa_ffdoc.h"
19 #include "xfa/fxfa/cxfa_ffdocview.h"
20 #include "xfa/fxfa/cxfa_ffdraw.h"
21 #include "xfa/fxfa/cxfa_ffexclgroup.h"
22 #include "xfa/fxfa/cxfa_fffield.h"
23 #include "xfa/fxfa/cxfa_ffimage.h"
24 #include "xfa/fxfa/cxfa_ffimageedit.h"
25 #include "xfa/fxfa/cxfa_ffline.h"
26 #include "xfa/fxfa/cxfa_fflistbox.h"
27 #include "xfa/fxfa/cxfa_ffnumericedit.h"
28 #include "xfa/fxfa/cxfa_ffpageview.h"
29 #include "xfa/fxfa/cxfa_ffpasswordedit.h"
30 #include "xfa/fxfa/cxfa_ffpushbutton.h"
31 #include "xfa/fxfa/cxfa_ffrectangle.h"
32 #include "xfa/fxfa/cxfa_ffsignature.h"
33 #include "xfa/fxfa/cxfa_ffsubform.h"
34 #include "xfa/fxfa/cxfa_fftext.h"
35 #include "xfa/fxfa/cxfa_ffwidget.h"
36 #include "xfa/fxfa/cxfa_ffwidgethandler.h"
37 #include "xfa/fxfa/cxfa_fwladapterwidgetmgr.h"
38 #include "xfa/fxfa/cxfa_textlayout.h"
39 #include "xfa/fxfa/cxfa_textprovider.h"
40 #include "xfa/fxfa/parser/cxfa_binditems.h"
41 #include "xfa/fxfa/parser/cxfa_node.h"
42 
43 namespace {
44 
ToListBox(CXFA_FFWidget * widget)45 CXFA_FFListBox* ToListBox(CXFA_FFWidget* widget) {
46   return static_cast<CXFA_FFListBox*>(widget);
47 }
48 
ToComboBox(CXFA_FFWidget * widget)49 CXFA_FFComboBox* ToComboBox(CXFA_FFWidget* widget) {
50   return static_cast<CXFA_FFComboBox*>(widget);
51 }
52 
53 }  // namespace
54 
CXFA_FFNotify(CXFA_FFDoc * pDoc)55 CXFA_FFNotify::CXFA_FFNotify(CXFA_FFDoc* pDoc) : m_pDoc(pDoc) {}
56 
~CXFA_FFNotify()57 CXFA_FFNotify::~CXFA_FFNotify() {}
58 
OnPageEvent(CXFA_ContainerLayoutItem * pSender,uint32_t dwEvent)59 void CXFA_FFNotify::OnPageEvent(CXFA_ContainerLayoutItem* pSender,
60                                 uint32_t dwEvent) {
61   CXFA_FFDocView* pDocView = m_pDoc->GetDocView(pSender->GetLayout());
62   if (pDocView)
63     pDocView->OnPageEvent(pSender, dwEvent);
64 }
65 
OnWidgetListItemAdded(CXFA_WidgetAcc * pSender,const wchar_t * pLabel,const wchar_t * pValue,int32_t iIndex)66 void CXFA_FFNotify::OnWidgetListItemAdded(CXFA_WidgetAcc* pSender,
67                                           const wchar_t* pLabel,
68                                           const wchar_t* pValue,
69                                           int32_t iIndex) {
70   if (pSender->GetUIType() != XFA_Element::ChoiceList)
71     return;
72 
73   CXFA_FFWidget* pWidget =
74       m_pDoc->GetDocView()->GetWidgetForNode(pSender->GetNode());
75   for (; pWidget; pWidget = pSender->GetNextWidget(pWidget)) {
76     if (pWidget->IsLoaded()) {
77       if (pSender->IsListBox())
78         ToListBox(pWidget)->InsertItem(pLabel, iIndex);
79       else
80         ToComboBox(pWidget)->InsertItem(pLabel, iIndex);
81     }
82   }
83 }
84 
OnWidgetListItemRemoved(CXFA_WidgetAcc * pSender,int32_t iIndex)85 void CXFA_FFNotify::OnWidgetListItemRemoved(CXFA_WidgetAcc* pSender,
86                                             int32_t iIndex) {
87   if (pSender->GetUIType() != XFA_Element::ChoiceList)
88     return;
89 
90   CXFA_FFWidget* pWidget =
91       m_pDoc->GetDocView()->GetWidgetForNode(pSender->GetNode());
92   for (; pWidget; pWidget = pSender->GetNextWidget(pWidget)) {
93     if (pWidget->IsLoaded()) {
94       if (pSender->IsListBox())
95         ToListBox(pWidget)->DeleteItem(iIndex);
96       else
97         ToComboBox(pWidget)->DeleteItem(iIndex);
98     }
99   }
100 }
101 
OnCreateContainerLayoutItem(CXFA_Node * pNode)102 CXFA_ContainerLayoutItem* CXFA_FFNotify::OnCreateContainerLayoutItem(
103     CXFA_Node* pNode) {
104   XFA_Element type = pNode->GetElementType();
105   ASSERT(type == XFA_Element::ContentArea || type == XFA_Element::PageArea);
106 
107   if (type == XFA_Element::PageArea) {
108     CXFA_LayoutProcessor* pLayout = m_pDoc->GetXFADoc()->GetDocLayout();
109     return new CXFA_FFPageView(m_pDoc->GetDocView(pLayout), pNode);
110   }
111   return new CXFA_ContainerLayoutItem(pNode);
112 }
113 
OnCreateContentLayoutItem(CXFA_Node * pNode)114 CXFA_ContentLayoutItem* CXFA_FFNotify::OnCreateContentLayoutItem(
115     CXFA_Node* pNode) {
116   ASSERT(pNode->GetElementType() != XFA_Element::ContentArea);
117   ASSERT(pNode->GetElementType() != XFA_Element::PageArea);
118 
119   // We only need to create the widget for certain types of objects.
120   if (!pNode->HasCreatedUIWidget())
121     return new CXFA_ContentLayoutItem(pNode);
122 
123   CXFA_FFWidget* pWidget;
124   switch (pNode->GetWidgetAcc()->GetUIType()) {
125     case XFA_Element::Barcode:
126       pWidget = new CXFA_FFBarcode(pNode);
127       break;
128     case XFA_Element::Button:
129       pWidget = new CXFA_FFPushButton(pNode);
130       break;
131     case XFA_Element::CheckButton:
132       pWidget = new CXFA_FFCheckButton(pNode);
133       break;
134     case XFA_Element::ChoiceList: {
135       if (pNode->GetWidgetAcc()->IsListBox())
136         pWidget = new CXFA_FFListBox(pNode);
137       else
138         pWidget = new CXFA_FFComboBox(pNode);
139     } break;
140     case XFA_Element::DateTimeEdit:
141       pWidget = new CXFA_FFDateTimeEdit(pNode);
142       break;
143     case XFA_Element::ImageEdit:
144       pWidget = new CXFA_FFImageEdit(pNode);
145       break;
146     case XFA_Element::NumericEdit:
147       pWidget = new CXFA_FFNumericEdit(pNode);
148       break;
149     case XFA_Element::PasswordEdit:
150       pWidget = new CXFA_FFPasswordEdit(pNode);
151       break;
152     case XFA_Element::Signature:
153       pWidget = new CXFA_FFSignature(pNode);
154       break;
155     case XFA_Element::TextEdit:
156       pWidget = new CXFA_FFTextEdit(pNode);
157       break;
158     case XFA_Element::Arc:
159       pWidget = new CXFA_FFArc(pNode);
160       break;
161     case XFA_Element::Line:
162       pWidget = new CXFA_FFLine(pNode);
163       break;
164     case XFA_Element::Rectangle:
165       pWidget = new CXFA_FFRectangle(pNode);
166       break;
167     case XFA_Element::Text:
168       pWidget = new CXFA_FFText(pNode);
169       break;
170     case XFA_Element::Image:
171       pWidget = new CXFA_FFImage(pNode);
172       break;
173     case XFA_Element::Draw:
174       pWidget = new CXFA_FFDraw(pNode);
175       break;
176     case XFA_Element::Subform:
177       pWidget = new CXFA_FFSubForm(pNode);
178       break;
179     case XFA_Element::ExclGroup:
180       pWidget = new CXFA_FFExclGroup(pNode);
181       break;
182     case XFA_Element::DefaultUi:
183     default:
184       pWidget = nullptr;
185       break;
186   }
187 
188   if (pWidget) {
189     CXFA_LayoutProcessor* pLayout = m_pDoc->GetXFADoc()->GetDocLayout();
190     pWidget->SetDocView(m_pDoc->GetDocView(pLayout));
191   }
192   return pWidget;
193 }
194 
StartFieldDrawLayout(CXFA_Node * pItem,float & fCalcWidth,float & fCalcHeight)195 void CXFA_FFNotify::StartFieldDrawLayout(CXFA_Node* pItem,
196                                          float& fCalcWidth,
197                                          float& fCalcHeight) {
198   CXFA_WidgetAcc* pAcc = pItem->GetWidgetAcc();
199   if (!pAcc)
200     return;
201 
202   pAcc->StartWidgetLayout(m_pDoc.Get(), fCalcWidth, fCalcHeight);
203 }
204 
FindSplitPos(CXFA_Node * pItem,int32_t iBlockIndex,float & fCalcHeightPos)205 bool CXFA_FFNotify::FindSplitPos(CXFA_Node* pItem,
206                                  int32_t iBlockIndex,
207                                  float& fCalcHeightPos) {
208   CXFA_WidgetAcc* pAcc = pItem->GetWidgetAcc();
209   return pAcc &&
210          pAcc->FindSplitPos(m_pDoc->GetDocView(), iBlockIndex, fCalcHeightPos);
211 }
212 
RunScript(CXFA_Script * script,CXFA_Node * item)213 bool CXFA_FFNotify::RunScript(CXFA_Script* script, CXFA_Node* item) {
214   CXFA_FFDocView* pDocView = m_pDoc->GetDocView();
215   if (!pDocView)
216     return false;
217 
218   CXFA_EventParam EventParam;
219   EventParam.m_eType = XFA_EVENT_Unknown;
220 
221   int32_t iRet;
222   bool bRet;
223   std::tie(iRet, bRet) = item->ExecuteBoolScript(pDocView, script, &EventParam);
224   return iRet == XFA_EVENTERROR_Success && bRet;
225 }
226 
ExecEventByDeepFirst(CXFA_Node * pFormNode,XFA_EVENTTYPE eEventType,bool bIsFormReady,bool bRecursive,CXFA_WidgetAcc * pExclude)227 int32_t CXFA_FFNotify::ExecEventByDeepFirst(CXFA_Node* pFormNode,
228                                             XFA_EVENTTYPE eEventType,
229                                             bool bIsFormReady,
230                                             bool bRecursive,
231                                             CXFA_WidgetAcc* pExclude) {
232   CXFA_FFDocView* pDocView = m_pDoc->GetDocView();
233   if (!pDocView)
234     return XFA_EVENTERROR_NotExist;
235   return pDocView->ExecEventActivityByDeepFirst(
236       pFormNode, eEventType, bIsFormReady, bRecursive,
237       pExclude ? pExclude->GetNode() : nullptr);
238 }
239 
AddCalcValidate(CXFA_Node * pNode)240 void CXFA_FFNotify::AddCalcValidate(CXFA_Node* pNode) {
241   CXFA_FFDocView* pDocView = m_pDoc->GetDocView();
242   if (!pDocView)
243     return;
244 
245   CXFA_WidgetAcc* pWidgetAcc = pNode->GetWidgetAcc();
246   if (!pWidgetAcc)
247     return;
248 
249   pDocView->AddCalculateWidgetAcc(pWidgetAcc);
250   pDocView->AddValidateWidget(pWidgetAcc);
251 }
252 
GetHDOC()253 CXFA_FFDoc* CXFA_FFNotify::GetHDOC() {
254   return m_pDoc.Get();
255 }
256 
GetDocEnvironment() const257 IXFA_DocEnvironment* CXFA_FFNotify::GetDocEnvironment() const {
258   return m_pDoc->GetDocEnvironment();
259 }
260 
GetAppProvider()261 IXFA_AppProvider* CXFA_FFNotify::GetAppProvider() {
262   return m_pDoc->GetApp()->GetAppProvider();
263 }
264 
GetWidgetHandler()265 CXFA_FFWidgetHandler* CXFA_FFNotify::GetWidgetHandler() {
266   CXFA_FFDocView* pDocView = m_pDoc->GetDocView();
267   return pDocView ? pDocView->GetWidgetHandler() : nullptr;
268 }
269 
GetHWidget(CXFA_LayoutItem * pLayoutItem)270 CXFA_FFWidget* CXFA_FFNotify::GetHWidget(CXFA_LayoutItem* pLayoutItem) {
271   return XFA_GetWidgetFromLayoutItem(pLayoutItem);
272 }
273 
OpenDropDownList(CXFA_FFWidget * hWidget)274 void CXFA_FFNotify::OpenDropDownList(CXFA_FFWidget* hWidget) {
275   if (hWidget->GetNode()->GetWidgetAcc()->GetUIType() !=
276       XFA_Element::ChoiceList)
277     return;
278 
279   CXFA_FFDocView* pDocView = m_pDoc->GetDocView();
280   pDocView->LockUpdate();
281   ToComboBox(hWidget)->OpenDropDownList();
282   pDocView->UnlockUpdate();
283   pDocView->UpdateDocView();
284 }
285 
GetCurrentDateTime()286 WideString CXFA_FFNotify::GetCurrentDateTime() {
287   CFX_DateTime dataTime = CFX_DateTime::Now();
288   return WideString::Format(L"%d%02d%02dT%02d%02d%02d", dataTime.GetYear(),
289                             dataTime.GetMonth(), dataTime.GetDay(),
290                             dataTime.GetHour(), dataTime.GetMinute(),
291                             dataTime.GetSecond());
292 }
293 
ResetData(CXFA_WidgetAcc * pWidgetAcc)294 void CXFA_FFNotify::ResetData(CXFA_WidgetAcc* pWidgetAcc) {
295   CXFA_FFDocView* pDocView = m_pDoc->GetDocView();
296   if (!pDocView)
297     return;
298 
299   pDocView->ResetWidgetAcc(pWidgetAcc);
300 }
301 
GetLayoutStatus()302 int32_t CXFA_FFNotify::GetLayoutStatus() {
303   CXFA_FFDocView* pDocView = m_pDoc->GetDocView();
304   return pDocView ? pDocView->GetLayoutStatus() : 0;
305 }
306 
RunNodeInitialize(CXFA_Node * pNode)307 void CXFA_FFNotify::RunNodeInitialize(CXFA_Node* pNode) {
308   CXFA_FFDocView* pDocView = m_pDoc->GetDocView();
309   if (!pDocView)
310     return;
311 
312   pDocView->AddNewFormNode(pNode);
313 }
314 
RunSubformIndexChange(CXFA_Node * pSubformNode)315 void CXFA_FFNotify::RunSubformIndexChange(CXFA_Node* pSubformNode) {
316   CXFA_FFDocView* pDocView = m_pDoc->GetDocView();
317   if (!pDocView)
318     return;
319 
320   pDocView->AddIndexChangedSubform(pSubformNode);
321 }
322 
GetFocusWidgetNode()323 CXFA_Node* CXFA_FFNotify::GetFocusWidgetNode() {
324   CXFA_FFDocView* pDocView = m_pDoc->GetDocView();
325   if (!pDocView)
326     return nullptr;
327 
328   CXFA_WidgetAcc* pAcc = pDocView->GetFocusWidgetAcc();
329   return pAcc ? pAcc->GetNode() : nullptr;
330 }
331 
SetFocusWidgetNode(CXFA_Node * pNode)332 void CXFA_FFNotify::SetFocusWidgetNode(CXFA_Node* pNode) {
333   CXFA_FFDocView* pDocView = m_pDoc->GetDocView();
334   if (!pDocView)
335     return;
336 
337   CXFA_WidgetAcc* pAcc = pNode ? pNode->GetWidgetAcc() : nullptr;
338   pDocView->SetFocusWidgetAcc(pAcc);
339 }
340 
OnNodeReady(CXFA_Node * pNode)341 void CXFA_FFNotify::OnNodeReady(CXFA_Node* pNode) {
342   CXFA_FFDocView* pDocView = m_pDoc->GetDocView();
343   if (!pDocView)
344     return;
345 
346   if (pNode->HasCreatedUIWidget()) {
347     pNode->CreateWidgetAcc();
348     return;
349   }
350 
351   switch (pNode->GetElementType()) {
352     case XFA_Element::BindItems:
353       pDocView->AddBindItem(static_cast<CXFA_BindItems*>(pNode));
354       break;
355     case XFA_Element::Validate:
356       pNode->SetFlag(XFA_NodeFlag_NeedsInitApp, false);
357       break;
358     default:
359       break;
360   }
361 }
362 
OnValueChanging(CXFA_Node * pSender,XFA_Attribute eAttr)363 void CXFA_FFNotify::OnValueChanging(CXFA_Node* pSender, XFA_Attribute eAttr) {
364   if (eAttr != XFA_Attribute::Presence)
365     return;
366   if (pSender->GetPacketType() == XFA_PacketType::Datasets)
367     return;
368   if (!pSender->IsFormContainer())
369     return;
370 
371   CXFA_FFDocView* pDocView = m_pDoc->GetDocView();
372   if (!pDocView)
373     return;
374   if (pDocView->GetLayoutStatus() < XFA_DOCVIEW_LAYOUTSTATUS_End)
375     return;
376 
377   CXFA_WidgetAcc* pWidgetAcc = pSender->GetWidgetAcc();
378   if (!pWidgetAcc)
379     return;
380 
381   CXFA_FFWidget* pWidget =
382       m_pDoc->GetDocView()->GetWidgetForNode(pWidgetAcc->GetNode());
383   for (; pWidget; pWidget = pWidgetAcc->GetNextWidget(pWidget)) {
384     if (pWidget->IsLoaded())
385       pWidget->AddInvalidateRect();
386   }
387 }
388 
OnValueChanged(CXFA_Node * pSender,XFA_Attribute eAttr,CXFA_Node * pParentNode,CXFA_Node * pWidgetNode)389 void CXFA_FFNotify::OnValueChanged(CXFA_Node* pSender,
390                                    XFA_Attribute eAttr,
391                                    CXFA_Node* pParentNode,
392                                    CXFA_Node* pWidgetNode) {
393   CXFA_FFDocView* pDocView = m_pDoc->GetDocView();
394   if (!pDocView)
395     return;
396 
397   if (pSender->GetPacketType() != XFA_PacketType::Form) {
398     if (eAttr == XFA_Attribute::Value)
399       pDocView->AddCalculateNodeNotify(pSender);
400     return;
401   }
402 
403   XFA_Element eType = pParentNode->GetElementType();
404   bool bIsContainerNode = pParentNode->IsContainerNode();
405   CXFA_WidgetAcc* pWidgetAcc = pWidgetNode->GetWidgetAcc();
406   if (!pWidgetAcc)
407     return;
408 
409   bool bUpdateProperty = false;
410   pDocView->SetChangeMark();
411   switch (eType) {
412     case XFA_Element::Caption: {
413       CXFA_TextLayout* pCapOut = pWidgetAcc->GetCaptionTextLayout();
414       if (!pCapOut)
415         return;
416 
417       pCapOut->Unload();
418       break;
419     }
420     case XFA_Element::Ui:
421     case XFA_Element::Para:
422       bUpdateProperty = true;
423       break;
424     default:
425       break;
426   }
427   if (bIsContainerNode && eAttr == XFA_Attribute::Access)
428     bUpdateProperty = true;
429 
430   if (eAttr == XFA_Attribute::Value) {
431     pDocView->AddCalculateNodeNotify(pSender);
432     if (eType == XFA_Element::Value || bIsContainerNode) {
433       if (bIsContainerNode) {
434         pWidgetAcc->UpdateUIDisplay(m_pDoc->GetDocView(), nullptr);
435         pDocView->AddCalculateWidgetAcc(pWidgetAcc);
436         pDocView->AddValidateWidget(pWidgetAcc);
437       } else if (pWidgetNode->GetParent()->GetElementType() ==
438                  XFA_Element::ExclGroup) {
439         pWidgetAcc->UpdateUIDisplay(m_pDoc->GetDocView(), nullptr);
440       }
441       return;
442     }
443   }
444 
445   CXFA_FFWidget* pWidget =
446       m_pDoc->GetDocView()->GetWidgetForNode(pWidgetAcc->GetNode());
447   for (; pWidget; pWidget = pWidgetAcc->GetNextWidget(pWidget)) {
448     if (!pWidget->IsLoaded())
449       continue;
450 
451     if (bUpdateProperty)
452       pWidget->UpdateWidgetProperty();
453     pWidget->PerformLayout();
454     pWidget->AddInvalidateRect();
455   }
456 }
457 
OnChildAdded(CXFA_Node * pSender)458 void CXFA_FFNotify::OnChildAdded(CXFA_Node* pSender) {
459   if (!pSender->IsFormContainer())
460     return;
461 
462   CXFA_FFDocView* pDocView = m_pDoc->GetDocView();
463   if (!pDocView)
464     return;
465 
466   bool bLayoutReady =
467       !(pDocView->m_bInLayoutStatus) &&
468       (pDocView->GetLayoutStatus() == XFA_DOCVIEW_LAYOUTSTATUS_End);
469   if (bLayoutReady)
470     m_pDoc->GetDocEnvironment()->SetChangeMark(m_pDoc.Get());
471 }
472 
OnChildRemoved()473 void CXFA_FFNotify::OnChildRemoved() {
474   CXFA_FFDocView* pDocView = m_pDoc->GetDocView();
475   if (!pDocView)
476     return;
477 
478   bool bLayoutReady =
479       !(pDocView->m_bInLayoutStatus) &&
480       (pDocView->GetLayoutStatus() == XFA_DOCVIEW_LAYOUTSTATUS_End);
481   if (bLayoutReady)
482     m_pDoc->GetDocEnvironment()->SetChangeMark(m_pDoc.Get());
483 }
484 
OnLayoutItemAdded(CXFA_LayoutProcessor * pLayout,CXFA_LayoutItem * pSender,int32_t iPageIdx,uint32_t dwStatus)485 void CXFA_FFNotify::OnLayoutItemAdded(CXFA_LayoutProcessor* pLayout,
486                                       CXFA_LayoutItem* pSender,
487                                       int32_t iPageIdx,
488                                       uint32_t dwStatus) {
489   CXFA_FFDocView* pDocView = m_pDoc->GetDocView(pLayout);
490   if (!pDocView)
491     return;
492 
493   CXFA_FFWidget* pWidget = XFA_GetWidgetFromLayoutItem(pSender);
494   if (!pWidget)
495     return;
496 
497   CXFA_FFPageView* pNewPageView = pDocView->GetPageView(iPageIdx);
498   uint32_t dwFilter = XFA_WidgetStatus_Visible | XFA_WidgetStatus_Viewable |
499                       XFA_WidgetStatus_Printable;
500   pWidget->ModifyStatus(dwStatus, dwFilter);
501   CXFA_FFPageView* pPrePageView = pWidget->GetPageView();
502   if (pPrePageView != pNewPageView ||
503       (dwStatus & (XFA_WidgetStatus_Visible | XFA_WidgetStatus_Viewable)) ==
504           (XFA_WidgetStatus_Visible | XFA_WidgetStatus_Viewable)) {
505     pWidget->SetPageView(pNewPageView);
506     m_pDoc->GetDocEnvironment()->WidgetPostAdd(
507         pWidget, pWidget->GetNode()->GetWidgetAcc());
508   }
509   if (pDocView->GetLayoutStatus() != XFA_DOCVIEW_LAYOUTSTATUS_End ||
510       !(dwStatus & XFA_WidgetStatus_Visible)) {
511     return;
512   }
513   if (pWidget->IsLoaded()) {
514     if (pWidget->GetWidgetRect() != pWidget->RecacheWidgetRect())
515       pWidget->PerformLayout();
516   } else {
517     pWidget->LoadWidget();
518   }
519   pWidget->AddInvalidateRect();
520 }
521 
OnLayoutItemRemoving(CXFA_LayoutProcessor * pLayout,CXFA_LayoutItem * pSender)522 void CXFA_FFNotify::OnLayoutItemRemoving(CXFA_LayoutProcessor* pLayout,
523                                          CXFA_LayoutItem* pSender) {
524   CXFA_FFDocView* pDocView = m_pDoc->GetDocView(pLayout);
525   if (!pDocView)
526     return;
527 
528   CXFA_FFWidget* pWidget = XFA_GetWidgetFromLayoutItem(pSender);
529   if (!pWidget)
530     return;
531 
532   pDocView->DeleteLayoutItem(pWidget);
533   m_pDoc->GetDocEnvironment()->WidgetPreRemove(
534       pWidget, pWidget->GetNode()->GetWidgetAcc());
535   pWidget->AddInvalidateRect();
536 }
537