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/app/xfa_ffnotify.h"
8
9 #include "fxjs/cfxjse_value.h"
10 #include "xfa/fxfa/app/cxfa_textlayout.h"
11 #include "xfa/fxfa/app/xfa_ffbarcode.h"
12 #include "xfa/fxfa/app/xfa_ffcheckbutton.h"
13 #include "xfa/fxfa/app/xfa_ffchoicelist.h"
14 #include "xfa/fxfa/app/xfa_ffdraw.h"
15 #include "xfa/fxfa/app/xfa_ffexclgroup.h"
16 #include "xfa/fxfa/app/xfa_fffield.h"
17 #include "xfa/fxfa/app/xfa_ffimage.h"
18 #include "xfa/fxfa/app/xfa_ffimageedit.h"
19 #include "xfa/fxfa/app/xfa_ffpath.h"
20 #include "xfa/fxfa/app/xfa_ffpushbutton.h"
21 #include "xfa/fxfa/app/xfa_ffsignature.h"
22 #include "xfa/fxfa/app/xfa_ffsubform.h"
23 #include "xfa/fxfa/app/xfa_fftext.h"
24 #include "xfa/fxfa/app/xfa_fftextedit.h"
25 #include "xfa/fxfa/app/xfa_ffwidgetacc.h"
26 #include "xfa/fxfa/app/xfa_fwladapter.h"
27 #include "xfa/fxfa/xfa_ffapp.h"
28 #include "xfa/fxfa/xfa_ffdoc.h"
29 #include "xfa/fxfa/xfa_ffdocview.h"
30 #include "xfa/fxfa/xfa_ffpageview.h"
31 #include "xfa/fxfa/xfa_ffwidget.h"
32 #include "xfa/fxfa/xfa_ffwidgethandler.h"
33
XFA_FFDeleteWidgetAcc(void * pData)34 static void XFA_FFDeleteWidgetAcc(void* pData) {
35 delete static_cast<CXFA_WidgetAcc*>(pData);
36 }
37
38 static XFA_MAPDATABLOCKCALLBACKINFO gs_XFADeleteWidgetAcc = {
39 XFA_FFDeleteWidgetAcc, nullptr};
40
CXFA_FFNotify(CXFA_FFDoc * pDoc)41 CXFA_FFNotify::CXFA_FFNotify(CXFA_FFDoc* pDoc) : m_pDoc(pDoc) {}
~CXFA_FFNotify()42 CXFA_FFNotify::~CXFA_FFNotify() {}
43
OnPageEvent(CXFA_ContainerLayoutItem * pSender,uint32_t dwEvent)44 void CXFA_FFNotify::OnPageEvent(CXFA_ContainerLayoutItem* pSender,
45 uint32_t dwEvent) {
46 CXFA_FFDocView* pDocView = m_pDoc->GetDocView(pSender->GetLayout());
47 if (pDocView)
48 pDocView->OnPageEvent(pSender, dwEvent);
49 }
50
OnWidgetListItemAdded(CXFA_WidgetData * pSender,const FX_WCHAR * pLabel,const FX_WCHAR * pValue,int32_t iIndex)51 void CXFA_FFNotify::OnWidgetListItemAdded(CXFA_WidgetData* pSender,
52 const FX_WCHAR* pLabel,
53 const FX_WCHAR* pValue,
54 int32_t iIndex) {
55 CXFA_WidgetAcc* pWidgetAcc = static_cast<CXFA_WidgetAcc*>(pSender);
56 if (pWidgetAcc->GetUIType() != XFA_Element::ChoiceList)
57 return;
58
59 CXFA_FFWidget* pWidget = nullptr;
60 while ((pWidget = pWidgetAcc->GetNextWidget(pWidget)) != nullptr) {
61 if (pWidget->IsLoaded()) {
62 if (pWidgetAcc->IsListBox()) {
63 static_cast<CXFA_FFListBox*>(pWidget)->InsertItem(pLabel, iIndex);
64 } else {
65 static_cast<CXFA_FFComboBox*>(pWidget)->InsertItem(pLabel, iIndex);
66 }
67 }
68 }
69 }
70
OnWidgetListItemRemoved(CXFA_WidgetData * pSender,int32_t iIndex)71 void CXFA_FFNotify::OnWidgetListItemRemoved(CXFA_WidgetData* pSender,
72 int32_t iIndex) {
73 CXFA_WidgetAcc* pWidgetAcc = static_cast<CXFA_WidgetAcc*>(pSender);
74 if (pWidgetAcc->GetUIType() != XFA_Element::ChoiceList)
75 return;
76
77 CXFA_FFWidget* pWidget = nullptr;
78 while ((pWidget = pWidgetAcc->GetNextWidget(pWidget)) != nullptr) {
79 if (pWidget->IsLoaded()) {
80 if (pWidgetAcc->IsListBox()) {
81 static_cast<CXFA_FFListBox*>(pWidget)->DeleteItem(iIndex);
82 } else {
83 static_cast<CXFA_FFComboBox*>(pWidget)->DeleteItem(iIndex);
84 }
85 }
86 }
87 }
88
OnCreateLayoutItem(CXFA_Node * pNode)89 CXFA_LayoutItem* CXFA_FFNotify::OnCreateLayoutItem(CXFA_Node* pNode) {
90 CXFA_LayoutProcessor* pLayout = m_pDoc->GetXFADoc()->GetDocLayout();
91 CXFA_FFDocView* pDocView = m_pDoc->GetDocView(pLayout);
92 XFA_Element eType = pNode->GetElementType();
93 if (eType == XFA_Element::PageArea)
94 return new CXFA_FFPageView(pDocView, pNode);
95 if (eType == XFA_Element::ContentArea)
96 return new CXFA_ContainerLayoutItem(pNode);
97
98 CXFA_WidgetAcc* pAcc = static_cast<CXFA_WidgetAcc*>(pNode->GetWidgetData());
99 if (!pAcc)
100 return new CXFA_ContentLayoutItem(pNode);
101
102 CXFA_FFWidget* pWidget;
103 switch (pAcc->GetUIType()) {
104 case XFA_Element::Barcode:
105 pWidget = new CXFA_FFBarcode(pAcc);
106 break;
107 case XFA_Element::Button:
108 pWidget = new CXFA_FFPushButton(pAcc);
109 break;
110 case XFA_Element::CheckButton:
111 pWidget = new CXFA_FFCheckButton(pAcc);
112 break;
113 case XFA_Element::ChoiceList: {
114 if (pAcc->IsListBox()) {
115 pWidget = new CXFA_FFListBox(pAcc);
116 } else {
117 pWidget = new CXFA_FFComboBox(pAcc);
118 }
119 } break;
120 case XFA_Element::DateTimeEdit:
121 pWidget = new CXFA_FFDateTimeEdit(pAcc);
122 break;
123 case XFA_Element::ImageEdit:
124 pWidget = new CXFA_FFImageEdit(pAcc);
125 break;
126 case XFA_Element::NumericEdit:
127 pWidget = new CXFA_FFNumericEdit(pAcc);
128 break;
129 case XFA_Element::PasswordEdit:
130 pWidget = new CXFA_FFPasswordEdit(pAcc);
131 break;
132 case XFA_Element::Signature:
133 pWidget = new CXFA_FFSignature(pAcc);
134 break;
135 case XFA_Element::TextEdit:
136 pWidget = new CXFA_FFTextEdit(pAcc);
137 break;
138 case XFA_Element::Arc:
139 pWidget = new CXFA_FFArc(pAcc);
140 break;
141 case XFA_Element::Line:
142 pWidget = new CXFA_FFLine(pAcc);
143 break;
144 case XFA_Element::Rectangle:
145 pWidget = new CXFA_FFRectangle(pAcc);
146 break;
147 case XFA_Element::Text:
148 pWidget = new CXFA_FFText(pAcc);
149 break;
150 case XFA_Element::Image:
151 pWidget = new CXFA_FFImage(pAcc);
152 break;
153 case XFA_Element::Draw:
154 pWidget = new CXFA_FFDraw(pAcc);
155 break;
156 case XFA_Element::Subform:
157 pWidget = new CXFA_FFSubForm(pAcc);
158 break;
159 case XFA_Element::ExclGroup:
160 pWidget = new CXFA_FFExclGroup(pAcc);
161 break;
162 case XFA_Element::DefaultUi:
163 default:
164 pWidget = nullptr;
165 break;
166 }
167
168 if (pWidget)
169 pWidget->SetDocView(pDocView);
170 return pWidget;
171 }
172
StartFieldDrawLayout(CXFA_Node * pItem,FX_FLOAT & fCalcWidth,FX_FLOAT & fCalcHeight)173 void CXFA_FFNotify::StartFieldDrawLayout(CXFA_Node* pItem,
174 FX_FLOAT& fCalcWidth,
175 FX_FLOAT& fCalcHeight) {
176 CXFA_WidgetAcc* pAcc = static_cast<CXFA_WidgetAcc*>(pItem->GetWidgetData());
177 if (!pAcc)
178 return;
179
180 pAcc->StartWidgetLayout(fCalcWidth, fCalcHeight);
181 }
182
FindSplitPos(CXFA_Node * pItem,int32_t iBlockIndex,FX_FLOAT & fCalcHeightPos)183 bool CXFA_FFNotify::FindSplitPos(CXFA_Node* pItem,
184 int32_t iBlockIndex,
185 FX_FLOAT& fCalcHeightPos) {
186 CXFA_WidgetAcc* pAcc = static_cast<CXFA_WidgetAcc*>(pItem->GetWidgetData());
187 return pAcc && pAcc->FindSplitPos(iBlockIndex, fCalcHeightPos);
188 }
189
RunScript(CXFA_Node * pScript,CXFA_Node * pFormItem)190 bool CXFA_FFNotify::RunScript(CXFA_Node* pScript, CXFA_Node* pFormItem) {
191 bool bRet = false;
192 CXFA_FFDocView* pDocView = m_pDoc->GetDocView();
193 if (!pDocView) {
194 return bRet;
195 }
196 CXFA_WidgetAcc* pWidgetAcc =
197 static_cast<CXFA_WidgetAcc*>(pFormItem->GetWidgetData());
198 if (!pWidgetAcc) {
199 return bRet;
200 }
201 CXFA_EventParam EventParam;
202 EventParam.m_eType = XFA_EVENT_Unknown;
203 CFXJSE_Value* pRetValue = nullptr;
204 int32_t iRet =
205 pWidgetAcc->ExecuteScript(CXFA_Script(pScript), &EventParam, &pRetValue);
206 if (iRet == XFA_EVENTERROR_Success && pRetValue) {
207 bRet = pRetValue->ToBoolean();
208 delete pRetValue;
209 }
210 return bRet;
211 }
ExecEventByDeepFirst(CXFA_Node * pFormNode,XFA_EVENTTYPE eEventType,bool bIsFormReady,bool bRecursive,CXFA_WidgetAcc * pExclude)212 int32_t CXFA_FFNotify::ExecEventByDeepFirst(CXFA_Node* pFormNode,
213 XFA_EVENTTYPE eEventType,
214 bool bIsFormReady,
215 bool bRecursive,
216 CXFA_WidgetAcc* pExclude) {
217 CXFA_FFDocView* pDocView = m_pDoc->GetDocView();
218 if (!pDocView) {
219 return XFA_EVENTERROR_NotExist;
220 }
221 return pDocView->ExecEventActivityByDeepFirst(
222 pFormNode, eEventType, bIsFormReady, bRecursive,
223 pExclude ? pExclude->GetNode() : nullptr);
224 }
AddCalcValidate(CXFA_Node * pNode)225 void CXFA_FFNotify::AddCalcValidate(CXFA_Node* pNode) {
226 CXFA_FFDocView* pDocView = m_pDoc->GetDocView();
227 if (!pDocView) {
228 return;
229 }
230 CXFA_WidgetAcc* pWidgetAcc =
231 static_cast<CXFA_WidgetAcc*>(pNode->GetWidgetData());
232 if (!pWidgetAcc) {
233 return;
234 }
235 pDocView->AddCalculateWidgetAcc(pWidgetAcc);
236 pDocView->AddValidateWidget(pWidgetAcc);
237 }
GetHDOC()238 CXFA_FFDoc* CXFA_FFNotify::GetHDOC() {
239 return m_pDoc;
240 }
GetDocEnvironment() const241 IXFA_DocEnvironment* CXFA_FFNotify::GetDocEnvironment() const {
242 return m_pDoc->GetDocEnvironment();
243 }
GetAppProvider()244 IXFA_AppProvider* CXFA_FFNotify::GetAppProvider() {
245 return m_pDoc->GetApp()->GetAppProvider();
246 }
GetWidgetHandler()247 CXFA_FFWidgetHandler* CXFA_FFNotify::GetWidgetHandler() {
248 CXFA_FFDocView* pDocView = m_pDoc->GetDocView();
249 return pDocView ? pDocView->GetWidgetHandler() : nullptr;
250 }
GetHWidget(CXFA_LayoutItem * pLayoutItem)251 CXFA_FFWidget* CXFA_FFNotify::GetHWidget(CXFA_LayoutItem* pLayoutItem) {
252 return XFA_GetWidgetFromLayoutItem(pLayoutItem);
253 }
OpenDropDownList(CXFA_FFWidget * hWidget)254 void CXFA_FFNotify::OpenDropDownList(CXFA_FFWidget* hWidget) {
255 if (hWidget->GetDataAcc()->GetUIType() != XFA_Element::ChoiceList) {
256 return;
257 }
258 CXFA_FFDocView* pDocView = m_pDoc->GetDocView();
259 pDocView->LockUpdate();
260 static_cast<CXFA_FFComboBox*>(hWidget)->OpenDropDownList();
261 pDocView->UnlockUpdate();
262 pDocView->UpdateDocView();
263 }
GetCurrentDateTime()264 CFX_WideString CXFA_FFNotify::GetCurrentDateTime() {
265 CFX_Unitime dataTime;
266 dataTime.Now();
267 CFX_WideString wsDateTime;
268 wsDateTime.Format(L"%d%02d%02dT%02d%02d%02d", dataTime.GetYear(),
269 dataTime.GetMonth(), dataTime.GetDay(), dataTime.GetHour(),
270 dataTime.GetMinute(), dataTime.GetSecond());
271 return wsDateTime;
272 }
ResetData(CXFA_WidgetData * pWidgetData)273 void CXFA_FFNotify::ResetData(CXFA_WidgetData* pWidgetData) {
274 CXFA_FFDocView* pDocView = m_pDoc->GetDocView();
275 if (!pDocView) {
276 return;
277 }
278 pDocView->ResetWidgetData(static_cast<CXFA_WidgetAcc*>(pWidgetData));
279 }
GetLayoutStatus()280 int32_t CXFA_FFNotify::GetLayoutStatus() {
281 CXFA_FFDocView* pDocView = m_pDoc->GetDocView();
282 return pDocView ? pDocView->GetLayoutStatus() : 0;
283 }
RunNodeInitialize(CXFA_Node * pNode)284 void CXFA_FFNotify::RunNodeInitialize(CXFA_Node* pNode) {
285 CXFA_FFDocView* pDocView = m_pDoc->GetDocView();
286 if (!pDocView) {
287 return;
288 }
289 pDocView->AddNewFormNode(pNode);
290 }
RunSubformIndexChange(CXFA_Node * pSubformNode)291 void CXFA_FFNotify::RunSubformIndexChange(CXFA_Node* pSubformNode) {
292 CXFA_FFDocView* pDocView = m_pDoc->GetDocView();
293 if (!pDocView) {
294 return;
295 }
296 pDocView->AddIndexChangedSubform(pSubformNode);
297 }
GetFocusWidgetNode()298 CXFA_Node* CXFA_FFNotify::GetFocusWidgetNode() {
299 CXFA_FFDocView* pDocView = m_pDoc->GetDocView();
300 if (!pDocView) {
301 return nullptr;
302 }
303 CXFA_WidgetAcc* pAcc = pDocView->GetFocusWidgetAcc();
304 return pAcc ? pAcc->GetNode() : nullptr;
305 }
SetFocusWidgetNode(CXFA_Node * pNode)306 void CXFA_FFNotify::SetFocusWidgetNode(CXFA_Node* pNode) {
307 CXFA_FFDocView* pDocView = m_pDoc->GetDocView();
308 if (!pDocView) {
309 return;
310 }
311 CXFA_WidgetAcc* pAcc =
312 pNode ? static_cast<CXFA_WidgetAcc*>(pNode->GetWidgetData()) : nullptr;
313 pDocView->SetFocusWidgetAcc(pAcc);
314 }
315
OnNodeReady(CXFA_Node * pNode)316 void CXFA_FFNotify::OnNodeReady(CXFA_Node* pNode) {
317 CXFA_FFDocView* pDocView = m_pDoc->GetDocView();
318 if (!pDocView)
319 return;
320
321 XFA_Element eType = pNode->GetElementType();
322 if (XFA_IsCreateWidget(eType)) {
323 CXFA_WidgetAcc* pAcc = new CXFA_WidgetAcc(pDocView, pNode);
324 pNode->SetObject(XFA_ATTRIBUTE_WidgetData, pAcc, &gs_XFADeleteWidgetAcc);
325 return;
326 }
327 switch (eType) {
328 case XFA_Element::BindItems:
329 pDocView->m_BindItems.push_back(pNode);
330 break;
331 case XFA_Element::Validate: {
332 pNode->SetFlag(XFA_NodeFlag_NeedsInitApp, false);
333 } break;
334 default:
335 break;
336 }
337 }
338
OnValueChanging(CXFA_Node * pSender,XFA_ATTRIBUTE eAttr)339 void CXFA_FFNotify::OnValueChanging(CXFA_Node* pSender, XFA_ATTRIBUTE eAttr) {
340 if (eAttr != XFA_ATTRIBUTE_Presence)
341 return;
342
343 if (pSender->GetPacketID() & XFA_XDPPACKET_Datasets)
344 return;
345
346 if (!pSender->IsFormContainer())
347 return;
348
349 CXFA_FFDocView* pDocView = m_pDoc->GetDocView();
350 if (!pDocView)
351 return;
352
353 if (pDocView->GetLayoutStatus() < XFA_DOCVIEW_LAYOUTSTATUS_End)
354 return;
355
356 CXFA_WidgetAcc* pWidgetAcc =
357 static_cast<CXFA_WidgetAcc*>(pSender->GetWidgetData());
358 if (!pWidgetAcc)
359 return;
360
361 CXFA_FFWidget* pWidget = nullptr;
362 while ((pWidget = pWidgetAcc->GetNextWidget(pWidget)) != nullptr) {
363 if (pWidget->IsLoaded())
364 pWidget->AddInvalidateRect();
365 }
366 }
367
OnValueChanged(CXFA_Node * pSender,XFA_ATTRIBUTE eAttr,CXFA_Node * pParentNode,CXFA_Node * pWidgetNode)368 void CXFA_FFNotify::OnValueChanged(CXFA_Node* pSender,
369 XFA_ATTRIBUTE eAttr,
370 CXFA_Node* pParentNode,
371 CXFA_Node* pWidgetNode) {
372 CXFA_FFDocView* pDocView = m_pDoc->GetDocView();
373 if (!pDocView)
374 return;
375
376 if (!(pSender->GetPacketID() & XFA_XDPPACKET_Form)) {
377 if (eAttr == XFA_ATTRIBUTE_Value)
378 pDocView->AddCalculateNodeNotify(pSender);
379 return;
380 }
381
382 XFA_Element eType = pParentNode->GetElementType();
383 bool bIsContainerNode = pParentNode->IsContainerNode();
384 CXFA_WidgetAcc* pWidgetAcc =
385 static_cast<CXFA_WidgetAcc*>(pWidgetNode->GetWidgetData());
386 if (!pWidgetAcc)
387 return;
388
389 bool bUpdateProperty = false;
390 pDocView->SetChangeMark();
391 switch (eType) {
392 case XFA_Element::Caption: {
393 CXFA_TextLayout* pCapOut = pWidgetAcc->GetCaptionTextLayout();
394 if (!pCapOut)
395 return;
396
397 pCapOut->Unload();
398 } break;
399 case XFA_Element::Ui:
400 case XFA_Element::Para:
401 bUpdateProperty = true;
402 break;
403 default:
404 break;
405 }
406 if (bIsContainerNode && eAttr == XFA_ATTRIBUTE_Access)
407 bUpdateProperty = true;
408
409 if (eAttr == XFA_ATTRIBUTE_Value) {
410 pDocView->AddCalculateNodeNotify(pSender);
411 if (eType == XFA_Element::Value || bIsContainerNode) {
412 if (bIsContainerNode) {
413 pWidgetAcc->UpdateUIDisplay();
414 pDocView->AddCalculateWidgetAcc(pWidgetAcc);
415 pDocView->AddValidateWidget(pWidgetAcc);
416 } else if (pWidgetNode->GetNodeItem(XFA_NODEITEM_Parent)
417 ->GetElementType() == XFA_Element::ExclGroup) {
418 pWidgetAcc->UpdateUIDisplay();
419 }
420 return;
421 }
422 }
423 CXFA_FFWidget* pWidget = nullptr;
424 while ((pWidget = pWidgetAcc->GetNextWidget(pWidget)) != nullptr) {
425 if (!pWidget->IsLoaded())
426 continue;
427
428 if (bUpdateProperty)
429 pWidget->UpdateWidgetProperty();
430 pWidget->PerformLayout();
431 pWidget->AddInvalidateRect();
432 }
433 }
434
OnChildAdded(CXFA_Node * pSender)435 void CXFA_FFNotify::OnChildAdded(CXFA_Node* pSender) {
436 if (!pSender->IsFormContainer()) {
437 return;
438 }
439 CXFA_FFDocView* pDocView = m_pDoc->GetDocView();
440 if (!pDocView) {
441 return;
442 }
443 bool bLayoutReady =
444 !(pDocView->m_bInLayoutStatus) &&
445 (pDocView->GetLayoutStatus() == XFA_DOCVIEW_LAYOUTSTATUS_End);
446 if (bLayoutReady)
447 m_pDoc->GetDocEnvironment()->SetChangeMark(m_pDoc);
448 }
449
OnChildRemoved()450 void CXFA_FFNotify::OnChildRemoved() {
451 CXFA_FFDocView* pDocView = m_pDoc->GetDocView();
452 if (!pDocView)
453 return;
454
455 bool bLayoutReady =
456 !(pDocView->m_bInLayoutStatus) &&
457 (pDocView->GetLayoutStatus() == XFA_DOCVIEW_LAYOUTSTATUS_End);
458 if (bLayoutReady)
459 m_pDoc->GetDocEnvironment()->SetChangeMark(m_pDoc);
460 }
461
OnLayoutItemAdded(CXFA_LayoutProcessor * pLayout,CXFA_LayoutItem * pSender,int32_t iPageIdx,uint32_t dwStatus)462 void CXFA_FFNotify::OnLayoutItemAdded(CXFA_LayoutProcessor* pLayout,
463 CXFA_LayoutItem* pSender,
464 int32_t iPageIdx,
465 uint32_t dwStatus) {
466 CXFA_FFDocView* pDocView = m_pDoc->GetDocView(pLayout);
467 if (!pDocView)
468 return;
469
470 CXFA_FFWidget* pWidget = XFA_GetWidgetFromLayoutItem(pSender);
471 if (!pWidget)
472 return;
473
474 CXFA_FFPageView* pNewPageView = pDocView->GetPageView(iPageIdx);
475 uint32_t dwFilter = XFA_WidgetStatus_Visible | XFA_WidgetStatus_Viewable |
476 XFA_WidgetStatus_Printable;
477 pWidget->ModifyStatus(dwStatus, dwFilter);
478 CXFA_FFPageView* pPrePageView = pWidget->GetPageView();
479 if (pPrePageView != pNewPageView ||
480 (dwStatus & (XFA_WidgetStatus_Visible | XFA_WidgetStatus_Viewable)) ==
481 (XFA_WidgetStatus_Visible | XFA_WidgetStatus_Viewable)) {
482 pWidget->SetPageView(pNewPageView);
483 m_pDoc->GetDocEnvironment()->WidgetPostAdd(pWidget, pWidget->GetDataAcc());
484 }
485 if (pDocView->GetLayoutStatus() != XFA_DOCVIEW_LAYOUTSTATUS_End ||
486 !(dwStatus & XFA_WidgetStatus_Visible)) {
487 return;
488 }
489 if (pWidget->IsLoaded()) {
490 if (pWidget->GetWidgetRect() != pWidget->RecacheWidgetRect())
491 pWidget->PerformLayout();
492 } else {
493 pWidget->LoadWidget();
494 }
495 pWidget->AddInvalidateRect(nullptr);
496 }
497
OnLayoutItemRemoving(CXFA_LayoutProcessor * pLayout,CXFA_LayoutItem * pSender)498 void CXFA_FFNotify::OnLayoutItemRemoving(CXFA_LayoutProcessor* pLayout,
499 CXFA_LayoutItem* pSender) {
500 CXFA_FFDocView* pDocView = m_pDoc->GetDocView(pLayout);
501 if (!pDocView)
502 return;
503
504 CXFA_FFWidget* pWidget = XFA_GetWidgetFromLayoutItem(pSender);
505 if (!pWidget)
506 return;
507
508 pDocView->DeleteLayoutItem(pWidget);
509 m_pDoc->GetDocEnvironment()->WidgetPreRemove(pWidget, pWidget->GetDataAcc());
510 pWidget->AddInvalidateRect(nullptr);
511 }
512