Home | History | Annotate | Download | only in app
      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 
     20 CXFA_FFWidgetHandler::CXFA_FFWidgetHandler(CXFA_FFDocView* pDocView)
     21     : m_pDocView(pDocView) {}
     22 
     23 CXFA_FFWidgetHandler::~CXFA_FFWidgetHandler() {}
     24 
     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 
     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 
     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 
     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 
     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 
     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 
     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 
     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 
    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 
    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 
    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 
    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 
    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 
    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 
    152 bool CXFA_FFWidgetHandler::OnSetCursor(CXFA_FFWidget* hWidget,
    153                                        const CFX_PointF& point) {
    154   return hWidget->OnSetCursor(hWidget->Rotate2Normal(point));
    155 }
    156 
    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 
    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 
    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 
    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 
    251 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 
    301 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 
    330 CXFA_Node* CXFA_FFWidgetHandler::CreateCheckButton(CXFA_Node* pParent,
    331                                                    CXFA_Node* pBefore) const {
    332   return CreateField(XFA_Element::CheckButton, pParent, pBefore);
    333 }
    334 
    335 CXFA_Node* CXFA_FFWidgetHandler::CreateExclGroup(CXFA_Node* pParent,
    336                                                  CXFA_Node* pBefore) const {
    337   return CreateFormItem(XFA_Element::ExclGroup, pParent, pBefore);
    338 }
    339 
    340 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 
    349 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 
    356 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 
    363 CXFA_Node* CXFA_FFWidgetHandler::CreateNumericField(CXFA_Node* pParent,
    364                                                     CXFA_Node* pBefore) const {
    365   return CreateField(XFA_Element::NumericEdit, pParent, pBefore);
    366 }
    367 
    368 CXFA_Node* CXFA_FFWidgetHandler::CreateSignature(CXFA_Node* pParent,
    369                                                  CXFA_Node* pBefore) const {
    370   return CreateField(XFA_Element::Signature, pParent, pBefore);
    371 }
    372 
    373 CXFA_Node* CXFA_FFWidgetHandler::CreateTextEdit(CXFA_Node* pParent,
    374                                                 CXFA_Node* pBefore) const {
    375   return CreateField(XFA_Element::TextEdit, pParent, pBefore);
    376 }
    377 
    378 CXFA_Node* CXFA_FFWidgetHandler::CreateDropdownList(CXFA_Node* pParent,
    379                                                     CXFA_Node* pBefore) const {
    380   return CreateField(XFA_Element::ChoiceList, pParent, pBefore);
    381 }
    382 
    383 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 
    393 CXFA_Node* CXFA_FFWidgetHandler::CreateImageField(CXFA_Node* pParent,
    394                                                   CXFA_Node* pBefore) const {
    395   return CreateField(XFA_Element::ImageEdit, pParent, pBefore);
    396 }
    397 
    398 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 
    406 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 
    415 CXFA_Node* CXFA_FFWidgetHandler::CreateArc(CXFA_Node* pParent,
    416                                            CXFA_Node* pBefore) const {
    417   return CreateDraw(XFA_Element::Arc, pParent, pBefore);
    418 }
    419 
    420 CXFA_Node* CXFA_FFWidgetHandler::CreateRectangle(CXFA_Node* pParent,
    421                                                  CXFA_Node* pBefore) const {
    422   return CreateDraw(XFA_Element::Rectangle, pParent, pBefore);
    423 }
    424 
    425 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 
    433 CXFA_Node* CXFA_FFWidgetHandler::CreateLine(CXFA_Node* pParent,
    434                                             CXFA_Node* pBefore) const {
    435   return CreateDraw(XFA_Element::Line, pParent, pBefore);
    436 }
    437 
    438 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 
    447 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 
    455 CXFA_Node* CXFA_FFWidgetHandler::CreateSubform(CXFA_Node* pParent,
    456                                                CXFA_Node* pBefore) const {
    457   return CreateFormItem(XFA_Element::Subform, pParent, pBefore);
    458 }
    459 
    460 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 
    470 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 
    483 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 
    494 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 
    500 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 
    519 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 
    526 CXFA_Document* CXFA_FFWidgetHandler::GetObjFactory() const {
    527   return GetXFADoc();
    528 }
    529 
    530 CXFA_Document* CXFA_FFWidgetHandler::GetXFADoc() const {
    531   return m_pDocView->GetDoc()->GetXFADoc();
    532 }
    533 
    534