• 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/xfa_ffwidgethandler.h"
8 
9 #include <vector>
10 
11 #include "xfa/fxfa/app/xfa_ffchoicelist.h"
12 #include "xfa/fxfa/app/xfa_fffield.h"
13 #include "xfa/fxfa/app/xfa_fwladapter.h"
14 #include "xfa/fxfa/parser/cxfa_layoutprocessor.h"
15 #include "xfa/fxfa/parser/cxfa_measurement.h"
16 #include "xfa/fxfa/xfa_ffdoc.h"
17 #include "xfa/fxfa/xfa_ffdocview.h"
18 #include "xfa/fxfa/xfa_ffwidget.h"
19 
CXFA_FFWidgetHandler(CXFA_FFDocView * pDocView)20 CXFA_FFWidgetHandler::CXFA_FFWidgetHandler(CXFA_FFDocView* pDocView)
21     : m_pDocView(pDocView) {}
22 
~CXFA_FFWidgetHandler()23 CXFA_FFWidgetHandler::~CXFA_FFWidgetHandler() {}
24 
OnMouseEnter(CXFA_FFWidget * hWidget)25 bool CXFA_FFWidgetHandler::OnMouseEnter(CXFA_FFWidget* hWidget) {
26   m_pDocView->LockUpdate();
27   bool bRet = hWidget->OnMouseEnter();
28   m_pDocView->UnlockUpdate();
29   m_pDocView->UpdateDocView();
30   return bRet;
31 }
32 
OnMouseExit(CXFA_FFWidget * hWidget)33 bool CXFA_FFWidgetHandler::OnMouseExit(CXFA_FFWidget* hWidget) {
34   m_pDocView->LockUpdate();
35   bool bRet = hWidget->OnMouseExit();
36   m_pDocView->UnlockUpdate();
37   m_pDocView->UpdateDocView();
38   return bRet;
39 }
40 
OnLButtonDown(CXFA_FFWidget * hWidget,uint32_t dwFlags,const CFX_PointF & point)41 bool CXFA_FFWidgetHandler::OnLButtonDown(CXFA_FFWidget* hWidget,
42                                          uint32_t dwFlags,
43                                          const CFX_PointF& point) {
44   m_pDocView->LockUpdate();
45   bool bRet = hWidget->OnLButtonDown(dwFlags, hWidget->Rotate2Normal(point));
46   if (bRet && m_pDocView->SetFocus(hWidget)) {
47     m_pDocView->GetDoc()->GetDocEnvironment()->SetFocusWidget(
48         m_pDocView->GetDoc(), hWidget);
49   }
50   m_pDocView->UnlockUpdate();
51   m_pDocView->UpdateDocView();
52   return bRet;
53 }
54 
OnLButtonUp(CXFA_FFWidget * hWidget,uint32_t dwFlags,const CFX_PointF & point)55 bool CXFA_FFWidgetHandler::OnLButtonUp(CXFA_FFWidget* hWidget,
56                                        uint32_t dwFlags,
57                                        const CFX_PointF& point) {
58   m_pDocView->LockUpdate();
59   m_pDocView->m_bLayoutEvent = true;
60   bool bRet = hWidget->OnLButtonUp(dwFlags, hWidget->Rotate2Normal(point));
61   m_pDocView->UnlockUpdate();
62   m_pDocView->UpdateDocView();
63   return bRet;
64 }
65 
OnLButtonDblClk(CXFA_FFWidget * hWidget,uint32_t dwFlags,const CFX_PointF & point)66 bool CXFA_FFWidgetHandler::OnLButtonDblClk(CXFA_FFWidget* hWidget,
67                                            uint32_t dwFlags,
68                                            const CFX_PointF& point) {
69   bool bRet = hWidget->OnLButtonDblClk(dwFlags, hWidget->Rotate2Normal(point));
70   m_pDocView->RunInvalidate();
71   return bRet;
72 }
73 
OnMouseMove(CXFA_FFWidget * hWidget,uint32_t dwFlags,const CFX_PointF & point)74 bool CXFA_FFWidgetHandler::OnMouseMove(CXFA_FFWidget* hWidget,
75                                        uint32_t dwFlags,
76                                        const CFX_PointF& point) {
77   bool bRet = hWidget->OnMouseMove(dwFlags, hWidget->Rotate2Normal(point));
78   m_pDocView->RunInvalidate();
79   return bRet;
80 }
81 
OnMouseWheel(CXFA_FFWidget * hWidget,uint32_t dwFlags,int16_t zDelta,const CFX_PointF & point)82 bool CXFA_FFWidgetHandler::OnMouseWheel(CXFA_FFWidget* hWidget,
83                                         uint32_t dwFlags,
84                                         int16_t zDelta,
85                                         const CFX_PointF& point) {
86   bool bRet =
87       hWidget->OnMouseWheel(dwFlags, zDelta, hWidget->Rotate2Normal(point));
88   m_pDocView->RunInvalidate();
89   return bRet;
90 }
91 
OnRButtonDown(CXFA_FFWidget * hWidget,uint32_t dwFlags,const CFX_PointF & point)92 bool CXFA_FFWidgetHandler::OnRButtonDown(CXFA_FFWidget* hWidget,
93                                          uint32_t dwFlags,
94                                          const CFX_PointF& point) {
95   bool bRet = hWidget->OnRButtonDown(dwFlags, hWidget->Rotate2Normal(point));
96   if (bRet && m_pDocView->SetFocus(hWidget)) {
97     m_pDocView->GetDoc()->GetDocEnvironment()->SetFocusWidget(
98         m_pDocView->GetDoc(), hWidget);
99   }
100   m_pDocView->RunInvalidate();
101   return bRet;
102 }
103 
OnRButtonUp(CXFA_FFWidget * hWidget,uint32_t dwFlags,const CFX_PointF & point)104 bool CXFA_FFWidgetHandler::OnRButtonUp(CXFA_FFWidget* hWidget,
105                                        uint32_t dwFlags,
106                                        const CFX_PointF& point) {
107   bool bRet = hWidget->OnRButtonUp(dwFlags, hWidget->Rotate2Normal(point));
108   m_pDocView->RunInvalidate();
109   return bRet;
110 }
111 
OnRButtonDblClk(CXFA_FFWidget * hWidget,uint32_t dwFlags,const CFX_PointF & point)112 bool CXFA_FFWidgetHandler::OnRButtonDblClk(CXFA_FFWidget* hWidget,
113                                            uint32_t dwFlags,
114                                            const CFX_PointF& point) {
115   bool bRet = hWidget->OnRButtonDblClk(dwFlags, hWidget->Rotate2Normal(point));
116   m_pDocView->RunInvalidate();
117   return bRet;
118 }
119 
OnKeyDown(CXFA_FFWidget * hWidget,uint32_t dwKeyCode,uint32_t dwFlags)120 bool CXFA_FFWidgetHandler::OnKeyDown(CXFA_FFWidget* hWidget,
121                                      uint32_t dwKeyCode,
122                                      uint32_t dwFlags) {
123   bool bRet = hWidget->OnKeyDown(dwKeyCode, dwFlags);
124   m_pDocView->RunInvalidate();
125   m_pDocView->UpdateDocView();
126   return bRet;
127 }
128 
OnKeyUp(CXFA_FFWidget * hWidget,uint32_t dwKeyCode,uint32_t dwFlags)129 bool CXFA_FFWidgetHandler::OnKeyUp(CXFA_FFWidget* hWidget,
130                                    uint32_t dwKeyCode,
131                                    uint32_t dwFlags) {
132   bool bRet = hWidget->OnKeyUp(dwKeyCode, dwFlags);
133   m_pDocView->RunInvalidate();
134   return bRet;
135 }
136 
OnChar(CXFA_FFWidget * hWidget,uint32_t dwChar,uint32_t dwFlags)137 bool CXFA_FFWidgetHandler::OnChar(CXFA_FFWidget* hWidget,
138                                   uint32_t dwChar,
139                                   uint32_t dwFlags) {
140   bool bRet = hWidget->OnChar(dwChar, dwFlags);
141   m_pDocView->RunInvalidate();
142   return bRet;
143 }
144 
OnHitTest(CXFA_FFWidget * hWidget,const CFX_PointF & point)145 FWL_WidgetHit CXFA_FFWidgetHandler::OnHitTest(CXFA_FFWidget* hWidget,
146                                               const CFX_PointF& point) {
147   if (!(hWidget->GetStatus() & XFA_WidgetStatus_Visible))
148     return FWL_WidgetHit::Unknown;
149   return hWidget->OnHitTest(hWidget->Rotate2Normal(point));
150 }
151 
OnSetCursor(CXFA_FFWidget * hWidget,const CFX_PointF & point)152 bool CXFA_FFWidgetHandler::OnSetCursor(CXFA_FFWidget* hWidget,
153                                        const CFX_PointF& point) {
154   return hWidget->OnSetCursor(hWidget->Rotate2Normal(point));
155 }
156 
RenderWidget(CXFA_FFWidget * hWidget,CFX_Graphics * pGS,CFX_Matrix * pMatrix,bool bHighlight)157 void CXFA_FFWidgetHandler::RenderWidget(CXFA_FFWidget* hWidget,
158                                         CFX_Graphics* pGS,
159                                         CFX_Matrix* pMatrix,
160                                         bool bHighlight) {
161   hWidget->RenderWidget(pGS, pMatrix,
162                         bHighlight ? XFA_WidgetStatus_Highlight : 0);
163 }
164 
HasEvent(CXFA_WidgetAcc * pWidgetAcc,XFA_EVENTTYPE eEventType)165 bool CXFA_FFWidgetHandler::HasEvent(CXFA_WidgetAcc* pWidgetAcc,
166                                     XFA_EVENTTYPE eEventType) {
167   if (!pWidgetAcc || eEventType == XFA_EVENT_Unknown)
168     return false;
169   if (pWidgetAcc->GetElementType() == XFA_Element::Draw)
170     return false;
171 
172   switch (eEventType) {
173     case XFA_EVENT_Calculate: {
174       CXFA_Calculate calc = pWidgetAcc->GetCalculate();
175       if (!calc)
176         return false;
177       if (calc.GetScript())
178         return true;
179       return false;
180     }
181     case XFA_EVENT_Validate: {
182       CXFA_Validate val = pWidgetAcc->GetValidate();
183       if (!val)
184         return false;
185       if (val.GetScript())
186         return true;
187       return false;
188     }
189     default:
190       break;
191   }
192   CXFA_NodeArray eventArray;
193   return pWidgetAcc->GetEventByActivity(gs_EventActivity[eEventType],
194                                         eventArray) > 0;
195 }
196 
ProcessEvent(CXFA_WidgetAcc * pWidgetAcc,CXFA_EventParam * pParam)197 int32_t CXFA_FFWidgetHandler::ProcessEvent(CXFA_WidgetAcc* pWidgetAcc,
198                                            CXFA_EventParam* pParam) {
199   if (!pParam || pParam->m_eType == XFA_EVENT_Unknown)
200     return XFA_EVENTERROR_NotExist;
201   if (!pWidgetAcc || pWidgetAcc->GetElementType() == XFA_Element::Draw)
202     return XFA_EVENTERROR_NotExist;
203 
204   switch (pParam->m_eType) {
205     case XFA_EVENT_Calculate:
206       return pWidgetAcc->ProcessCalculate();
207     case XFA_EVENT_Validate:
208       if (m_pDocView->GetDoc()->GetDocEnvironment()->IsValidationsEnabled(
209               m_pDocView->GetDoc())) {
210         return pWidgetAcc->ProcessValidate();
211       }
212       return XFA_EVENTERROR_Disabled;
213     case XFA_EVENT_InitCalculate: {
214       CXFA_Calculate calc = pWidgetAcc->GetCalculate();
215       if (!calc)
216         return XFA_EVENTERROR_NotExist;
217       if (pWidgetAcc->GetNode()->IsUserInteractive())
218         return XFA_EVENTERROR_Disabled;
219 
220       CXFA_Script script = calc.GetScript();
221       return pWidgetAcc->ExecuteScript(script, pParam);
222     }
223     default:
224       break;
225   }
226   int32_t iRet =
227       pWidgetAcc->ProcessEvent(gs_EventActivity[pParam->m_eType], pParam);
228   return iRet;
229 }
230 
CreateWidget(CXFA_FFWidget * hParent,XFA_WIDGETTYPE eType,CXFA_FFWidget * hBefore)231 CXFA_FFWidget* CXFA_FFWidgetHandler::CreateWidget(CXFA_FFWidget* hParent,
232                                                   XFA_WIDGETTYPE eType,
233                                                   CXFA_FFWidget* hBefore) {
234   CXFA_Node* pParentFormItem =
235       hParent ? hParent->GetDataAcc()->GetNode() : nullptr;
236   CXFA_Node* pBeforeFormItem =
237       hBefore ? hBefore->GetDataAcc()->GetNode() : nullptr;
238   CXFA_Node* pNewFormItem =
239       CreateWidgetFormItem(eType, pParentFormItem, pBeforeFormItem);
240   if (!pNewFormItem)
241     return nullptr;
242 
243   pNewFormItem->GetTemplateNode()->SetFlag(XFA_NodeFlag_Initialized, true);
244   pNewFormItem->SetFlag(XFA_NodeFlag_Initialized, true);
245   m_pDocView->RunLayout();
246   CXFA_LayoutItem* pLayout =
247       m_pDocView->GetXFALayout()->GetLayoutItem(pNewFormItem);
248   return static_cast<CXFA_FFWidget*>(pLayout);
249 }
250 
CreateWidgetFormItem(XFA_WIDGETTYPE eType,CXFA_Node * pParent,CXFA_Node * pBefore) const251 CXFA_Node* CXFA_FFWidgetHandler::CreateWidgetFormItem(
252     XFA_WIDGETTYPE eType,
253     CXFA_Node* pParent,
254     CXFA_Node* pBefore) const {
255   switch (eType) {
256     case XFA_WIDGETTYPE_Barcode:
257       return nullptr;
258     case XFA_WIDGETTYPE_PushButton:
259       return CreatePushButton(pParent, pBefore);
260     case XFA_WIDGETTYPE_CheckButton:
261       return CreateCheckButton(pParent, pBefore);
262     case XFA_WIDGETTYPE_ExcludeGroup:
263       return CreateExclGroup(pParent, pBefore);
264     case XFA_WIDGETTYPE_RadioButton:
265       return CreateRadioButton(pParent, pBefore);
266     case XFA_WIDGETTYPE_Arc:
267       return CreateArc(pParent, pBefore);
268     case XFA_WIDGETTYPE_Rectangle:
269       return CreateRectangle(pParent, pBefore);
270     case XFA_WIDGETTYPE_Image:
271       return CreateImage(pParent, pBefore);
272     case XFA_WIDGETTYPE_Line:
273       return CreateLine(pParent, pBefore);
274     case XFA_WIDGETTYPE_Text:
275       return CreateText(pParent, pBefore);
276     case XFA_WIDGETTYPE_DatetimeEdit:
277       return CreateDatetimeEdit(pParent, pBefore);
278     case XFA_WIDGETTYPE_DecimalField:
279       return CreateDecimalField(pParent, pBefore);
280     case XFA_WIDGETTYPE_NumericField:
281       return CreateNumericField(pParent, pBefore);
282     case XFA_WIDGETTYPE_Signature:
283       return CreateSignature(pParent, pBefore);
284     case XFA_WIDGETTYPE_TextEdit:
285       return CreateTextEdit(pParent, pBefore);
286     case XFA_WIDGETTYPE_DropdownList:
287       return CreateDropdownList(pParent, pBefore);
288     case XFA_WIDGETTYPE_ListBox:
289       return CreateListBox(pParent, pBefore);
290     case XFA_WIDGETTYPE_ImageField:
291       return CreateImageField(pParent, pBefore);
292     case XFA_WIDGETTYPE_PasswordEdit:
293       return CreatePasswordEdit(pParent, pBefore);
294     case XFA_WIDGETTYPE_Subform:
295       return CreateSubform(pParent, pBefore);
296     default:
297       return nullptr;
298   }
299 }
300 
CreatePushButton(CXFA_Node * pParent,CXFA_Node * pBefore) const301 CXFA_Node* CXFA_FFWidgetHandler::CreatePushButton(CXFA_Node* pParent,
302                                                   CXFA_Node* pBefore) const {
303   CXFA_Node* pField = CreateField(XFA_Element::Button, pParent, pBefore);
304   CXFA_Node* pCaption = CreateCopyNode(XFA_Element::Caption, pField);
305   CXFA_Node* pValue = CreateCopyNode(XFA_Element::Value, pCaption);
306   CXFA_Node* pText = CreateCopyNode(XFA_Element::Text, pValue);
307   pText->SetContent(L"Button", L"Button", false);
308 
309   CXFA_Node* pPara = CreateCopyNode(XFA_Element::Para, pCaption);
310   pPara->SetEnum(XFA_ATTRIBUTE_VAlign, XFA_ATTRIBUTEENUM_Middle, false);
311   pPara->SetEnum(XFA_ATTRIBUTE_HAlign, XFA_ATTRIBUTEENUM_Center, false);
312   CreateFontNode(pCaption);
313 
314   CXFA_Node* pBorder = CreateCopyNode(XFA_Element::Border, pField);
315   pBorder->SetEnum(XFA_ATTRIBUTE_Hand, XFA_ATTRIBUTEENUM_Right, false);
316 
317   CXFA_Node* pEdge = CreateCopyNode(XFA_Element::Edge, pBorder);
318   pEdge->SetEnum(XFA_ATTRIBUTE_Stroke, XFA_ATTRIBUTEENUM_Raised, false);
319 
320   CXFA_Node* pFill = CreateCopyNode(XFA_Element::Fill, pBorder);
321   CXFA_Node* pColor = CreateCopyNode(XFA_Element::Color, pFill);
322   pColor->SetCData(XFA_ATTRIBUTE_Value, L"212, 208, 200", false);
323 
324   CXFA_Node* pBind = CreateCopyNode(XFA_Element::Bind, pField);
325   pBind->SetEnum(XFA_ATTRIBUTE_Match, XFA_ATTRIBUTEENUM_None);
326 
327   return pField;
328 }
329 
CreateCheckButton(CXFA_Node * pParent,CXFA_Node * pBefore) const330 CXFA_Node* CXFA_FFWidgetHandler::CreateCheckButton(CXFA_Node* pParent,
331                                                    CXFA_Node* pBefore) const {
332   return CreateField(XFA_Element::CheckButton, pParent, pBefore);
333 }
334 
CreateExclGroup(CXFA_Node * pParent,CXFA_Node * pBefore) const335 CXFA_Node* CXFA_FFWidgetHandler::CreateExclGroup(CXFA_Node* pParent,
336                                                  CXFA_Node* pBefore) const {
337   return CreateFormItem(XFA_Element::ExclGroup, pParent, pBefore);
338 }
339 
CreateRadioButton(CXFA_Node * pParent,CXFA_Node * pBefore) const340 CXFA_Node* CXFA_FFWidgetHandler::CreateRadioButton(CXFA_Node* pParent,
341                                                    CXFA_Node* pBefore) const {
342   CXFA_Node* pField = CreateField(XFA_Element::CheckButton, pParent, pBefore);
343   CXFA_Node* pUi = pField->GetFirstChildByClass(XFA_Element::Ui);
344   CXFA_Node* pWidget = pUi->GetFirstChildByClass(XFA_Element::CheckButton);
345   pWidget->SetEnum(XFA_ATTRIBUTE_Shape, XFA_ATTRIBUTEENUM_Round);
346   return pField;
347 }
348 
CreateDatetimeEdit(CXFA_Node * pParent,CXFA_Node * pBefore) const349 CXFA_Node* CXFA_FFWidgetHandler::CreateDatetimeEdit(CXFA_Node* pParent,
350                                                     CXFA_Node* pBefore) const {
351   CXFA_Node* pField = CreateField(XFA_Element::DateTimeEdit, pParent, pBefore);
352   CreateValueNode(XFA_Element::Date, pField);
353   return pField;
354 }
355 
CreateDecimalField(CXFA_Node * pParent,CXFA_Node * pBefore) const356 CXFA_Node* CXFA_FFWidgetHandler::CreateDecimalField(CXFA_Node* pParent,
357                                                     CXFA_Node* pBefore) const {
358   CXFA_Node* pField = CreateNumericField(pParent, pBefore);
359   CreateValueNode(XFA_Element::Decimal, pField);
360   return pField;
361 }
362 
CreateNumericField(CXFA_Node * pParent,CXFA_Node * pBefore) const363 CXFA_Node* CXFA_FFWidgetHandler::CreateNumericField(CXFA_Node* pParent,
364                                                     CXFA_Node* pBefore) const {
365   return CreateField(XFA_Element::NumericEdit, pParent, pBefore);
366 }
367 
CreateSignature(CXFA_Node * pParent,CXFA_Node * pBefore) const368 CXFA_Node* CXFA_FFWidgetHandler::CreateSignature(CXFA_Node* pParent,
369                                                  CXFA_Node* pBefore) const {
370   return CreateField(XFA_Element::Signature, pParent, pBefore);
371 }
372 
CreateTextEdit(CXFA_Node * pParent,CXFA_Node * pBefore) const373 CXFA_Node* CXFA_FFWidgetHandler::CreateTextEdit(CXFA_Node* pParent,
374                                                 CXFA_Node* pBefore) const {
375   return CreateField(XFA_Element::TextEdit, pParent, pBefore);
376 }
377 
CreateDropdownList(CXFA_Node * pParent,CXFA_Node * pBefore) const378 CXFA_Node* CXFA_FFWidgetHandler::CreateDropdownList(CXFA_Node* pParent,
379                                                     CXFA_Node* pBefore) const {
380   return CreateField(XFA_Element::ChoiceList, pParent, pBefore);
381 }
382 
CreateListBox(CXFA_Node * pParent,CXFA_Node * pBefore) const383 CXFA_Node* CXFA_FFWidgetHandler::CreateListBox(CXFA_Node* pParent,
384                                                CXFA_Node* pBefore) const {
385   CXFA_Node* pField = CreateDropdownList(pParent, pBefore);
386   CXFA_Node* pUi = pField->GetNodeItem(XFA_NODEITEM_FirstChild);
387   CXFA_Node* pListBox = pUi->GetNodeItem(XFA_NODEITEM_FirstChild);
388   pListBox->SetEnum(XFA_ATTRIBUTE_Open, XFA_ATTRIBUTEENUM_Always);
389   pListBox->SetEnum(XFA_ATTRIBUTE_CommitOn, XFA_ATTRIBUTEENUM_Exit);
390   return pField;
391 }
392 
CreateImageField(CXFA_Node * pParent,CXFA_Node * pBefore) const393 CXFA_Node* CXFA_FFWidgetHandler::CreateImageField(CXFA_Node* pParent,
394                                                   CXFA_Node* pBefore) const {
395   return CreateField(XFA_Element::ImageEdit, pParent, pBefore);
396 }
397 
CreatePasswordEdit(CXFA_Node * pParent,CXFA_Node * pBefore) const398 CXFA_Node* CXFA_FFWidgetHandler::CreatePasswordEdit(CXFA_Node* pParent,
399                                                     CXFA_Node* pBefore) const {
400   CXFA_Node* pField = CreateField(XFA_Element::PasswordEdit, pParent, pBefore);
401   CXFA_Node* pBind = CreateCopyNode(XFA_Element::Bind, pField);
402   pBind->SetEnum(XFA_ATTRIBUTE_Match, XFA_ATTRIBUTEENUM_None, false);
403   return pField;
404 }
405 
CreateField(XFA_Element eElement,CXFA_Node * pParent,CXFA_Node * pBefore) const406 CXFA_Node* CXFA_FFWidgetHandler::CreateField(XFA_Element eElement,
407                                              CXFA_Node* pParent,
408                                              CXFA_Node* pBefore) const {
409   CXFA_Node* pField = CreateFormItem(XFA_Element::Field, pParent, pBefore);
410   CreateCopyNode(eElement, CreateCopyNode(XFA_Element::Ui, pField));
411   CreateFontNode(pField);
412   return pField;
413 }
414 
CreateArc(CXFA_Node * pParent,CXFA_Node * pBefore) const415 CXFA_Node* CXFA_FFWidgetHandler::CreateArc(CXFA_Node* pParent,
416                                            CXFA_Node* pBefore) const {
417   return CreateDraw(XFA_Element::Arc, pParent, pBefore);
418 }
419 
CreateRectangle(CXFA_Node * pParent,CXFA_Node * pBefore) const420 CXFA_Node* CXFA_FFWidgetHandler::CreateRectangle(CXFA_Node* pParent,
421                                                  CXFA_Node* pBefore) const {
422   return CreateDraw(XFA_Element::Rectangle, pParent, pBefore);
423 }
424 
CreateImage(CXFA_Node * pParent,CXFA_Node * pBefore) const425 CXFA_Node* CXFA_FFWidgetHandler::CreateImage(CXFA_Node* pParent,
426                                              CXFA_Node* pBefore) const {
427   CXFA_Node* pField = CreateDraw(XFA_Element::Image, pParent, pBefore);
428   CreateCopyNode(XFA_Element::ImageEdit,
429                  CreateCopyNode(XFA_Element::Ui, pField));
430   return pField;
431 }
432 
CreateLine(CXFA_Node * pParent,CXFA_Node * pBefore) const433 CXFA_Node* CXFA_FFWidgetHandler::CreateLine(CXFA_Node* pParent,
434                                             CXFA_Node* pBefore) const {
435   return CreateDraw(XFA_Element::Line, pParent, pBefore);
436 }
437 
CreateText(CXFA_Node * pParent,CXFA_Node * pBefore) const438 CXFA_Node* CXFA_FFWidgetHandler::CreateText(CXFA_Node* pParent,
439                                             CXFA_Node* pBefore) const {
440   CXFA_Node* pField = CreateDraw(XFA_Element::Text, pParent, pBefore);
441   CreateCopyNode(XFA_Element::TextEdit,
442                  CreateCopyNode(XFA_Element::Ui, pField));
443   CreateFontNode(pField);
444   return pField;
445 }
446 
CreateDraw(XFA_Element eElement,CXFA_Node * pParent,CXFA_Node * pBefore) const447 CXFA_Node* CXFA_FFWidgetHandler::CreateDraw(XFA_Element eElement,
448                                             CXFA_Node* pParent,
449                                             CXFA_Node* pBefore) const {
450   CXFA_Node* pDraw = CreateFormItem(XFA_Element::Draw, pParent, pBefore);
451   CreateValueNode(eElement, pDraw);
452   return pDraw;
453 }
454 
CreateSubform(CXFA_Node * pParent,CXFA_Node * pBefore) const455 CXFA_Node* CXFA_FFWidgetHandler::CreateSubform(CXFA_Node* pParent,
456                                                CXFA_Node* pBefore) const {
457   return CreateFormItem(XFA_Element::Subform, pParent, pBefore);
458 }
459 
CreateFormItem(XFA_Element eElement,CXFA_Node * pParent,CXFA_Node * pBefore) const460 CXFA_Node* CXFA_FFWidgetHandler::CreateFormItem(XFA_Element eElement,
461                                                 CXFA_Node* pParent,
462                                                 CXFA_Node* pBefore) const {
463   CXFA_Node* pTemplateParent = pParent ? pParent->GetTemplateNode() : nullptr;
464   CXFA_Node* pNewFormItem = pTemplateParent->CloneTemplateToForm(false);
465   if (pParent)
466     pParent->InsertChild(pNewFormItem, pBefore);
467   return pNewFormItem;
468 }
469 
CreateCopyNode(XFA_Element eElement,CXFA_Node * pParent,CXFA_Node * pBefore) const470 CXFA_Node* CXFA_FFWidgetHandler::CreateCopyNode(XFA_Element eElement,
471                                                 CXFA_Node* pParent,
472                                                 CXFA_Node* pBefore) const {
473   CXFA_Node* pTemplateParent = pParent ? pParent->GetTemplateNode() : nullptr;
474   CXFA_Node* pNewNode =
475       CreateTemplateNode(eElement, pTemplateParent,
476                          pBefore ? pBefore->GetTemplateNode() : nullptr)
477           ->Clone(false);
478   if (pParent)
479     pParent->InsertChild(pNewNode, pBefore);
480   return pNewNode;
481 }
482 
CreateTemplateNode(XFA_Element eElement,CXFA_Node * pParent,CXFA_Node * pBefore) const483 CXFA_Node* CXFA_FFWidgetHandler::CreateTemplateNode(XFA_Element eElement,
484                                                     CXFA_Node* pParent,
485                                                     CXFA_Node* pBefore) const {
486   CXFA_Document* pXFADoc = GetXFADoc();
487   CXFA_Node* pNewTemplateNode =
488       pXFADoc->CreateNode(XFA_XDPPACKET_Template, eElement);
489   if (pParent)
490     pParent->InsertChild(pNewTemplateNode, pBefore);
491   return pNewTemplateNode;
492 }
493 
CreateFontNode(CXFA_Node * pParent) const494 CXFA_Node* CXFA_FFWidgetHandler::CreateFontNode(CXFA_Node* pParent) const {
495   CXFA_Node* pFont = CreateCopyNode(XFA_Element::Font, pParent);
496   pFont->SetCData(XFA_ATTRIBUTE_Typeface, L"Myriad Pro", false);
497   return pFont;
498 }
499 
CreateMarginNode(CXFA_Node * pParent,uint32_t dwFlags,FX_FLOAT fInsets[4]) const500 CXFA_Node* CXFA_FFWidgetHandler::CreateMarginNode(CXFA_Node* pParent,
501                                                   uint32_t dwFlags,
502                                                   FX_FLOAT fInsets[4]) const {
503   CXFA_Node* pMargin = CreateCopyNode(XFA_Element::Margin, pParent);
504   if (dwFlags & 0x01)
505     pMargin->SetMeasure(XFA_ATTRIBUTE_LeftInset,
506                         CXFA_Measurement(fInsets[0], XFA_UNIT_Pt), false);
507   if (dwFlags & 0x02)
508     pMargin->SetMeasure(XFA_ATTRIBUTE_TopInset,
509                         CXFA_Measurement(fInsets[1], XFA_UNIT_Pt), false);
510   if (dwFlags & 0x04)
511     pMargin->SetMeasure(XFA_ATTRIBUTE_RightInset,
512                         CXFA_Measurement(fInsets[2], XFA_UNIT_Pt), false);
513   if (dwFlags & 0x08)
514     pMargin->SetMeasure(XFA_ATTRIBUTE_BottomInset,
515                         CXFA_Measurement(fInsets[3], XFA_UNIT_Pt), false);
516   return pMargin;
517 }
518 
CreateValueNode(XFA_Element eValue,CXFA_Node * pParent) const519 CXFA_Node* CXFA_FFWidgetHandler::CreateValueNode(XFA_Element eValue,
520                                                  CXFA_Node* pParent) const {
521   CXFA_Node* pValue = CreateCopyNode(XFA_Element::Value, pParent);
522   CreateCopyNode(eValue, pValue);
523   return pValue;
524 }
525 
GetObjFactory() const526 CXFA_Document* CXFA_FFWidgetHandler::GetObjFactory() const {
527   return GetXFADoc();
528 }
529 
GetXFADoc() const530 CXFA_Document* CXFA_FFWidgetHandler::GetXFADoc() const {
531   return m_pDocView->GetDoc()->GetXFADoc();
532 }
533 
534