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"
16CXFA_FFWidgetHandler::CXFA_FFWidgetHandler(CXFA_FFDocView* pDocView)
17    : m_pDocView(pDocView) {}
18CXFA_FFWidgetHandler::~CXFA_FFWidgetHandler() {}
19IXFA_PageView* CXFA_FFWidgetHandler::GetPageView(IXFA_Widget* hWidget) {
20  return static_cast<CXFA_FFWidget*>(hWidget)->GetPageView();
21}
22void CXFA_FFWidgetHandler::GetRect(IXFA_Widget* hWidget, CFX_RectF& rt) {
23  static_cast<CXFA_FFWidget*>(hWidget)->GetWidgetRect(rt);
24}
25FX_DWORD CXFA_FFWidgetHandler::GetStatus(IXFA_Widget* hWidget) {
26  return static_cast<CXFA_FFWidget*>(hWidget)->GetStatus();
27}
28FX_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}
35CXFA_WidgetAcc* CXFA_FFWidgetHandler::GetDataAcc(IXFA_Widget* hWidget) {
36  return static_cast<CXFA_FFWidget*>(hWidget)->GetDataAcc();
37}
38void 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}
44FX_BOOL CXFA_FFWidgetHandler::GetToolTip(IXFA_Widget* hWidget,
45                                         CFX_WideString& wsToolTip) {
46  return static_cast<CXFA_FFWidget*>(hWidget)->GetToolTip(wsToolTip);
47}
48void 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}
55void* CXFA_FFWidgetHandler::GetPrivateData(IXFA_Widget* hWidget,
56                                           void* module_id) {
57  return static_cast<CXFA_FFWidget*>(hWidget)->GetPrivateData(module_id);
58}
59FX_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}
66FX_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}
73FX_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}
90FX_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}
103FX_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}
113FX_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}
123FX_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}
134FX_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}
149FX_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}
159FX_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}
169FX_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}
178FX_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}
186FX_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}
193FX_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}
203FX_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}
209void 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}
216FX_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}
252int32_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}
288IXFA_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}
309CXFA_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}
359CXFA_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}
381CXFA_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}
386CXFA_Node* CXFA_FFWidgetHandler::CreateExclGroup(CXFA_Node* pParent,
387                                                 CXFA_Node* pBefore) const {
388  return CreateFormItem(XFA_ELEMENT_ExclGroup, pParent, pBefore);
389}
390CXFA_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}
398CXFA_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}
404CXFA_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}
410CXFA_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}
415CXFA_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}
420CXFA_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}
425CXFA_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}
430CXFA_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}
439CXFA_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}
444CXFA_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}
451CXFA_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}
459CXFA_Node* CXFA_FFWidgetHandler::CreateArc(CXFA_Node* pParent,
460                                           CXFA_Node* pBefore) const {
461  return CreateDraw(XFA_ELEMENT_Arc, pParent, pBefore);
462}
463CXFA_Node* CXFA_FFWidgetHandler::CreateRectangle(CXFA_Node* pParent,
464                                                 CXFA_Node* pBefore) const {
465  return CreateDraw(XFA_ELEMENT_Rectangle, pParent, pBefore);
466}
467CXFA_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}
473CXFA_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}
478CXFA_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}
485CXFA_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}
492CXFA_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}
497CXFA_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}
508CXFA_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}
522CXFA_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}
533CXFA_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}
538CXFA_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}
560CXFA_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}
566IXFA_ObjFactory* CXFA_FFWidgetHandler::GetObjFactory() const {
567  return GetXFADoc()->GetParser()->GetFactory();
568}
569CXFA_Document* CXFA_FFWidgetHandler::GetXFADoc() const {
570  return ((CXFA_FFDoc*)(m_pDocView->GetDoc()))->GetXFADoc();
571}
572CXFA_FFMenuHandler::CXFA_FFMenuHandler() {}
573CXFA_FFMenuHandler::~CXFA_FFMenuHandler() {}
574FX_BOOL CXFA_FFMenuHandler::CanCopy(IXFA_Widget* hWidget) {
575  return static_cast<CXFA_FFWidget*>(hWidget)->CanCopy();
576}
577FX_BOOL CXFA_FFMenuHandler::CanCut(IXFA_Widget* hWidget) {
578  return static_cast<CXFA_FFWidget*>(hWidget)->CanCut();
579}
580FX_BOOL CXFA_FFMenuHandler::CanPaste(IXFA_Widget* hWidget) {
581  return static_cast<CXFA_FFWidget*>(hWidget)->CanPaste();
582}
583FX_BOOL CXFA_FFMenuHandler::CanSelectAll(IXFA_Widget* hWidget) {
584  return static_cast<CXFA_FFWidget*>(hWidget)->CanSelectAll();
585}
586FX_BOOL CXFA_FFMenuHandler::CanDelete(IXFA_Widget* hWidget) {
587  return static_cast<CXFA_FFWidget*>(hWidget)->CanDelete();
588}
589FX_BOOL CXFA_FFMenuHandler::CanDeSelect(IXFA_Widget* hWidget) {
590  return static_cast<CXFA_FFWidget*>(hWidget)->CanDeSelect();
591}
592FX_BOOL CXFA_FFMenuHandler::Copy(IXFA_Widget* hWidget, CFX_WideString& wsText) {
593  return static_cast<CXFA_FFWidget*>(hWidget)->Copy(wsText);
594}
595FX_BOOL CXFA_FFMenuHandler::Cut(IXFA_Widget* hWidget, CFX_WideString& wsText) {
596  return static_cast<CXFA_FFWidget*>(hWidget)->Cut(wsText);
597}
598FX_BOOL CXFA_FFMenuHandler::Paste(IXFA_Widget* hWidget,
599                                  const CFX_WideString& wsText) {
600  return static_cast<CXFA_FFWidget*>(hWidget)->Paste(wsText);
601}
602FX_BOOL CXFA_FFMenuHandler::SelectAll(IXFA_Widget* hWidget) {
603  return static_cast<CXFA_FFWidget*>(hWidget)->SelectAll();
604}
605FX_BOOL CXFA_FFMenuHandler::Delete(IXFA_Widget* hWidget) {
606  return static_cast<CXFA_FFWidget*>(hWidget)->Delete();
607}
608FX_BOOL CXFA_FFMenuHandler::DeSelect(IXFA_Widget* hWidget) {
609  return static_cast<CXFA_FFWidget*>(hWidget)->DeSelect();
610}
611FX_BOOL CXFA_FFMenuHandler::CanUndo(IXFA_Widget* hWidget) {
612  return static_cast<CXFA_FFWidget*>(hWidget)->CanUndo();
613}
614FX_BOOL CXFA_FFMenuHandler::CanRedo(IXFA_Widget* hWidget) {
615  return static_cast<CXFA_FFWidget*>(hWidget)->CanRedo();
616}
617FX_BOOL CXFA_FFMenuHandler::Undo(IXFA_Widget* hWidget) {
618  return static_cast<CXFA_FFWidget*>(hWidget)->Undo();
619}
620FX_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)
627FX_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}
633FX_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