• 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_ffwidgethandler.h"
8 
9 #include <vector>
10 
11 #include "fxjs/xfa/cjx_object.h"
12 #include "xfa/fxfa/cxfa_ffdoc.h"
13 #include "xfa/fxfa/cxfa_ffdocview.h"
14 #include "xfa/fxfa/cxfa_fffield.h"
15 #include "xfa/fxfa/cxfa_ffwidget.h"
16 #include "xfa/fxfa/cxfa_fwladapterwidgetmgr.h"
17 #include "xfa/fxfa/parser/cxfa_calculate.h"
18 #include "xfa/fxfa/parser/cxfa_checkbutton.h"
19 #include "xfa/fxfa/parser/cxfa_layoutprocessor.h"
20 #include "xfa/fxfa/parser/cxfa_measurement.h"
21 #include "xfa/fxfa/parser/cxfa_node.h"
22 #include "xfa/fxfa/parser/cxfa_ui.h"
23 #include "xfa/fxfa/parser/cxfa_validate.h"
24 
CXFA_FFWidgetHandler(CXFA_FFDocView * pDocView)25 CXFA_FFWidgetHandler::CXFA_FFWidgetHandler(CXFA_FFDocView* pDocView)
26     : m_pDocView(pDocView) {}
27 
~CXFA_FFWidgetHandler()28 CXFA_FFWidgetHandler::~CXFA_FFWidgetHandler() {}
29 
OnMouseEnter(CXFA_FFWidget * hWidget)30 bool CXFA_FFWidgetHandler::OnMouseEnter(CXFA_FFWidget* hWidget) {
31   m_pDocView->LockUpdate();
32   bool bRet = hWidget->OnMouseEnter();
33   m_pDocView->UnlockUpdate();
34   m_pDocView->UpdateDocView();
35   return bRet;
36 }
37 
OnMouseExit(CXFA_FFWidget * hWidget)38 bool CXFA_FFWidgetHandler::OnMouseExit(CXFA_FFWidget* hWidget) {
39   m_pDocView->LockUpdate();
40   bool bRet = hWidget->OnMouseExit();
41   m_pDocView->UnlockUpdate();
42   m_pDocView->UpdateDocView();
43   return bRet;
44 }
45 
OnLButtonDown(CXFA_FFWidget * hWidget,uint32_t dwFlags,const CFX_PointF & point)46 bool CXFA_FFWidgetHandler::OnLButtonDown(CXFA_FFWidget* hWidget,
47                                          uint32_t dwFlags,
48                                          const CFX_PointF& point) {
49   m_pDocView->LockUpdate();
50   bool bRet = hWidget->OnLButtonDown(dwFlags, hWidget->Rotate2Normal(point));
51   if (bRet && m_pDocView->SetFocus(hWidget)) {
52     m_pDocView->GetDoc()->GetDocEnvironment()->SetFocusWidget(
53         m_pDocView->GetDoc(), hWidget);
54   }
55   m_pDocView->UnlockUpdate();
56   m_pDocView->UpdateDocView();
57   return bRet;
58 }
59 
OnLButtonUp(CXFA_FFWidget * hWidget,uint32_t dwFlags,const CFX_PointF & point)60 bool CXFA_FFWidgetHandler::OnLButtonUp(CXFA_FFWidget* hWidget,
61                                        uint32_t dwFlags,
62                                        const CFX_PointF& point) {
63   m_pDocView->LockUpdate();
64   m_pDocView->m_bLayoutEvent = true;
65   bool bRet = hWidget->OnLButtonUp(dwFlags, hWidget->Rotate2Normal(point));
66   m_pDocView->UnlockUpdate();
67   m_pDocView->UpdateDocView();
68   return bRet;
69 }
70 
OnLButtonDblClk(CXFA_FFWidget * hWidget,uint32_t dwFlags,const CFX_PointF & point)71 bool CXFA_FFWidgetHandler::OnLButtonDblClk(CXFA_FFWidget* hWidget,
72                                            uint32_t dwFlags,
73                                            const CFX_PointF& point) {
74   bool bRet = hWidget->OnLButtonDblClk(dwFlags, hWidget->Rotate2Normal(point));
75   m_pDocView->RunInvalidate();
76   return bRet;
77 }
78 
OnMouseMove(CXFA_FFWidget * hWidget,uint32_t dwFlags,const CFX_PointF & point)79 bool CXFA_FFWidgetHandler::OnMouseMove(CXFA_FFWidget* hWidget,
80                                        uint32_t dwFlags,
81                                        const CFX_PointF& point) {
82   bool bRet = hWidget->OnMouseMove(dwFlags, hWidget->Rotate2Normal(point));
83   m_pDocView->RunInvalidate();
84   return bRet;
85 }
86 
OnMouseWheel(CXFA_FFWidget * hWidget,uint32_t dwFlags,int16_t zDelta,const CFX_PointF & point)87 bool CXFA_FFWidgetHandler::OnMouseWheel(CXFA_FFWidget* hWidget,
88                                         uint32_t dwFlags,
89                                         int16_t zDelta,
90                                         const CFX_PointF& point) {
91   bool bRet =
92       hWidget->OnMouseWheel(dwFlags, zDelta, hWidget->Rotate2Normal(point));
93   m_pDocView->RunInvalidate();
94   return bRet;
95 }
96 
OnRButtonDown(CXFA_FFWidget * hWidget,uint32_t dwFlags,const CFX_PointF & point)97 bool CXFA_FFWidgetHandler::OnRButtonDown(CXFA_FFWidget* hWidget,
98                                          uint32_t dwFlags,
99                                          const CFX_PointF& point) {
100   bool bRet = hWidget->OnRButtonDown(dwFlags, hWidget->Rotate2Normal(point));
101   if (bRet && m_pDocView->SetFocus(hWidget)) {
102     m_pDocView->GetDoc()->GetDocEnvironment()->SetFocusWidget(
103         m_pDocView->GetDoc(), hWidget);
104   }
105   m_pDocView->RunInvalidate();
106   return bRet;
107 }
108 
OnRButtonUp(CXFA_FFWidget * hWidget,uint32_t dwFlags,const CFX_PointF & point)109 bool CXFA_FFWidgetHandler::OnRButtonUp(CXFA_FFWidget* hWidget,
110                                        uint32_t dwFlags,
111                                        const CFX_PointF& point) {
112   bool bRet = hWidget->OnRButtonUp(dwFlags, hWidget->Rotate2Normal(point));
113   m_pDocView->RunInvalidate();
114   return bRet;
115 }
116 
OnRButtonDblClk(CXFA_FFWidget * hWidget,uint32_t dwFlags,const CFX_PointF & point)117 bool CXFA_FFWidgetHandler::OnRButtonDblClk(CXFA_FFWidget* hWidget,
118                                            uint32_t dwFlags,
119                                            const CFX_PointF& point) {
120   bool bRet = hWidget->OnRButtonDblClk(dwFlags, hWidget->Rotate2Normal(point));
121   m_pDocView->RunInvalidate();
122   return bRet;
123 }
124 
OnKeyDown(CXFA_FFWidget * hWidget,uint32_t dwKeyCode,uint32_t dwFlags)125 bool CXFA_FFWidgetHandler::OnKeyDown(CXFA_FFWidget* hWidget,
126                                      uint32_t dwKeyCode,
127                                      uint32_t dwFlags) {
128   bool bRet = hWidget->OnKeyDown(dwKeyCode, dwFlags);
129   m_pDocView->RunInvalidate();
130   m_pDocView->UpdateDocView();
131   return bRet;
132 }
133 
OnKeyUp(CXFA_FFWidget * hWidget,uint32_t dwKeyCode,uint32_t dwFlags)134 bool CXFA_FFWidgetHandler::OnKeyUp(CXFA_FFWidget* hWidget,
135                                    uint32_t dwKeyCode,
136                                    uint32_t dwFlags) {
137   bool bRet = hWidget->OnKeyUp(dwKeyCode, dwFlags);
138   m_pDocView->RunInvalidate();
139   return bRet;
140 }
141 
OnChar(CXFA_FFWidget * hWidget,uint32_t dwChar,uint32_t dwFlags)142 bool CXFA_FFWidgetHandler::OnChar(CXFA_FFWidget* hWidget,
143                                   uint32_t dwChar,
144                                   uint32_t dwFlags) {
145   bool bRet = hWidget->OnChar(dwChar, dwFlags);
146   m_pDocView->RunInvalidate();
147   return bRet;
148 }
149 
GetSelectedText(CXFA_FFWidget * widget)150 WideString CXFA_FFWidgetHandler::GetSelectedText(CXFA_FFWidget* widget) {
151   if (!widget->CanCopy())
152     return WideString();
153 
154   return widget->Copy().value_or(WideString());
155 }
156 
PasteText(CXFA_FFWidget * widget,const WideString & text)157 void CXFA_FFWidgetHandler::PasteText(CXFA_FFWidget* widget,
158                                      const WideString& text) {
159   if (!widget->CanPaste())
160     return;
161 
162   widget->Paste(text);
163 }
164 
OnHitTest(CXFA_FFWidget * hWidget,const CFX_PointF & point)165 FWL_WidgetHit CXFA_FFWidgetHandler::OnHitTest(CXFA_FFWidget* hWidget,
166                                               const CFX_PointF& point) {
167   if (!(hWidget->GetStatus() & XFA_WidgetStatus_Visible))
168     return FWL_WidgetHit::Unknown;
169   return hWidget->OnHitTest(hWidget->Rotate2Normal(point));
170 }
171 
OnSetCursor(CXFA_FFWidget * hWidget,const CFX_PointF & point)172 bool CXFA_FFWidgetHandler::OnSetCursor(CXFA_FFWidget* hWidget,
173                                        const CFX_PointF& point) {
174   return hWidget->OnSetCursor(hWidget->Rotate2Normal(point));
175 }
176 
RenderWidget(CXFA_FFWidget * hWidget,CXFA_Graphics * pGS,const CFX_Matrix & matrix,bool bHighlight)177 void CXFA_FFWidgetHandler::RenderWidget(CXFA_FFWidget* hWidget,
178                                         CXFA_Graphics* pGS,
179                                         const CFX_Matrix& matrix,
180                                         bool bHighlight) {
181   hWidget->RenderWidget(pGS, matrix,
182                         bHighlight ? XFA_WidgetStatus_Highlight : 0);
183 }
184 
HasEvent(CXFA_WidgetAcc * pWidgetAcc,XFA_EVENTTYPE eEventType)185 bool CXFA_FFWidgetHandler::HasEvent(CXFA_WidgetAcc* pWidgetAcc,
186                                     XFA_EVENTTYPE eEventType) {
187   if (eEventType == XFA_EVENT_Unknown)
188     return false;
189   if (!pWidgetAcc)
190     return false;
191 
192   CXFA_Node* node = pWidgetAcc->GetNode();
193   if (!node || node->GetElementType() == XFA_Element::Draw)
194     return false;
195 
196   switch (eEventType) {
197     case XFA_EVENT_Calculate: {
198       CXFA_Calculate* calc = node->GetCalculateIfExists();
199       return calc && calc->GetScriptIfExists();
200     }
201     case XFA_EVENT_Validate: {
202       CXFA_Validate* validate = node->GetValidateIfExists();
203       return validate && validate->GetScriptIfExists();
204     }
205     default:
206       break;
207   }
208   return !pWidgetAcc->GetEventByActivity(gs_EventActivity[eEventType], false)
209               .empty();
210 }
211 
ProcessEvent(CXFA_WidgetAcc * pWidgetAcc,CXFA_EventParam * pParam)212 int32_t CXFA_FFWidgetHandler::ProcessEvent(CXFA_WidgetAcc* pWidgetAcc,
213                                            CXFA_EventParam* pParam) {
214   if (!pParam || pParam->m_eType == XFA_EVENT_Unknown)
215     return XFA_EVENTERROR_NotExist;
216   if (!pWidgetAcc)
217     return XFA_EVENTERROR_NotExist;
218 
219   CXFA_Node* node = pWidgetAcc->GetNode();
220   if (!node || node->GetElementType() == XFA_Element::Draw)
221     return XFA_EVENTERROR_NotExist;
222 
223   switch (pParam->m_eType) {
224     case XFA_EVENT_Calculate:
225       return node->ProcessCalculate(m_pDocView);
226     case XFA_EVENT_Validate:
227       if (m_pDocView->GetDoc()->GetDocEnvironment()->IsValidationsEnabled(
228               m_pDocView->GetDoc())) {
229         return node->ProcessValidate(m_pDocView, 0);
230       }
231       return XFA_EVENTERROR_Disabled;
232     case XFA_EVENT_InitCalculate: {
233       CXFA_Calculate* calc = node->GetCalculateIfExists();
234       if (!calc)
235         return XFA_EVENTERROR_NotExist;
236       if (node->IsUserInteractive())
237         return XFA_EVENTERROR_Disabled;
238       return node->ExecuteScript(m_pDocView, calc->GetScriptIfExists(), pParam);
239     }
240     default:
241       break;
242   }
243   int32_t iRet =
244       node->ProcessEvent(m_pDocView, gs_EventActivity[pParam->m_eType], pParam);
245   return iRet;
246 }
247 
CreateWidget(CXFA_FFWidget * hParent,XFA_WIDGETTYPE eType,CXFA_FFWidget * hBefore)248 CXFA_FFWidget* CXFA_FFWidgetHandler::CreateWidget(CXFA_FFWidget* hParent,
249                                                   XFA_WIDGETTYPE eType,
250                                                   CXFA_FFWidget* hBefore) {
251   CXFA_Node* pParentFormItem = hParent ? hParent->GetNode() : nullptr;
252   CXFA_Node* pBeforeFormItem = hBefore ? hBefore->GetNode() : nullptr;
253   CXFA_Node* pNewFormItem =
254       CreateWidgetFormItem(eType, pParentFormItem, pBeforeFormItem);
255   if (!pNewFormItem)
256     return nullptr;
257 
258   CXFA_Node* templateNode = pNewFormItem->GetTemplateNodeIfExists();
259   if (!templateNode)
260     return nullptr;
261 
262   templateNode->SetFlag(XFA_NodeFlag_Initialized, true);
263   pNewFormItem->SetFlag(XFA_NodeFlag_Initialized, true);
264   m_pDocView->RunLayout();
265   CXFA_LayoutItem* pLayout =
266       m_pDocView->GetXFALayout()->GetLayoutItem(pNewFormItem);
267   return static_cast<CXFA_FFWidget*>(pLayout);
268 }
269 
CreateWidgetFormItem(XFA_WIDGETTYPE eType,CXFA_Node * pParent,CXFA_Node * pBefore) const270 CXFA_Node* CXFA_FFWidgetHandler::CreateWidgetFormItem(
271     XFA_WIDGETTYPE eType,
272     CXFA_Node* pParent,
273     CXFA_Node* pBefore) const {
274   switch (eType) {
275     case XFA_WIDGETTYPE_Barcode:
276       return nullptr;
277     case XFA_WIDGETTYPE_PushButton:
278       return CreatePushButton(pParent, pBefore);
279     case XFA_WIDGETTYPE_CheckButton:
280       return CreateCheckButton(pParent, pBefore);
281     case XFA_WIDGETTYPE_ExcludeGroup:
282       return CreateExclGroup(pParent, pBefore);
283     case XFA_WIDGETTYPE_RadioButton:
284       return CreateRadioButton(pParent, pBefore);
285     case XFA_WIDGETTYPE_Arc:
286       return CreateArc(pParent, pBefore);
287     case XFA_WIDGETTYPE_Rectangle:
288       return CreateRectangle(pParent, pBefore);
289     case XFA_WIDGETTYPE_Image:
290       return CreateImage(pParent, pBefore);
291     case XFA_WIDGETTYPE_Line:
292       return CreateLine(pParent, pBefore);
293     case XFA_WIDGETTYPE_Text:
294       return CreateText(pParent, pBefore);
295     case XFA_WIDGETTYPE_DatetimeEdit:
296       return CreateDatetimeEdit(pParent, pBefore);
297     case XFA_WIDGETTYPE_DecimalField:
298       return CreateDecimalField(pParent, pBefore);
299     case XFA_WIDGETTYPE_NumericField:
300       return CreateNumericField(pParent, pBefore);
301     case XFA_WIDGETTYPE_Signature:
302       return CreateSignature(pParent, pBefore);
303     case XFA_WIDGETTYPE_TextEdit:
304       return CreateTextEdit(pParent, pBefore);
305     case XFA_WIDGETTYPE_DropdownList:
306       return CreateDropdownList(pParent, pBefore);
307     case XFA_WIDGETTYPE_ListBox:
308       return CreateListBox(pParent, pBefore);
309     case XFA_WIDGETTYPE_ImageField:
310       return CreateImageField(pParent, pBefore);
311     case XFA_WIDGETTYPE_PasswordEdit:
312       return CreatePasswordEdit(pParent, pBefore);
313     case XFA_WIDGETTYPE_Subform:
314       return CreateSubform(pParent, pBefore);
315     default:
316       return nullptr;
317   }
318 }
319 
CreatePushButton(CXFA_Node * pParent,CXFA_Node * pBefore) const320 CXFA_Node* CXFA_FFWidgetHandler::CreatePushButton(CXFA_Node* pParent,
321                                                   CXFA_Node* pBefore) const {
322   CXFA_Node* pField = CreateField(XFA_Element::Button, pParent, pBefore);
323   CXFA_Node* pCaption = CreateCopyNode(XFA_Element::Caption, pField);
324   CXFA_Node* pValue = CreateCopyNode(XFA_Element::Value, pCaption);
325   CXFA_Node* pText = CreateCopyNode(XFA_Element::Text, pValue);
326   pText->JSObject()->SetContent(L"Button", L"Button", false, false, true);
327 
328   CXFA_Node* pPara = CreateCopyNode(XFA_Element::Para, pCaption);
329   pPara->JSObject()->SetEnum(XFA_Attribute::VAlign, XFA_AttributeEnum::Middle,
330                              false);
331   pPara->JSObject()->SetEnum(XFA_Attribute::HAlign, XFA_AttributeEnum::Center,
332                              false);
333   CreateFontNode(pCaption);
334 
335   CXFA_Node* pBorder = CreateCopyNode(XFA_Element::Border, pField);
336   pBorder->JSObject()->SetEnum(XFA_Attribute::Hand, XFA_AttributeEnum::Right,
337                                false);
338 
339   CXFA_Node* pEdge = CreateCopyNode(XFA_Element::Edge, pBorder);
340   pEdge->JSObject()->SetEnum(XFA_Attribute::Stroke, XFA_AttributeEnum::Raised,
341                              false);
342 
343   CXFA_Node* pFill = CreateCopyNode(XFA_Element::Fill, pBorder);
344   CXFA_Node* pColor = CreateCopyNode(XFA_Element::Color, pFill);
345   pColor->JSObject()->SetCData(XFA_Attribute::Value, L"212, 208, 200", false,
346                                false);
347 
348   CXFA_Node* pBind = CreateCopyNode(XFA_Element::Bind, pField);
349   pBind->JSObject()->SetEnum(XFA_Attribute::Match, XFA_AttributeEnum::None,
350                              false);
351 
352   return pField;
353 }
354 
CreateCheckButton(CXFA_Node * pParent,CXFA_Node * pBefore) const355 CXFA_Node* CXFA_FFWidgetHandler::CreateCheckButton(CXFA_Node* pParent,
356                                                    CXFA_Node* pBefore) const {
357   return CreateField(XFA_Element::CheckButton, pParent, pBefore);
358 }
359 
CreateExclGroup(CXFA_Node * pParent,CXFA_Node * pBefore) const360 CXFA_Node* CXFA_FFWidgetHandler::CreateExclGroup(CXFA_Node* pParent,
361                                                  CXFA_Node* pBefore) const {
362   return CreateFormItem(XFA_Element::ExclGroup, pParent, pBefore);
363 }
364 
CreateRadioButton(CXFA_Node * pParent,CXFA_Node * pBefore) const365 CXFA_Node* CXFA_FFWidgetHandler::CreateRadioButton(CXFA_Node* pParent,
366                                                    CXFA_Node* pBefore) const {
367   CXFA_Node* pField = CreateField(XFA_Element::CheckButton, pParent, pBefore);
368   CXFA_Ui* pUi = pField->GetFirstChildByClass<CXFA_Ui>(XFA_Element::Ui);
369   CXFA_CheckButton* pWidget =
370       pUi->GetFirstChildByClass<CXFA_CheckButton>(XFA_Element::CheckButton);
371   pWidget->JSObject()->SetEnum(XFA_Attribute::Shape, XFA_AttributeEnum::Round,
372                                false);
373   return pField;
374 }
375 
CreateDatetimeEdit(CXFA_Node * pParent,CXFA_Node * pBefore) const376 CXFA_Node* CXFA_FFWidgetHandler::CreateDatetimeEdit(CXFA_Node* pParent,
377                                                     CXFA_Node* pBefore) const {
378   CXFA_Node* pField = CreateField(XFA_Element::DateTimeEdit, pParent, pBefore);
379   CreateValueNode(XFA_Element::Date, pField);
380   return pField;
381 }
382 
CreateDecimalField(CXFA_Node * pParent,CXFA_Node * pBefore) const383 CXFA_Node* CXFA_FFWidgetHandler::CreateDecimalField(CXFA_Node* pParent,
384                                                     CXFA_Node* pBefore) const {
385   CXFA_Node* pField = CreateNumericField(pParent, pBefore);
386   CreateValueNode(XFA_Element::Decimal, pField);
387   return pField;
388 }
389 
CreateNumericField(CXFA_Node * pParent,CXFA_Node * pBefore) const390 CXFA_Node* CXFA_FFWidgetHandler::CreateNumericField(CXFA_Node* pParent,
391                                                     CXFA_Node* pBefore) const {
392   return CreateField(XFA_Element::NumericEdit, pParent, pBefore);
393 }
394 
CreateSignature(CXFA_Node * pParent,CXFA_Node * pBefore) const395 CXFA_Node* CXFA_FFWidgetHandler::CreateSignature(CXFA_Node* pParent,
396                                                  CXFA_Node* pBefore) const {
397   return CreateField(XFA_Element::Signature, pParent, pBefore);
398 }
399 
CreateTextEdit(CXFA_Node * pParent,CXFA_Node * pBefore) const400 CXFA_Node* CXFA_FFWidgetHandler::CreateTextEdit(CXFA_Node* pParent,
401                                                 CXFA_Node* pBefore) const {
402   return CreateField(XFA_Element::TextEdit, pParent, pBefore);
403 }
404 
CreateDropdownList(CXFA_Node * pParent,CXFA_Node * pBefore) const405 CXFA_Node* CXFA_FFWidgetHandler::CreateDropdownList(CXFA_Node* pParent,
406                                                     CXFA_Node* pBefore) const {
407   return CreateField(XFA_Element::ChoiceList, pParent, pBefore);
408 }
409 
CreateListBox(CXFA_Node * pParent,CXFA_Node * pBefore) const410 CXFA_Node* CXFA_FFWidgetHandler::CreateListBox(CXFA_Node* pParent,
411                                                CXFA_Node* pBefore) const {
412   CXFA_Node* pField = CreateDropdownList(pParent, pBefore);
413   CXFA_Node* pUi = pField->GetFirstChild();
414   CXFA_Node* pListBox = pUi->GetFirstChild();
415   pListBox->JSObject()->SetEnum(XFA_Attribute::Open, XFA_AttributeEnum::Always,
416                                 false);
417   pListBox->JSObject()->SetEnum(XFA_Attribute::CommitOn,
418                                 XFA_AttributeEnum::Exit, false);
419   return pField;
420 }
421 
CreateImageField(CXFA_Node * pParent,CXFA_Node * pBefore) const422 CXFA_Node* CXFA_FFWidgetHandler::CreateImageField(CXFA_Node* pParent,
423                                                   CXFA_Node* pBefore) const {
424   return CreateField(XFA_Element::ImageEdit, pParent, pBefore);
425 }
426 
CreatePasswordEdit(CXFA_Node * pParent,CXFA_Node * pBefore) const427 CXFA_Node* CXFA_FFWidgetHandler::CreatePasswordEdit(CXFA_Node* pParent,
428                                                     CXFA_Node* pBefore) const {
429   CXFA_Node* pField = CreateField(XFA_Element::PasswordEdit, pParent, pBefore);
430   CXFA_Node* pBind = CreateCopyNode(XFA_Element::Bind, pField);
431   pBind->JSObject()->SetEnum(XFA_Attribute::Match, XFA_AttributeEnum::None,
432                              false);
433   return pField;
434 }
435 
CreateField(XFA_Element eElement,CXFA_Node * pParent,CXFA_Node * pBefore) const436 CXFA_Node* CXFA_FFWidgetHandler::CreateField(XFA_Element eElement,
437                                              CXFA_Node* pParent,
438                                              CXFA_Node* pBefore) const {
439   CXFA_Node* pField = CreateFormItem(XFA_Element::Field, pParent, pBefore);
440   CreateCopyNode(eElement, CreateCopyNode(XFA_Element::Ui, pField));
441   CreateFontNode(pField);
442   return pField;
443 }
444 
CreateArc(CXFA_Node * pParent,CXFA_Node * pBefore) const445 CXFA_Node* CXFA_FFWidgetHandler::CreateArc(CXFA_Node* pParent,
446                                            CXFA_Node* pBefore) const {
447   return CreateDraw(XFA_Element::Arc, pParent, pBefore);
448 }
449 
CreateRectangle(CXFA_Node * pParent,CXFA_Node * pBefore) const450 CXFA_Node* CXFA_FFWidgetHandler::CreateRectangle(CXFA_Node* pParent,
451                                                  CXFA_Node* pBefore) const {
452   return CreateDraw(XFA_Element::Rectangle, pParent, pBefore);
453 }
454 
CreateImage(CXFA_Node * pParent,CXFA_Node * pBefore) const455 CXFA_Node* CXFA_FFWidgetHandler::CreateImage(CXFA_Node* pParent,
456                                              CXFA_Node* pBefore) const {
457   CXFA_Node* pField = CreateDraw(XFA_Element::Image, pParent, pBefore);
458   CreateCopyNode(XFA_Element::ImageEdit,
459                  CreateCopyNode(XFA_Element::Ui, pField));
460   return pField;
461 }
462 
CreateLine(CXFA_Node * pParent,CXFA_Node * pBefore) const463 CXFA_Node* CXFA_FFWidgetHandler::CreateLine(CXFA_Node* pParent,
464                                             CXFA_Node* pBefore) const {
465   return CreateDraw(XFA_Element::Line, pParent, pBefore);
466 }
467 
CreateText(CXFA_Node * pParent,CXFA_Node * pBefore) const468 CXFA_Node* CXFA_FFWidgetHandler::CreateText(CXFA_Node* pParent,
469                                             CXFA_Node* pBefore) const {
470   CXFA_Node* pField = CreateDraw(XFA_Element::Text, pParent, pBefore);
471   CreateCopyNode(XFA_Element::TextEdit,
472                  CreateCopyNode(XFA_Element::Ui, pField));
473   CreateFontNode(pField);
474   return pField;
475 }
476 
CreateDraw(XFA_Element eElement,CXFA_Node * pParent,CXFA_Node * pBefore) const477 CXFA_Node* CXFA_FFWidgetHandler::CreateDraw(XFA_Element eElement,
478                                             CXFA_Node* pParent,
479                                             CXFA_Node* pBefore) const {
480   CXFA_Node* pDraw = CreateFormItem(XFA_Element::Draw, pParent, pBefore);
481   CreateValueNode(eElement, pDraw);
482   return pDraw;
483 }
484 
CreateSubform(CXFA_Node * pParent,CXFA_Node * pBefore) const485 CXFA_Node* CXFA_FFWidgetHandler::CreateSubform(CXFA_Node* pParent,
486                                                CXFA_Node* pBefore) const {
487   return CreateFormItem(XFA_Element::Subform, pParent, pBefore);
488 }
489 
CreateFormItem(XFA_Element eElement,CXFA_Node * pParent,CXFA_Node * pBefore) const490 CXFA_Node* CXFA_FFWidgetHandler::CreateFormItem(XFA_Element eElement,
491                                                 CXFA_Node* pParent,
492                                                 CXFA_Node* pBefore) const {
493   if (!pParent)
494     return nullptr;
495 
496   CXFA_Node* pTemplateParent = pParent->GetTemplateNodeIfExists();
497   if (!pTemplateParent)
498     return nullptr;
499 
500   CXFA_Node* pNewFormItem = pTemplateParent->CloneTemplateToForm(false);
501   if (pParent)
502     pParent->InsertChild(pNewFormItem, pBefore);
503   return pNewFormItem;
504 }
505 
CreateCopyNode(XFA_Element eElement,CXFA_Node * pParent,CXFA_Node * pBefore) const506 CXFA_Node* CXFA_FFWidgetHandler::CreateCopyNode(XFA_Element eElement,
507                                                 CXFA_Node* pParent,
508                                                 CXFA_Node* pBefore) const {
509   if (!pParent)
510     return nullptr;
511 
512   CXFA_Node* pTemplateParent = pParent->GetTemplateNodeIfExists();
513   CXFA_Node* pNewNode =
514       CreateTemplateNode(eElement, pTemplateParent,
515                          pBefore ? pBefore->GetTemplateNodeIfExists() : nullptr)
516           ->Clone(false);
517   if (pParent)
518     pParent->InsertChild(pNewNode, pBefore);
519   return pNewNode;
520 }
521 
CreateTemplateNode(XFA_Element eElement,CXFA_Node * pParent,CXFA_Node * pBefore) const522 CXFA_Node* CXFA_FFWidgetHandler::CreateTemplateNode(XFA_Element eElement,
523                                                     CXFA_Node* pParent,
524                                                     CXFA_Node* pBefore) const {
525   CXFA_Document* pXFADoc = GetXFADoc();
526   CXFA_Node* pNewTemplateNode =
527       pXFADoc->CreateNode(XFA_PacketType::Template, eElement);
528   if (pParent)
529     pParent->InsertChild(pNewTemplateNode, pBefore);
530   return pNewTemplateNode;
531 }
532 
CreateFontNode(CXFA_Node * pParent) const533 CXFA_Node* CXFA_FFWidgetHandler::CreateFontNode(CXFA_Node* pParent) const {
534   CXFA_Node* pFont = CreateCopyNode(XFA_Element::Font, pParent);
535   pFont->JSObject()->SetCData(XFA_Attribute::Typeface, L"Myriad Pro", false,
536                               false);
537   return pFont;
538 }
539 
CreateMarginNode(CXFA_Node * pParent,uint32_t dwFlags,float fInsets[4]) const540 CXFA_Node* CXFA_FFWidgetHandler::CreateMarginNode(CXFA_Node* pParent,
541                                                   uint32_t dwFlags,
542                                                   float fInsets[4]) const {
543   CXFA_Node* pMargin = CreateCopyNode(XFA_Element::Margin, pParent);
544   if (dwFlags & 0x01)
545     pMargin->JSObject()->SetMeasure(XFA_Attribute::LeftInset,
546                                     CXFA_Measurement(fInsets[0], XFA_Unit::Pt),
547                                     false);
548   if (dwFlags & 0x02)
549     pMargin->JSObject()->SetMeasure(XFA_Attribute::TopInset,
550                                     CXFA_Measurement(fInsets[1], XFA_Unit::Pt),
551                                     false);
552   if (dwFlags & 0x04)
553     pMargin->JSObject()->SetMeasure(XFA_Attribute::RightInset,
554                                     CXFA_Measurement(fInsets[2], XFA_Unit::Pt),
555                                     false);
556   if (dwFlags & 0x08)
557     pMargin->JSObject()->SetMeasure(XFA_Attribute::BottomInset,
558                                     CXFA_Measurement(fInsets[3], XFA_Unit::Pt),
559                                     false);
560   return pMargin;
561 }
562 
CreateValueNode(XFA_Element eValue,CXFA_Node * pParent) const563 CXFA_Node* CXFA_FFWidgetHandler::CreateValueNode(XFA_Element eValue,
564                                                  CXFA_Node* pParent) const {
565   CXFA_Node* pValue = CreateCopyNode(XFA_Element::Value, pParent);
566   CreateCopyNode(eValue, pValue);
567   return pValue;
568 }
569 
GetObjFactory() const570 CXFA_Document* CXFA_FFWidgetHandler::GetObjFactory() const {
571   return GetXFADoc();
572 }
573 
GetXFADoc() const574 CXFA_Document* CXFA_FFWidgetHandler::GetXFADoc() const {
575   return m_pDocView->GetDoc()->GetXFADoc();
576 }
577