1 // Copyright 2014 The PDFium Authors
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 <utility>
10
11 #include "third_party/base/check.h"
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_ffexclgroup.h"
21 #include "xfa/fxfa/cxfa_fffield.h"
22 #include "xfa/fxfa/cxfa_ffimage.h"
23 #include "xfa/fxfa/cxfa_ffimageedit.h"
24 #include "xfa/fxfa/cxfa_ffline.h"
25 #include "xfa/fxfa/cxfa_fflistbox.h"
26 #include "xfa/fxfa/cxfa_ffnumericedit.h"
27 #include "xfa/fxfa/cxfa_ffpageview.h"
28 #include "xfa/fxfa/cxfa_ffpasswordedit.h"
29 #include "xfa/fxfa/cxfa_ffpushbutton.h"
30 #include "xfa/fxfa/cxfa_ffrectangle.h"
31 #include "xfa/fxfa/cxfa_ffsignature.h"
32 #include "xfa/fxfa/cxfa_fftext.h"
33 #include "xfa/fxfa/cxfa_ffwidget.h"
34 #include "xfa/fxfa/cxfa_ffwidgethandler.h"
35 #include "xfa/fxfa/cxfa_fwladapterwidgetmgr.h"
36 #include "xfa/fxfa/cxfa_textlayout.h"
37 #include "xfa/fxfa/cxfa_textprovider.h"
38 #include "xfa/fxfa/layout/cxfa_layoutprocessor.h"
39 #include "xfa/fxfa/parser/cxfa_barcode.h"
40 #include "xfa/fxfa/parser/cxfa_binditems.h"
41 #include "xfa/fxfa/parser/cxfa_button.h"
42 #include "xfa/fxfa/parser/cxfa_checkbutton.h"
43 #include "xfa/fxfa/parser/cxfa_node.h"
44 #include "xfa/fxfa/parser/cxfa_passwordedit.h"
45
CXFA_FFNotify(CXFA_FFDoc * pDoc)46 CXFA_FFNotify::CXFA_FFNotify(CXFA_FFDoc* pDoc) : m_pDoc(pDoc) {}
47
48 CXFA_FFNotify::~CXFA_FFNotify() = default;
49
Trace(cppgc::Visitor * visitor) const50 void CXFA_FFNotify::Trace(cppgc::Visitor* visitor) const {
51 visitor->Trace(m_pDoc);
52 }
53
OnPageViewEvent(CXFA_ViewLayoutItem * pSender,CXFA_FFDoc::PageViewEvent eEvent)54 void CXFA_FFNotify::OnPageViewEvent(CXFA_ViewLayoutItem* pSender,
55 CXFA_FFDoc::PageViewEvent eEvent) {
56 CXFA_FFDocView* pDocView = m_pDoc->GetDocView(pSender->GetLayout());
57 if (pDocView)
58 pDocView->OnPageViewEvent(pSender, eEvent);
59 }
60
OnWidgetListItemAdded(CXFA_Node * pSender,const WideString & wsLabel,int32_t iIndex)61 void CXFA_FFNotify::OnWidgetListItemAdded(CXFA_Node* pSender,
62 const WideString& wsLabel,
63 int32_t iIndex) {
64 if (pSender->GetFFWidgetType() != XFA_FFWidgetType::kChoiceList)
65 return;
66
67 CXFA_FFWidget* pWidget = m_pDoc->GetDocView()->GetWidgetForNode(pSender);
68 for (; pWidget; pWidget = pWidget->GetNextFFWidget()) {
69 if (pWidget->IsLoaded())
70 ToDropDown(ToField(pWidget))->InsertItem(wsLabel, iIndex);
71 }
72 }
73
OnWidgetListItemRemoved(CXFA_Node * pSender,int32_t iIndex)74 void CXFA_FFNotify::OnWidgetListItemRemoved(CXFA_Node* pSender,
75 int32_t iIndex) {
76 if (pSender->GetFFWidgetType() != XFA_FFWidgetType::kChoiceList)
77 return;
78
79 CXFA_FFWidget* pWidget = m_pDoc->GetDocView()->GetWidgetForNode(pSender);
80 for (; pWidget; pWidget = pWidget->GetNextFFWidget()) {
81 if (pWidget->IsLoaded())
82 ToDropDown(ToField(pWidget))->DeleteItem(iIndex);
83 }
84 }
85
OnCreateViewLayoutItem(CXFA_Node * pNode)86 CXFA_FFPageView* CXFA_FFNotify::OnCreateViewLayoutItem(CXFA_Node* pNode) {
87 if (pNode->GetElementType() != XFA_Element::PageArea)
88 return nullptr;
89
90 auto* pLayout = CXFA_LayoutProcessor::FromDocument(m_pDoc->GetXFADoc());
91 return cppgc::MakeGarbageCollected<CXFA_FFPageView>(
92 m_pDoc->GetHeap()->GetAllocationHandle(), m_pDoc->GetDocView(pLayout),
93 pNode);
94 }
95
OnCreateContentLayoutItem(CXFA_Node * pNode)96 CXFA_FFWidget* CXFA_FFNotify::OnCreateContentLayoutItem(CXFA_Node* pNode) {
97 DCHECK(pNode->GetElementType() != XFA_Element::ContentArea);
98 DCHECK(pNode->GetElementType() != XFA_Element::PageArea);
99
100 // We only need to create the widget for certain types of objects.
101 if (!pNode->HasCreatedUIWidget())
102 return nullptr;
103
104 CXFA_FFWidget* pWidget = nullptr;
105 switch (pNode->GetFFWidgetType()) {
106 case XFA_FFWidgetType::kBarcode: {
107 auto* child = CXFA_Barcode::FromNode(pNode->GetUIChildNode());
108 if (!child)
109 return nullptr;
110
111 pWidget = cppgc::MakeGarbageCollected<CXFA_FFBarcode>(
112 m_pDoc->GetHeap()->GetAllocationHandle(), pNode, child);
113 break;
114 }
115 case XFA_FFWidgetType::kButton: {
116 auto* child = CXFA_Button::FromNode(pNode->GetUIChildNode());
117 if (!child)
118 return nullptr;
119
120 pWidget = cppgc::MakeGarbageCollected<CXFA_FFPushButton>(
121 m_pDoc->GetHeap()->GetAllocationHandle(), pNode, child);
122 break;
123 }
124 case XFA_FFWidgetType::kCheckButton: {
125 auto* child = CXFA_CheckButton::FromNode(pNode->GetUIChildNode());
126 if (!child)
127 return nullptr;
128
129 pWidget = cppgc::MakeGarbageCollected<CXFA_FFCheckButton>(
130 m_pDoc->GetHeap()->GetAllocationHandle(), pNode, child);
131 break;
132 }
133 case XFA_FFWidgetType::kChoiceList: {
134 if (pNode->IsListBox()) {
135 pWidget = cppgc::MakeGarbageCollected<CXFA_FFListBox>(
136 m_pDoc->GetHeap()->GetAllocationHandle(), pNode);
137 } else {
138 pWidget = cppgc::MakeGarbageCollected<CXFA_FFComboBox>(
139 m_pDoc->GetHeap()->GetAllocationHandle(), pNode);
140 }
141 break;
142 }
143 case XFA_FFWidgetType::kDateTimeEdit:
144 pWidget = cppgc::MakeGarbageCollected<CXFA_FFDateTimeEdit>(
145 m_pDoc->GetHeap()->GetAllocationHandle(), pNode);
146 break;
147 case XFA_FFWidgetType::kImageEdit:
148 pWidget = cppgc::MakeGarbageCollected<CXFA_FFImageEdit>(
149 m_pDoc->GetHeap()->GetAllocationHandle(), pNode);
150 break;
151 case XFA_FFWidgetType::kNumericEdit:
152 pWidget = cppgc::MakeGarbageCollected<CXFA_FFNumericEdit>(
153 m_pDoc->GetHeap()->GetAllocationHandle(), pNode);
154 break;
155 case XFA_FFWidgetType::kPasswordEdit: {
156 auto* child = CXFA_PasswordEdit::FromNode(pNode->GetUIChildNode());
157 if (!child)
158 return nullptr;
159
160 pWidget = cppgc::MakeGarbageCollected<CXFA_FFPasswordEdit>(
161 m_pDoc->GetHeap()->GetAllocationHandle(), pNode, child);
162 break;
163 }
164 case XFA_FFWidgetType::kSignature:
165 pWidget = cppgc::MakeGarbageCollected<CXFA_FFSignature>(
166 m_pDoc->GetHeap()->GetAllocationHandle(), pNode);
167 break;
168 case XFA_FFWidgetType::kTextEdit:
169 pWidget = cppgc::MakeGarbageCollected<CXFA_FFTextEdit>(
170 m_pDoc->GetHeap()->GetAllocationHandle(), pNode);
171 break;
172 case XFA_FFWidgetType::kArc:
173 pWidget = cppgc::MakeGarbageCollected<CXFA_FFArc>(
174 m_pDoc->GetHeap()->GetAllocationHandle(), pNode);
175 break;
176 case XFA_FFWidgetType::kLine:
177 pWidget = cppgc::MakeGarbageCollected<CXFA_FFLine>(
178 m_pDoc->GetHeap()->GetAllocationHandle(), pNode);
179 break;
180 case XFA_FFWidgetType::kRectangle:
181 pWidget = cppgc::MakeGarbageCollected<CXFA_FFRectangle>(
182 m_pDoc->GetHeap()->GetAllocationHandle(), pNode);
183 break;
184 case XFA_FFWidgetType::kText:
185 pWidget = cppgc::MakeGarbageCollected<CXFA_FFText>(
186 m_pDoc->GetHeap()->GetAllocationHandle(), pNode);
187 break;
188 case XFA_FFWidgetType::kImage:
189 pWidget = cppgc::MakeGarbageCollected<CXFA_FFImage>(
190 m_pDoc->GetHeap()->GetAllocationHandle(), pNode);
191 break;
192 case XFA_FFWidgetType::kSubform:
193 pWidget = cppgc::MakeGarbageCollected<CXFA_FFWidget>(
194 m_pDoc->GetHeap()->GetAllocationHandle(), pNode);
195 break;
196 case XFA_FFWidgetType::kExclGroup:
197 pWidget = cppgc::MakeGarbageCollected<CXFA_FFExclGroup>(
198 m_pDoc->GetHeap()->GetAllocationHandle(), pNode);
199 break;
200 case XFA_FFWidgetType::kNone:
201 return nullptr;
202 }
203 auto* pLayout = CXFA_LayoutProcessor::FromDocument(m_pDoc->GetXFADoc());
204 pWidget->SetDocView(m_pDoc->GetDocView(pLayout));
205 return pWidget;
206 }
207
StartFieldDrawLayout(CXFA_Node * pItem,float * pCalcWidth,float * pCalcHeight)208 void CXFA_FFNotify::StartFieldDrawLayout(CXFA_Node* pItem,
209 float* pCalcWidth,
210 float* pCalcHeight) {
211 pItem->StartWidgetLayout(m_pDoc.Get(), pCalcWidth, pCalcHeight);
212 }
213
RunScript(CXFA_Script * script,CXFA_Node * item)214 bool CXFA_FFNotify::RunScript(CXFA_Script* script, CXFA_Node* item) {
215 CXFA_FFDocView* pDocView = m_pDoc->GetDocView();
216 if (!pDocView)
217 return false;
218
219 CXFA_EventParam EventParam;
220 EventParam.m_eType = XFA_EVENT_Unknown;
221 EventParam.m_bTargeted = false;
222
223 XFA_EventError iRet;
224 bool bRet;
225 std::tie(iRet, bRet) = item->ExecuteBoolScript(pDocView, script, &EventParam);
226 return iRet == XFA_EventError::kSuccess && bRet;
227 }
228
ExecEventByDeepFirst(CXFA_Node * pFormNode,XFA_EVENTTYPE eEventType,bool bIsFormReady,bool bRecursive)229 XFA_EventError CXFA_FFNotify::ExecEventByDeepFirst(CXFA_Node* pFormNode,
230 XFA_EVENTTYPE eEventType,
231 bool bIsFormReady,
232 bool bRecursive) {
233 CXFA_FFDocView* pDocView = m_pDoc->GetDocView();
234 if (!pDocView)
235 return XFA_EventError::kNotExist;
236 return pDocView->ExecEventActivityByDeepFirst(pFormNode, eEventType,
237 bIsFormReady, bRecursive);
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 pDocView->AddCalculateNode(pNode);
246 pDocView->AddValidateNode(pNode);
247 }
248
GetAppProvider()249 CXFA_FFApp::CallbackIface* CXFA_FFNotify::GetAppProvider() {
250 return m_pDoc->GetApp()->GetAppProvider();
251 }
252
HandleWidgetEvent(CXFA_Node * pNode,CXFA_EventParam * pParam)253 void CXFA_FFNotify::HandleWidgetEvent(CXFA_Node* pNode,
254 CXFA_EventParam* pParam) {
255 CXFA_FFDocView* pDocView = m_pDoc->GetDocView();
256 if (!pDocView)
257 return;
258
259 CXFA_FFWidgetHandler* pHandler = pDocView->GetWidgetHandler();
260 if (!pHandler)
261 return;
262
263 pHandler->ProcessEvent(pNode, pParam);
264 }
265
OpenDropDownList(CXFA_Node * pNode)266 void CXFA_FFNotify::OpenDropDownList(CXFA_Node* pNode) {
267 auto* pDocLayout = CXFA_LayoutProcessor::FromDocument(m_pDoc->GetXFADoc());
268 CXFA_LayoutItem* pLayoutItem = pDocLayout->GetLayoutItem(pNode);
269 if (!pLayoutItem)
270 return;
271
272 CXFA_FFWidget* hWidget = CXFA_FFWidget::FromLayoutItem(pLayoutItem);
273 if (!hWidget)
274 return;
275
276 CXFA_FFDoc* hDoc = GetFFDoc();
277 hDoc->SetFocusWidget(hWidget);
278 if (hWidget->GetNode()->GetFFWidgetType() != XFA_FFWidgetType::kChoiceList)
279 return;
280
281 if (!hWidget->IsLoaded())
282 return;
283
284 CXFA_FFDropDown* pDropDown = ToDropDown(ToField(hWidget));
285 CXFA_FFComboBox* pComboBox = ToComboBox(pDropDown);
286 if (!pComboBox)
287 return;
288
289 CXFA_FFDocView::UpdateScope scope(m_pDoc->GetDocView());
290 pComboBox->OpenDropDownList();
291 }
292
ResetData(CXFA_Node * pNode)293 void CXFA_FFNotify::ResetData(CXFA_Node* pNode) {
294 CXFA_FFDocView* pDocView = m_pDoc->GetDocView();
295 if (!pDocView)
296 return;
297
298 pDocView->ResetNode(pNode);
299 }
300
GetLayoutStatus()301 CXFA_FFDocView::LayoutStatus CXFA_FFNotify::GetLayoutStatus() {
302 CXFA_FFDocView* pDocView = m_pDoc->GetDocView();
303 return pDocView ? pDocView->GetLayoutStatus()
304 : CXFA_FFDocView::LayoutStatus::kNone;
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_Subform * pSubformNode)315 void CXFA_FFNotify::RunSubformIndexChange(CXFA_Subform* 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 return pDocView ? pDocView->GetFocusNode() : nullptr;
326 }
327
SetFocusWidgetNode(CXFA_Node * pNode)328 void CXFA_FFNotify::SetFocusWidgetNode(CXFA_Node* pNode) {
329 CXFA_FFDocView* pDocView = m_pDoc->GetDocView();
330 if (!pDocView)
331 return;
332 pDocView->SetFocusNode(pNode);
333 }
334
OnNodeReady(CXFA_Node * pNode)335 void CXFA_FFNotify::OnNodeReady(CXFA_Node* pNode) {
336 CXFA_FFDocView* pDocView = m_pDoc->GetDocView();
337 if (!pDocView)
338 return;
339
340 if (pNode->HasCreatedUIWidget()) {
341 pNode->SetWidgetReady();
342 return;
343 }
344
345 switch (pNode->GetElementType()) {
346 case XFA_Element::BindItems:
347 pDocView->AddBindItem(static_cast<CXFA_BindItems*>(pNode));
348 break;
349 case XFA_Element::Validate:
350 pNode->SetFlag(XFA_NodeFlag::kNeedsInitApp);
351 break;
352 default:
353 break;
354 }
355 }
356
OnValueChanging(CXFA_Node * pSender,XFA_Attribute eAttr)357 void CXFA_FFNotify::OnValueChanging(CXFA_Node* pSender, XFA_Attribute eAttr) {
358 if (eAttr != XFA_Attribute::Presence)
359 return;
360 if (pSender->GetPacketType() == XFA_PacketType::Datasets)
361 return;
362 if (!pSender->IsFormContainer())
363 return;
364
365 CXFA_FFDocView* pDocView = m_pDoc->GetDocView();
366 if (!pDocView)
367 return;
368 if (pDocView->GetLayoutStatus() != CXFA_FFDocView::LayoutStatus::kEnd)
369 return;
370
371 CXFA_FFWidget* pWidget = m_pDoc->GetDocView()->GetWidgetForNode(pSender);
372 for (; pWidget; pWidget = pWidget->GetNextFFWidget()) {
373 if (pWidget->IsLoaded())
374 pWidget->InvalidateRect();
375 }
376 }
377
OnValueChanged(CXFA_Node * pSender,XFA_Attribute eAttr,CXFA_Node * pParentNode,CXFA_Node * pWidgetNode)378 void CXFA_FFNotify::OnValueChanged(CXFA_Node* pSender,
379 XFA_Attribute eAttr,
380 CXFA_Node* pParentNode,
381 CXFA_Node* pWidgetNode) {
382 CXFA_FFDocView* pDocView = m_pDoc->GetDocView();
383 if (!pDocView)
384 return;
385
386 if (pSender->GetPacketType() != XFA_PacketType::Form) {
387 if (eAttr == XFA_Attribute::Value)
388 pDocView->AddCalculateNodeNotify(pSender);
389 return;
390 }
391
392 XFA_Element eType = pParentNode->GetElementType();
393 bool bIsContainerNode = pParentNode->IsContainerNode();
394 bool bUpdateProperty = false;
395 pDocView->SetChangeMark();
396 switch (eType) {
397 case XFA_Element::Caption: {
398 CXFA_TextLayout* pCapOut = pWidgetNode->GetCaptionTextLayout();
399 if (!pCapOut)
400 return;
401
402 pCapOut->Unload();
403 break;
404 }
405 case XFA_Element::Ui:
406 case XFA_Element::Para:
407 bUpdateProperty = true;
408 break;
409 default:
410 break;
411 }
412 if (bIsContainerNode && eAttr == XFA_Attribute::Access)
413 bUpdateProperty = true;
414
415 if (eAttr == XFA_Attribute::Value) {
416 pDocView->AddCalculateNodeNotify(pSender);
417 if (eType == XFA_Element::Value || bIsContainerNode) {
418 if (bIsContainerNode) {
419 m_pDoc->GetDocView()->UpdateUIDisplay(pWidgetNode, nullptr);
420 pDocView->AddCalculateNode(pWidgetNode);
421 pDocView->AddValidateNode(pWidgetNode);
422 } else if (pWidgetNode->GetParent()->GetElementType() ==
423 XFA_Element::ExclGroup) {
424 m_pDoc->GetDocView()->UpdateUIDisplay(pWidgetNode, nullptr);
425 }
426 return;
427 }
428 }
429
430 CXFA_FFWidget* pWidget = m_pDoc->GetDocView()->GetWidgetForNode(pWidgetNode);
431 for (; pWidget; pWidget = pWidget->GetNextFFWidget()) {
432 if (!pWidget->IsLoaded())
433 continue;
434
435 if (bUpdateProperty)
436 pWidget->UpdateWidgetProperty();
437 pWidget->PerformLayout();
438 pWidget->InvalidateRect();
439 }
440 }
441
OnContainerChanged()442 void CXFA_FFNotify::OnContainerChanged() {
443 m_pDoc->GetXFADoc()->GetLayoutProcessor()->SetHasChangedContainer();
444 }
445
OnChildAdded(CXFA_Node * pSender)446 void CXFA_FFNotify::OnChildAdded(CXFA_Node* pSender) {
447 if (!pSender->IsFormContainer())
448 return;
449
450 CXFA_FFDocView* pDocView = m_pDoc->GetDocView();
451 if (!pDocView)
452 return;
453
454 const bool bLayoutReady =
455 !pDocView->InLayoutStatus() &&
456 pDocView->GetLayoutStatus() == CXFA_FFDocView::LayoutStatus::kEnd;
457 if (bLayoutReady)
458 m_pDoc->SetChangeMark();
459 }
460
OnChildRemoved()461 void CXFA_FFNotify::OnChildRemoved() {
462 CXFA_FFDocView* pDocView = m_pDoc->GetDocView();
463 if (!pDocView)
464 return;
465
466 const bool bLayoutReady =
467 !pDocView->InLayoutStatus() &&
468 pDocView->GetLayoutStatus() == CXFA_FFDocView::LayoutStatus::kEnd;
469 if (bLayoutReady)
470 m_pDoc->SetChangeMark();
471 }
472
OnLayoutItemAdded(CXFA_LayoutProcessor * pLayout,CXFA_LayoutItem * pSender,int32_t iPageIdx,Mask<XFA_WidgetStatus> dwStatus)473 void CXFA_FFNotify::OnLayoutItemAdded(CXFA_LayoutProcessor* pLayout,
474 CXFA_LayoutItem* pSender,
475 int32_t iPageIdx,
476 Mask<XFA_WidgetStatus> dwStatus) {
477 CXFA_FFDocView* pDocView = m_pDoc->GetDocView(pLayout);
478 if (!pDocView)
479 return;
480
481 CXFA_FFWidget* pWidget = CXFA_FFWidget::FromLayoutItem(pSender);
482 if (!pWidget)
483 return;
484
485 CXFA_FFPageView* pNewPageView = pDocView->GetPageView(iPageIdx);
486 constexpr Mask<XFA_WidgetStatus> kRemove{XFA_WidgetStatus::kVisible,
487 XFA_WidgetStatus::kViewable,
488 XFA_WidgetStatus::kPrintable};
489 pWidget->ModifyStatus(dwStatus, kRemove);
490 CXFA_FFPageView* pPrePageView = pWidget->GetPageView();
491 if (pPrePageView != pNewPageView ||
492 dwStatus.TestAll(
493 {XFA_WidgetStatus::kVisible, XFA_WidgetStatus::kViewable})) {
494 pWidget->SetPageView(pNewPageView);
495 m_pDoc->WidgetPostAdd(pWidget);
496 }
497 if (pDocView->GetLayoutStatus() != CXFA_FFDocView::LayoutStatus::kEnd ||
498 !(dwStatus & XFA_WidgetStatus::kVisible)) {
499 return;
500 }
501 if (pWidget->IsLoaded()) {
502 if (pWidget->GetWidgetRect() != pWidget->RecacheWidgetRect())
503 pWidget->PerformLayout();
504 } else {
505 pWidget->LoadWidget();
506 }
507 pWidget->InvalidateRect();
508 }
509
OnLayoutItemRemoving(CXFA_LayoutProcessor * pLayout,CXFA_LayoutItem * pSender)510 void CXFA_FFNotify::OnLayoutItemRemoving(CXFA_LayoutProcessor* pLayout,
511 CXFA_LayoutItem* pSender) {
512 CXFA_FFDocView* pDocView = m_pDoc->GetDocView(pLayout);
513 if (!pDocView)
514 return;
515
516 CXFA_FFWidget* pWidget = CXFA_FFWidget::FromLayoutItem(pSender);
517 if (!pWidget)
518 return;
519
520 pDocView->DeleteLayoutItem(pWidget);
521 m_pDoc->WidgetPreRemove(pWidget);
522 pWidget->InvalidateRect();
523 }
524