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/src/foxitlib.h"
      8 #include "xfa/src/fxfa/src/common/xfa_common.h"
      9 #include "xfa_fwladapter.h"
     10 #include "xfa_ffwidgethandler.h"
     11 #include "xfa_ffwidget.h"
     12 #include "xfa_fffield.h"
     13 #include "xfa_ffchoicelist.h"
     14 #include "xfa_ffdoc.h"
     15 #include "xfa_ffdocview.h"
     16 CXFA_FFWidgetHandler::CXFA_FFWidgetHandler(CXFA_FFDocView* pDocView)
     17     : m_pDocView(pDocView) {}
     18 CXFA_FFWidgetHandler::~CXFA_FFWidgetHandler() {}
     19 IXFA_PageView* CXFA_FFWidgetHandler::GetPageView(IXFA_Widget* hWidget) {
     20   return static_cast<CXFA_FFWidget*>(hWidget)->GetPageView();
     21 }
     22 void CXFA_FFWidgetHandler::GetRect(IXFA_Widget* hWidget, CFX_RectF& rt) {
     23   static_cast<CXFA_FFWidget*>(hWidget)->GetWidgetRect(rt);
     24 }
     25 FX_DWORD CXFA_FFWidgetHandler::GetStatus(IXFA_Widget* hWidget) {
     26   return static_cast<CXFA_FFWidget*>(hWidget)->GetStatus();
     27 }
     28 FX_BOOL CXFA_FFWidgetHandler::GetBBox(IXFA_Widget* hWidget,
     29                                       CFX_RectF& rtBox,
     30                                       FX_DWORD dwStatus,
     31                                       FX_BOOL bDrawFocus) {
     32   return static_cast<CXFA_FFWidget*>(hWidget)
     33       ->GetBBox(rtBox, dwStatus, bDrawFocus);
     34 }
     35 CXFA_WidgetAcc* CXFA_FFWidgetHandler::GetDataAcc(IXFA_Widget* hWidget) {
     36   return static_cast<CXFA_FFWidget*>(hWidget)->GetDataAcc();
     37 }
     38 void CXFA_FFWidgetHandler::GetName(IXFA_Widget* hWidget,
     39                                    CFX_WideString& wsName,
     40                                    int32_t iNameType) {
     41   static_cast<CXFA_FFWidget*>(hWidget)->GetDataAcc()->GetName(wsName,
     42                                                               iNameType);
     43 }
     44 FX_BOOL CXFA_FFWidgetHandler::GetToolTip(IXFA_Widget* hWidget,
     45                                          CFX_WideString& wsToolTip) {
     46   return static_cast<CXFA_FFWidget*>(hWidget)->GetToolTip(wsToolTip);
     47 }
     48 void CXFA_FFWidgetHandler::SetPrivateData(IXFA_Widget* hWidget,
     49                                           void* module_id,
     50                                           void* pData,
     51                                           PD_CALLBACK_FREEDATA callback) {
     52   static_cast<CXFA_FFWidget*>(hWidget)
     53       ->SetPrivateData(module_id, pData, callback);
     54 }
     55 void* CXFA_FFWidgetHandler::GetPrivateData(IXFA_Widget* hWidget,
     56                                            void* module_id) {
     57   return static_cast<CXFA_FFWidget*>(hWidget)->GetPrivateData(module_id);
     58 }
     59 FX_BOOL CXFA_FFWidgetHandler::OnMouseEnter(IXFA_Widget* hWidget) {
     60   m_pDocView->LockUpdate();
     61   FX_BOOL bRet = static_cast<CXFA_FFWidget*>(hWidget)->OnMouseEnter();
     62   m_pDocView->UnlockUpdate();
     63   m_pDocView->UpdateDocView();
     64   return bRet;
     65 }
     66 FX_BOOL CXFA_FFWidgetHandler::OnMouseExit(IXFA_Widget* hWidget) {
     67   m_pDocView->LockUpdate();
     68   FX_BOOL bRet = static_cast<CXFA_FFWidget*>(hWidget)->OnMouseExit();
     69   m_pDocView->UnlockUpdate();
     70   m_pDocView->UpdateDocView();
     71   return bRet;
     72 }
     73 FX_BOOL CXFA_FFWidgetHandler::OnLButtonDown(IXFA_Widget* hWidget,
     74                                             FX_DWORD dwFlags,
     75                                             FX_FLOAT fx,
     76                                             FX_FLOAT fy) {
     77   m_pDocView->LockUpdate();
     78   static_cast<CXFA_FFWidget*>(hWidget)->Rotate2Normal(fx, fy);
     79   FX_BOOL bRet =
     80       static_cast<CXFA_FFWidget*>(hWidget)->OnLButtonDown(dwFlags, fx, fy);
     81   if (bRet && m_pDocView->SetFocus(hWidget)) {
     82     ((CXFA_FFDoc*)m_pDocView->GetDoc())
     83         ->GetDocProvider()
     84         ->SetFocusWidget(m_pDocView->GetDoc(), (IXFA_Widget*)hWidget);
     85   }
     86   m_pDocView->UnlockUpdate();
     87   m_pDocView->UpdateDocView();
     88   return bRet;
     89 }
     90 FX_BOOL CXFA_FFWidgetHandler::OnLButtonUp(IXFA_Widget* hWidget,
     91                                           FX_DWORD dwFlags,
     92                                           FX_FLOAT fx,
     93                                           FX_FLOAT fy) {
     94   m_pDocView->LockUpdate();
     95   static_cast<CXFA_FFWidget*>(hWidget)->Rotate2Normal(fx, fy);
     96   m_pDocView->m_bLayoutEvent = TRUE;
     97   FX_BOOL bRet =
     98       static_cast<CXFA_FFWidget*>(hWidget)->OnLButtonUp(dwFlags, fx, fy);
     99   m_pDocView->UnlockUpdate();
    100   m_pDocView->UpdateDocView();
    101   return bRet;
    102 }
    103 FX_BOOL CXFA_FFWidgetHandler::OnLButtonDblClk(IXFA_Widget* hWidget,
    104                                               FX_DWORD dwFlags,
    105                                               FX_FLOAT fx,
    106                                               FX_FLOAT fy) {
    107   static_cast<CXFA_FFWidget*>(hWidget)->Rotate2Normal(fx, fy);
    108   FX_BOOL bRet =
    109       static_cast<CXFA_FFWidget*>(hWidget)->OnLButtonDblClk(dwFlags, fx, fy);
    110   m_pDocView->RunInvalidate();
    111   return bRet;
    112 }
    113 FX_BOOL CXFA_FFWidgetHandler::OnMouseMove(IXFA_Widget* hWidget,
    114                                           FX_DWORD dwFlags,
    115                                           FX_FLOAT fx,
    116                                           FX_FLOAT fy) {
    117   static_cast<CXFA_FFWidget*>(hWidget)->Rotate2Normal(fx, fy);
    118   FX_BOOL bRet =
    119       static_cast<CXFA_FFWidget*>(hWidget)->OnMouseMove(dwFlags, fx, fy);
    120   m_pDocView->RunInvalidate();
    121   return bRet;
    122 }
    123 FX_BOOL CXFA_FFWidgetHandler::OnMouseWheel(IXFA_Widget* hWidget,
    124                                            FX_DWORD dwFlags,
    125                                            int16_t zDelta,
    126                                            FX_FLOAT fx,
    127                                            FX_FLOAT fy) {
    128   static_cast<CXFA_FFWidget*>(hWidget)->Rotate2Normal(fx, fy);
    129   FX_BOOL bRet = static_cast<CXFA_FFWidget*>(hWidget)
    130                      ->OnMouseWheel(dwFlags, zDelta, fx, fy);
    131   m_pDocView->RunInvalidate();
    132   return bRet;
    133 }
    134 FX_BOOL CXFA_FFWidgetHandler::OnRButtonDown(IXFA_Widget* hWidget,
    135                                             FX_DWORD dwFlags,
    136                                             FX_FLOAT fx,
    137                                             FX_FLOAT fy) {
    138   static_cast<CXFA_FFWidget*>(hWidget)->Rotate2Normal(fx, fy);
    139   FX_BOOL bRet =
    140       static_cast<CXFA_FFWidget*>(hWidget)->OnRButtonDown(dwFlags, fx, fy);
    141   if (bRet && m_pDocView->SetFocus(hWidget)) {
    142     ((CXFA_FFDoc*)m_pDocView->GetDoc())
    143         ->GetDocProvider()
    144         ->SetFocusWidget(m_pDocView->GetDoc(), (IXFA_Widget*)hWidget);
    145   }
    146   m_pDocView->RunInvalidate();
    147   return bRet;
    148 }
    149 FX_BOOL CXFA_FFWidgetHandler::OnRButtonUp(IXFA_Widget* hWidget,
    150                                           FX_DWORD dwFlags,
    151                                           FX_FLOAT fx,
    152                                           FX_FLOAT fy) {
    153   static_cast<CXFA_FFWidget*>(hWidget)->Rotate2Normal(fx, fy);
    154   FX_BOOL bRet =
    155       static_cast<CXFA_FFWidget*>(hWidget)->OnRButtonUp(dwFlags, fx, fy);
    156   m_pDocView->RunInvalidate();
    157   return bRet;
    158 }
    159 FX_BOOL CXFA_FFWidgetHandler::OnRButtonDblClk(IXFA_Widget* hWidget,
    160                                               FX_DWORD dwFlags,
    161                                               FX_FLOAT fx,
    162                                               FX_FLOAT fy) {
    163   static_cast<CXFA_FFWidget*>(hWidget)->Rotate2Normal(fx, fy);
    164   FX_BOOL bRet =
    165       static_cast<CXFA_FFWidget*>(hWidget)->OnRButtonDblClk(dwFlags, fx, fy);
    166   m_pDocView->RunInvalidate();
    167   return bRet;
    168 }
    169 FX_BOOL CXFA_FFWidgetHandler::OnKeyDown(IXFA_Widget* hWidget,
    170                                         FX_DWORD dwKeyCode,
    171                                         FX_DWORD dwFlags) {
    172   FX_BOOL bRet =
    173       static_cast<CXFA_FFWidget*>(hWidget)->OnKeyDown(dwKeyCode, dwFlags);
    174   m_pDocView->RunInvalidate();
    175   m_pDocView->UpdateDocView();
    176   return bRet;
    177 }
    178 FX_BOOL CXFA_FFWidgetHandler::OnKeyUp(IXFA_Widget* hWidget,
    179                                       FX_DWORD dwKeyCode,
    180                                       FX_DWORD dwFlags) {
    181   FX_BOOL bRet =
    182       static_cast<CXFA_FFWidget*>(hWidget)->OnKeyUp(dwKeyCode, dwFlags);
    183   m_pDocView->RunInvalidate();
    184   return bRet;
    185 }
    186 FX_BOOL CXFA_FFWidgetHandler::OnChar(IXFA_Widget* hWidget,
    187                                      FX_DWORD dwChar,
    188                                      FX_DWORD dwFlags) {
    189   FX_BOOL bRet = static_cast<CXFA_FFWidget*>(hWidget)->OnChar(dwChar, dwFlags);
    190   m_pDocView->RunInvalidate();
    191   return bRet;
    192 }
    193 FX_DWORD CXFA_FFWidgetHandler::OnHitTest(IXFA_Widget* hWidget,
    194                                          FX_FLOAT fx,
    195                                          FX_FLOAT fy) {
    196   if (!(static_cast<CXFA_FFWidget*>(hWidget)->GetStatus() &
    197         XFA_WIDGETSTATUS_Visible)) {
    198     return FWL_WGTHITTEST_Unknown;
    199   }
    200   static_cast<CXFA_FFWidget*>(hWidget)->Rotate2Normal(fx, fy);
    201   return static_cast<CXFA_FFWidget*>(hWidget)->OnHitTest(fx, fy);
    202 }
    203 FX_BOOL CXFA_FFWidgetHandler::OnSetCursor(IXFA_Widget* hWidget,
    204                                           FX_FLOAT fx,
    205                                           FX_FLOAT fy) {
    206   static_cast<CXFA_FFWidget*>(hWidget)->Rotate2Normal(fx, fy);
    207   return static_cast<CXFA_FFWidget*>(hWidget)->OnSetCursor(fx, fy);
    208 }
    209 void CXFA_FFWidgetHandler::RenderWidget(IXFA_Widget* hWidget,
    210                                         CFX_Graphics* pGS,
    211                                         CFX_Matrix* pMatrix,
    212                                         FX_BOOL bHighlight) {
    213   static_cast<CXFA_FFWidget*>(hWidget)->RenderWidget(
    214       pGS, pMatrix, bHighlight ? XFA_WIDGETSTATUS_Highlight : 0, 0);
    215 }
    216 FX_BOOL CXFA_FFWidgetHandler::HasEvent(CXFA_WidgetAcc* pWidgetAcc,
    217                                        XFA_EVENTTYPE eEventType) {
    218   if (!pWidgetAcc || eEventType == XFA_EVENT_Unknown) {
    219     return FALSE;
    220   }
    221   if (pWidgetAcc->GetClassID() == XFA_ELEMENT_Draw) {
    222     return FALSE;
    223   }
    224   switch (eEventType) {
    225     case XFA_EVENT_Calculate: {
    226       CXFA_Calculate calc = pWidgetAcc->GetCalculate();
    227       if (!calc) {
    228         return FALSE;
    229       }
    230       if (calc.GetScript()) {
    231         return TRUE;
    232       }
    233       return FALSE;
    234     }
    235     case XFA_EVENT_Validate: {
    236       CXFA_Validate val = pWidgetAcc->GetValidate();
    237       if (!val) {
    238         return FALSE;
    239       }
    240       if (val.GetScript()) {
    241         return TRUE;
    242       }
    243       return FALSE;
    244     }
    245     default:
    246       break;
    247   }
    248   CXFA_NodeArray eventArray;
    249   return pWidgetAcc->GetEventByActivity(gs_EventActivity[eEventType],
    250                                         eventArray);
    251 }
    252 int32_t CXFA_FFWidgetHandler::ProcessEvent(CXFA_WidgetAcc* pWidgetAcc,
    253                                            CXFA_EventParam* pParam) {
    254   if (!pParam || pParam->m_eType == XFA_EVENT_Unknown) {
    255     return XFA_EVENTERROR_NotExist;
    256   }
    257   if (!pWidgetAcc || pWidgetAcc->GetClassID() == XFA_ELEMENT_Draw) {
    258     return XFA_EVENTERROR_NotExist;
    259   }
    260   switch (pParam->m_eType) {
    261     case XFA_EVENT_Calculate:
    262       return pWidgetAcc->ProcessCalculate();
    263     case XFA_EVENT_Validate:
    264       if (((CXFA_FFDoc*)m_pDocView->GetDoc())
    265               ->GetDocProvider()
    266               ->IsValidationsEnabled(m_pDocView->GetDoc())) {
    267         return pWidgetAcc->ProcessValidate();
    268       }
    269       return XFA_EVENTERROR_Disabled;
    270     case XFA_EVENT_InitCalculate: {
    271       CXFA_Calculate calc = pWidgetAcc->GetCalculate();
    272       if (!calc) {
    273         return XFA_EVENTERROR_NotExist;
    274       }
    275       if (pWidgetAcc->GetNode()->HasFlag(XFA_NODEFLAG_UserInteractive)) {
    276         return XFA_EVENTERROR_Disabled;
    277       }
    278       CXFA_Script script = calc.GetScript();
    279       return pWidgetAcc->ExecuteScript(script, pParam);
    280     }
    281     default:
    282       break;
    283   }
    284   int32_t iRet =
    285       pWidgetAcc->ProcessEvent(gs_EventActivity[pParam->m_eType], pParam);
    286   return iRet;
    287 }
    288 IXFA_Widget* CXFA_FFWidgetHandler::CreateWidget(IXFA_Widget* hParent,
    289                                                 XFA_WIDGETTYPE eType,
    290                                                 IXFA_Widget* hBefore) {
    291   CXFA_Node* pParentFormItem =
    292       hParent ? static_cast<CXFA_FFWidget*>(hParent)->GetDataAcc()->GetNode()
    293               : NULL;
    294   CXFA_Node* pBeforeFormItem =
    295       hBefore ? static_cast<CXFA_FFWidget*>(hBefore)->GetDataAcc()->GetNode()
    296               : NULL;
    297   CXFA_Node* pNewFormItem =
    298       CreateWidgetFormItem(eType, pParentFormItem, pBeforeFormItem);
    299   if (pNewFormItem == NULL) {
    300     return NULL;
    301   }
    302   pNewFormItem->GetTemplateNode()->SetFlag(XFA_NODEFLAG_Initialized);
    303   pNewFormItem->SetFlag(XFA_NODEFLAG_Initialized);
    304   m_pDocView->RunLayout();
    305   CXFA_LayoutItem* pLayout =
    306       m_pDocView->GetXFALayout()->GetLayoutItem(pNewFormItem);
    307   return (IXFA_Widget*)pLayout;
    308 }
    309 CXFA_Node* CXFA_FFWidgetHandler::CreateWidgetFormItem(
    310     XFA_WIDGETTYPE eType,
    311     CXFA_Node* pParent,
    312     CXFA_Node* pBefore) const {
    313   switch (eType) {
    314     case XFA_WIDGETTYPE_Barcode:
    315       return NULL;
    316     case XFA_WIDGETTYPE_PushButton:
    317       return CreatePushButton(pParent, pBefore);
    318     case XFA_WIDGETTYPE_CheckButton:
    319       return CreateCheckButton(pParent, pBefore);
    320     case XFA_WIDGETTYPE_ExcludeGroup:
    321       return CreateExclGroup(pParent, pBefore);
    322     case XFA_WIDGETTYPE_RadioButton:
    323       return CreateRadioButton(pParent, pBefore);
    324     case XFA_WIDGETTYPE_Arc:
    325       return CreateArc(pParent, pBefore);
    326     case XFA_WIDGETTYPE_Rectangle:
    327       return CreateRectangle(pParent, pBefore);
    328     case XFA_WIDGETTYPE_Image:
    329       return CreateImage(pParent, pBefore);
    330     case XFA_WIDGETTYPE_Line:
    331       return CreateLine(pParent, pBefore);
    332     case XFA_WIDGETTYPE_Text:
    333       return CreateText(pParent, pBefore);
    334     case XFA_WIDGETTYPE_DatetimeEdit:
    335       return CreateDatetimeEdit(pParent, pBefore);
    336     case XFA_WIDGETTYPE_DecimalField:
    337       return CreateDecimalField(pParent, pBefore);
    338     case XFA_WIDGETTYPE_NumericField:
    339       return CreateNumericField(pParent, pBefore);
    340     case XFA_WIDGETTYPE_Signature:
    341       return CreateSignature(pParent, pBefore);
    342     case XFA_WIDGETTYPE_TextEdit:
    343       return CreateTextEdit(pParent, pBefore);
    344     case XFA_WIDGETTYPE_DropdownList:
    345       return CreateDropdownList(pParent, pBefore);
    346     case XFA_WIDGETTYPE_ListBox:
    347       return CreateListBox(pParent, pBefore);
    348     case XFA_WIDGETTYPE_ImageField:
    349       return CreateImageField(pParent, pBefore);
    350     case XFA_WIDGETTYPE_PasswordEdit:
    351       return CreatePasswordEdit(pParent, pBefore);
    352     case XFA_WIDGETTYPE_Subform:
    353       return CreateSubform(pParent, pBefore);
    354     default:
    355       break;
    356   }
    357   return NULL;
    358 }
    359 CXFA_Node* CXFA_FFWidgetHandler::CreatePushButton(CXFA_Node* pParent,
    360                                                   CXFA_Node* pBefore) const {
    361   CXFA_Node* pField = CreateField(XFA_ELEMENT_Button, pParent, pBefore);
    362   CXFA_Node* pCaption = CreateCopyNode(XFA_ELEMENT_Caption, pField);
    363   CXFA_Node* pValue = CreateCopyNode(XFA_ELEMENT_Value, pCaption);
    364   CXFA_Node* pText = CreateCopyNode(XFA_ELEMENT_Text, pValue);
    365   pText->SetContent(FX_WSTRC(L"Button"), FX_WSTRC(L"Button"), FALSE);
    366   CXFA_Node* pPara = CreateCopyNode(XFA_ELEMENT_Para, pCaption);
    367   pPara->SetEnum(XFA_ATTRIBUTE_VAlign, XFA_ATTRIBUTEENUM_Middle, FALSE);
    368   pPara->SetEnum(XFA_ATTRIBUTE_HAlign, XFA_ATTRIBUTEENUM_Center, FALSE);
    369   CreateFontNode(pCaption);
    370   CXFA_Node* pBorder = CreateCopyNode(XFA_ELEMENT_Border, pField);
    371   pBorder->SetEnum(XFA_ATTRIBUTE_Hand, XFA_ATTRIBUTEENUM_Right, FALSE);
    372   CXFA_Node* pEdge = CreateCopyNode(XFA_ELEMENT_Edge, pBorder);
    373   pEdge->SetEnum(XFA_ATTRIBUTE_Stroke, XFA_ATTRIBUTEENUM_Raised, FALSE);
    374   CXFA_Node* pFill = CreateCopyNode(XFA_ELEMENT_Fill, pBorder);
    375   CXFA_Node* pColor = CreateCopyNode(XFA_ELEMENT_Color, pFill);
    376   pColor->SetCData(XFA_ATTRIBUTE_Value, FX_WSTRC(L"212, 208, 200"), FALSE);
    377   CXFA_Node* pBind = CreateCopyNode(XFA_ELEMENT_Bind, pField);
    378   pBind->SetEnum(XFA_ATTRIBUTE_Match, XFA_ATTRIBUTEENUM_None);
    379   return pField;
    380 }
    381 CXFA_Node* CXFA_FFWidgetHandler::CreateCheckButton(CXFA_Node* pParent,
    382                                                    CXFA_Node* pBefore) const {
    383   CXFA_Node* pField = CreateField(XFA_ELEMENT_CheckButton, pParent, pBefore);
    384   return pField;
    385 }
    386 CXFA_Node* CXFA_FFWidgetHandler::CreateExclGroup(CXFA_Node* pParent,
    387                                                  CXFA_Node* pBefore) const {
    388   return CreateFormItem(XFA_ELEMENT_ExclGroup, pParent, pBefore);
    389 }
    390 CXFA_Node* CXFA_FFWidgetHandler::CreateRadioButton(CXFA_Node* pParent,
    391                                                    CXFA_Node* pBefore) const {
    392   CXFA_Node* pField = CreateField(XFA_ELEMENT_CheckButton, pParent, pBefore);
    393   CXFA_Node* pUi = pField->GetFirstChildByClass(XFA_ELEMENT_Ui);
    394   CXFA_Node* pWidget = pUi->GetFirstChildByClass(XFA_ELEMENT_CheckButton);
    395   pWidget->SetEnum(XFA_ATTRIBUTE_Shape, XFA_ATTRIBUTEENUM_Round);
    396   return pField;
    397 }
    398 CXFA_Node* CXFA_FFWidgetHandler::CreateDatetimeEdit(CXFA_Node* pParent,
    399                                                     CXFA_Node* pBefore) const {
    400   CXFA_Node* pField = CreateField(XFA_ELEMENT_DateTimeEdit, pParent, pBefore);
    401   CreateValueNode(XFA_ELEMENT_Date, pField);
    402   return pField;
    403 }
    404 CXFA_Node* CXFA_FFWidgetHandler::CreateDecimalField(CXFA_Node* pParent,
    405                                                     CXFA_Node* pBefore) const {
    406   CXFA_Node* pField = CreateNumericField(pParent, pBefore);
    407   CreateValueNode(XFA_ELEMENT_Decimal, pField);
    408   return pField;
    409 }
    410 CXFA_Node* CXFA_FFWidgetHandler::CreateNumericField(CXFA_Node* pParent,
    411                                                     CXFA_Node* pBefore) const {
    412   CXFA_Node* pField = CreateField(XFA_ELEMENT_NumericEdit, pParent, pBefore);
    413   return pField;
    414 }
    415 CXFA_Node* CXFA_FFWidgetHandler::CreateSignature(CXFA_Node* pParent,
    416                                                  CXFA_Node* pBefore) const {
    417   CXFA_Node* pField = CreateField(XFA_ELEMENT_Signature, pParent, pBefore);
    418   return pField;
    419 }
    420 CXFA_Node* CXFA_FFWidgetHandler::CreateTextEdit(CXFA_Node* pParent,
    421                                                 CXFA_Node* pBefore) const {
    422   CXFA_Node* pField = CreateField(XFA_ELEMENT_TextEdit, pParent, pBefore);
    423   return pField;
    424 }
    425 CXFA_Node* CXFA_FFWidgetHandler::CreateDropdownList(CXFA_Node* pParent,
    426                                                     CXFA_Node* pBefore) const {
    427   CXFA_Node* pField = CreateField(XFA_ELEMENT_ChoiceList, pParent, pBefore);
    428   return pField;
    429 }
    430 CXFA_Node* CXFA_FFWidgetHandler::CreateListBox(CXFA_Node* pParent,
    431                                                CXFA_Node* pBefore) const {
    432   CXFA_Node* pField = CreateDropdownList(pParent, pBefore);
    433   CXFA_Node* pUi = pField->GetNodeItem(XFA_NODEITEM_FirstChild);
    434   CXFA_Node* pListBox = pUi->GetNodeItem(XFA_NODEITEM_FirstChild);
    435   pListBox->SetEnum(XFA_ATTRIBUTE_Open, XFA_ATTRIBUTEENUM_Always);
    436   pListBox->SetEnum(XFA_ATTRIBUTE_CommitOn, XFA_ATTRIBUTEENUM_Exit);
    437   return pField;
    438 }
    439 CXFA_Node* CXFA_FFWidgetHandler::CreateImageField(CXFA_Node* pParent,
    440                                                   CXFA_Node* pBefore) const {
    441   CXFA_Node* pField = CreateField(XFA_ELEMENT_ImageEdit, pParent, pBefore);
    442   return pField;
    443 }
    444 CXFA_Node* CXFA_FFWidgetHandler::CreatePasswordEdit(CXFA_Node* pParent,
    445                                                     CXFA_Node* pBefore) const {
    446   CXFA_Node* pField = CreateField(XFA_ELEMENT_PasswordEdit, pParent, pBefore);
    447   CXFA_Node* pBind = CreateCopyNode(XFA_ELEMENT_Bind, pField);
    448   pBind->SetEnum(XFA_ATTRIBUTE_Match, XFA_ATTRIBUTEENUM_None, FALSE);
    449   return pField;
    450 }
    451 CXFA_Node* CXFA_FFWidgetHandler::CreateField(XFA_ELEMENT eElement,
    452                                              CXFA_Node* pParent,
    453                                              CXFA_Node* pBefore) const {
    454   CXFA_Node* pField = CreateFormItem(XFA_ELEMENT_Field, pParent, pBefore);
    455   CreateCopyNode(eElement, CreateCopyNode(XFA_ELEMENT_Ui, pField));
    456   CreateFontNode(pField);
    457   return pField;
    458 }
    459 CXFA_Node* CXFA_FFWidgetHandler::CreateArc(CXFA_Node* pParent,
    460                                            CXFA_Node* pBefore) const {
    461   return CreateDraw(XFA_ELEMENT_Arc, pParent, pBefore);
    462 }
    463 CXFA_Node* CXFA_FFWidgetHandler::CreateRectangle(CXFA_Node* pParent,
    464                                                  CXFA_Node* pBefore) const {
    465   return CreateDraw(XFA_ELEMENT_Rectangle, pParent, pBefore);
    466 }
    467 CXFA_Node* CXFA_FFWidgetHandler::CreateImage(CXFA_Node* pParent,
    468                                              CXFA_Node* pBefore) const {
    469   CXFA_Node* pField = CreateDraw(XFA_ELEMENT_Image, pParent, pBefore);
    470   CreateCopyNode(XFA_ELEMENT_ImageEdit, CreateCopyNode(XFA_ELEMENT_Ui, pField));
    471   return pField;
    472 }
    473 CXFA_Node* CXFA_FFWidgetHandler::CreateLine(CXFA_Node* pParent,
    474                                             CXFA_Node* pBefore) const {
    475   CXFA_Node* pField = CreateDraw(XFA_ELEMENT_Line, pParent, pBefore);
    476   return pField;
    477 }
    478 CXFA_Node* CXFA_FFWidgetHandler::CreateText(CXFA_Node* pParent,
    479                                             CXFA_Node* pBefore) const {
    480   CXFA_Node* pField = CreateDraw(XFA_ELEMENT_Text, pParent, pBefore);
    481   CreateCopyNode(XFA_ELEMENT_TextEdit, CreateCopyNode(XFA_ELEMENT_Ui, pField));
    482   CreateFontNode(pField);
    483   return pField;
    484 }
    485 CXFA_Node* CXFA_FFWidgetHandler::CreateDraw(XFA_ELEMENT eElement,
    486                                             CXFA_Node* pParent,
    487                                             CXFA_Node* pBefore) const {
    488   CXFA_Node* pDraw = CreateFormItem(XFA_ELEMENT_Draw, pParent, pBefore);
    489   CreateValueNode(eElement, pDraw);
    490   return pDraw;
    491 }
    492 CXFA_Node* CXFA_FFWidgetHandler::CreateSubform(CXFA_Node* pParent,
    493                                                CXFA_Node* pBefore) const {
    494   CXFA_Node* pSubform = CreateFormItem(XFA_ELEMENT_Subform, pParent, pBefore);
    495   return pSubform;
    496 }
    497 CXFA_Node* CXFA_FFWidgetHandler::CreateFormItem(XFA_ELEMENT eElement,
    498                                                 CXFA_Node* pParent,
    499                                                 CXFA_Node* pBefore) const {
    500   CXFA_Node* pTemplateParent =
    501       pParent != NULL ? pParent->GetTemplateNode() : NULL;
    502   CXFA_Node* pNewFormItem = pTemplateParent->CloneTemplateToForm(FALSE);
    503   if (pParent != NULL) {
    504     pParent->InsertChild(pNewFormItem, pBefore);
    505   }
    506   return pNewFormItem;
    507 }
    508 CXFA_Node* CXFA_FFWidgetHandler::CreateCopyNode(XFA_ELEMENT eElement,
    509                                                 CXFA_Node* pParent,
    510                                                 CXFA_Node* pBefore) const {
    511   CXFA_Node* pTemplateParent =
    512       pParent != NULL ? pParent->GetTemplateNode() : NULL;
    513   CXFA_Node* pNewNode =
    514       CreateTemplateNode(eElement, pTemplateParent,
    515                          pBefore ? pBefore->GetTemplateNode() : NULL)
    516           ->Clone(FALSE);
    517   if (pParent != NULL) {
    518     pParent->InsertChild(pNewNode, pBefore);
    519   }
    520   return pNewNode;
    521 }
    522 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 = pXFADoc->GetParser()->GetFactory()->CreateNode(
    527       XFA_XDPPACKET_Template, eElement);
    528   if (pParent != NULL) {
    529     pParent->InsertChild(pNewTemplateNode, pBefore);
    530   }
    531   return pNewTemplateNode;
    532 }
    533 CXFA_Node* CXFA_FFWidgetHandler::CreateFontNode(CXFA_Node* pParent) const {
    534   CXFA_Node* pFont = CreateCopyNode(XFA_ELEMENT_Font, pParent);
    535   pFont->SetCData(XFA_ATTRIBUTE_Typeface, FX_WSTRC(L"Myriad Pro"), FALSE);
    536   return pFont;
    537 }
    538 CXFA_Node* CXFA_FFWidgetHandler::CreateMarginNode(CXFA_Node* pParent,
    539                                                   FX_DWORD dwFlags,
    540                                                   FX_FLOAT fInsets[4]) const {
    541   CXFA_Node* pMargin = CreateCopyNode(XFA_ELEMENT_Margin, pParent);
    542   if (dwFlags & 0x01) {
    543     pMargin->SetMeasure(XFA_ATTRIBUTE_LeftInset,
    544                         CXFA_Measurement(fInsets[0], XFA_UNIT_Pt), FALSE);
    545   }
    546   if (dwFlags & 0x02) {
    547     pMargin->SetMeasure(XFA_ATTRIBUTE_TopInset,
    548                         CXFA_Measurement(fInsets[1], XFA_UNIT_Pt), FALSE);
    549   }
    550   if (dwFlags & 0x04) {
    551     pMargin->SetMeasure(XFA_ATTRIBUTE_RightInset,
    552                         CXFA_Measurement(fInsets[2], XFA_UNIT_Pt), FALSE);
    553   }
    554   if (dwFlags & 0x08) {
    555     pMargin->SetMeasure(XFA_ATTRIBUTE_BottomInset,
    556                         CXFA_Measurement(fInsets[3], XFA_UNIT_Pt), FALSE);
    557   }
    558   return pMargin;
    559 }
    560 CXFA_Node* CXFA_FFWidgetHandler::CreateValueNode(XFA_ELEMENT eValue,
    561                                                  CXFA_Node* pParent) const {
    562   CXFA_Node* pValue = CreateCopyNode(XFA_ELEMENT_Value, pParent);
    563   CreateCopyNode(eValue, pValue);
    564   return pValue;
    565 }
    566 IXFA_ObjFactory* CXFA_FFWidgetHandler::GetObjFactory() const {
    567   return GetXFADoc()->GetParser()->GetFactory();
    568 }
    569 CXFA_Document* CXFA_FFWidgetHandler::GetXFADoc() const {
    570   return ((CXFA_FFDoc*)(m_pDocView->GetDoc()))->GetXFADoc();
    571 }
    572 CXFA_FFMenuHandler::CXFA_FFMenuHandler() {}
    573 CXFA_FFMenuHandler::~CXFA_FFMenuHandler() {}
    574 FX_BOOL CXFA_FFMenuHandler::CanCopy(IXFA_Widget* hWidget) {
    575   return static_cast<CXFA_FFWidget*>(hWidget)->CanCopy();
    576 }
    577 FX_BOOL CXFA_FFMenuHandler::CanCut(IXFA_Widget* hWidget) {
    578   return static_cast<CXFA_FFWidget*>(hWidget)->CanCut();
    579 }
    580 FX_BOOL CXFA_FFMenuHandler::CanPaste(IXFA_Widget* hWidget) {
    581   return static_cast<CXFA_FFWidget*>(hWidget)->CanPaste();
    582 }
    583 FX_BOOL CXFA_FFMenuHandler::CanSelectAll(IXFA_Widget* hWidget) {
    584   return static_cast<CXFA_FFWidget*>(hWidget)->CanSelectAll();
    585 }
    586 FX_BOOL CXFA_FFMenuHandler::CanDelete(IXFA_Widget* hWidget) {
    587   return static_cast<CXFA_FFWidget*>(hWidget)->CanDelete();
    588 }
    589 FX_BOOL CXFA_FFMenuHandler::CanDeSelect(IXFA_Widget* hWidget) {
    590   return static_cast<CXFA_FFWidget*>(hWidget)->CanDeSelect();
    591 }
    592 FX_BOOL CXFA_FFMenuHandler::Copy(IXFA_Widget* hWidget, CFX_WideString& wsText) {
    593   return static_cast<CXFA_FFWidget*>(hWidget)->Copy(wsText);
    594 }
    595 FX_BOOL CXFA_FFMenuHandler::Cut(IXFA_Widget* hWidget, CFX_WideString& wsText) {
    596   return static_cast<CXFA_FFWidget*>(hWidget)->Cut(wsText);
    597 }
    598 FX_BOOL CXFA_FFMenuHandler::Paste(IXFA_Widget* hWidget,
    599                                   const CFX_WideString& wsText) {
    600   return static_cast<CXFA_FFWidget*>(hWidget)->Paste(wsText);
    601 }
    602 FX_BOOL CXFA_FFMenuHandler::SelectAll(IXFA_Widget* hWidget) {
    603   return static_cast<CXFA_FFWidget*>(hWidget)->SelectAll();
    604 }
    605 FX_BOOL CXFA_FFMenuHandler::Delete(IXFA_Widget* hWidget) {
    606   return static_cast<CXFA_FFWidget*>(hWidget)->Delete();
    607 }
    608 FX_BOOL CXFA_FFMenuHandler::DeSelect(IXFA_Widget* hWidget) {
    609   return static_cast<CXFA_FFWidget*>(hWidget)->DeSelect();
    610 }
    611 FX_BOOL CXFA_FFMenuHandler::CanUndo(IXFA_Widget* hWidget) {
    612   return static_cast<CXFA_FFWidget*>(hWidget)->CanUndo();
    613 }
    614 FX_BOOL CXFA_FFMenuHandler::CanRedo(IXFA_Widget* hWidget) {
    615   return static_cast<CXFA_FFWidget*>(hWidget)->CanRedo();
    616 }
    617 FX_BOOL CXFA_FFMenuHandler::Undo(IXFA_Widget* hWidget) {
    618   return static_cast<CXFA_FFWidget*>(hWidget)->Undo();
    619 }
    620 FX_BOOL CXFA_FFMenuHandler::Redo(IXFA_Widget* hWidget) {
    621   return static_cast<CXFA_FFWidget*>(hWidget)->Redo();
    622 }
    623 #define FX_EDIT_ISLATINWORD(u)                                     \
    624   (u == 0x2D || (u <= 0x005A && u >= 0x0041) ||                    \
    625    (u <= 0x007A && u >= 0x0061) || (u <= 0x02AF && u >= 0x00C0) || \
    626    u == 0x0027)
    627 FX_BOOL CXFA_FFMenuHandler::GetSuggestWords(IXFA_Widget* hWidget,
    628                                             CFX_PointF pointf,
    629                                             CFX_ByteStringArray& sSuggest) {
    630   return static_cast<CXFA_FFWidget*>(hWidget)
    631       ->GetSuggestWords(pointf, sSuggest);
    632 }
    633 FX_BOOL CXFA_FFMenuHandler::ReplaceSpellCheckWord(
    634     IXFA_Widget* hWidget,
    635     CFX_PointF pointf,
    636     const CFX_ByteStringC& bsReplace) {
    637   return static_cast<CXFA_FFWidget*>(hWidget)
    638       ->ReplaceSpellCheckWord(pointf, bsReplace);
    639 }
    640