• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2014 The PDFium Authors
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 "fxjs/xfa/cjx_object.h"
10 #include "xfa/fxfa/cxfa_ffdoc.h"
11 #include "xfa/fxfa/cxfa_ffdocview.h"
12 #include "xfa/fxfa/cxfa_fffield.h"
13 #include "xfa/fxfa/cxfa_ffwidget.h"
14 #include "xfa/fxfa/cxfa_fwladapterwidgetmgr.h"
15 #include "xfa/fxfa/layout/cxfa_layoutprocessor.h"
16 #include "xfa/fxfa/parser/cxfa_calculate.h"
17 #include "xfa/fxfa/parser/cxfa_checkbutton.h"
18 #include "xfa/fxfa/parser/cxfa_measurement.h"
19 #include "xfa/fxfa/parser/cxfa_node.h"
20 #include "xfa/fxfa/parser/cxfa_ui.h"
21 #include "xfa/fxfa/parser/cxfa_validate.h"
22 
CXFA_FFWidgetHandler(CXFA_FFDocView * pDocView)23 CXFA_FFWidgetHandler::CXFA_FFWidgetHandler(CXFA_FFDocView* pDocView)
24     : m_pDocView(pDocView) {}
25 
26 CXFA_FFWidgetHandler::~CXFA_FFWidgetHandler() = default;
27 
Trace(cppgc::Visitor * visitor) const28 void CXFA_FFWidgetHandler::Trace(cppgc::Visitor* visitor) const {
29   visitor->Trace(m_pDocView);
30 }
31 
OnMouseEnter(CXFA_FFWidget * hWidget)32 bool CXFA_FFWidgetHandler::OnMouseEnter(CXFA_FFWidget* hWidget) {
33   CXFA_FFDocView::UpdateScope scope(m_pDocView);
34   return hWidget->OnMouseEnter();
35 }
36 
OnMouseExit(CXFA_FFWidget * hWidget)37 bool CXFA_FFWidgetHandler::OnMouseExit(CXFA_FFWidget* hWidget) {
38   CXFA_FFDocView::UpdateScope scope(m_pDocView);
39   return hWidget->OnMouseExit();
40 }
41 
OnLButtonDown(CXFA_FFWidget * hWidget,Mask<XFA_FWL_KeyFlag> dwFlags,const CFX_PointF & point)42 bool CXFA_FFWidgetHandler::OnLButtonDown(CXFA_FFWidget* hWidget,
43                                          Mask<XFA_FWL_KeyFlag> dwFlags,
44                                          const CFX_PointF& point) {
45   CXFA_FFDocView::UpdateScope scope(m_pDocView);
46   if (!hWidget->AcceptsFocusOnButtonDown(
47           dwFlags, hWidget->Rotate2Normal(point),
48           CFWL_MessageMouse::MouseCommand::kLeftButtonDown)) {
49     return false;
50   }
51   // May re-enter JS.
52   if (m_pDocView->SetFocus(hWidget))
53     m_pDocView->GetDoc()->SetFocusWidget(hWidget);
54 
55   return hWidget->OnLButtonDown(dwFlags, hWidget->Rotate2Normal(point));
56 }
57 
OnLButtonUp(CXFA_FFWidget * hWidget,Mask<XFA_FWL_KeyFlag> dwFlags,const CFX_PointF & point)58 bool CXFA_FFWidgetHandler::OnLButtonUp(CXFA_FFWidget* hWidget,
59                                        Mask<XFA_FWL_KeyFlag> dwFlags,
60                                        const CFX_PointF& point) {
61   CXFA_FFDocView::UpdateScope scope(m_pDocView);
62   m_pDocView->SetLayoutEvent();
63   return hWidget->OnLButtonUp(dwFlags, hWidget->Rotate2Normal(point));
64 }
65 
OnLButtonDblClk(CXFA_FFWidget * hWidget,Mask<XFA_FWL_KeyFlag> dwFlags,const CFX_PointF & point)66 bool CXFA_FFWidgetHandler::OnLButtonDblClk(CXFA_FFWidget* hWidget,
67                                            Mask<XFA_FWL_KeyFlag> dwFlags,
68                                            const CFX_PointF& point) {
69   return hWidget->OnLButtonDblClk(dwFlags, hWidget->Rotate2Normal(point));
70 }
71 
OnMouseMove(CXFA_FFWidget * hWidget,Mask<XFA_FWL_KeyFlag> dwFlags,const CFX_PointF & point)72 bool CXFA_FFWidgetHandler::OnMouseMove(CXFA_FFWidget* hWidget,
73                                        Mask<XFA_FWL_KeyFlag> dwFlags,
74                                        const CFX_PointF& point) {
75   return hWidget->OnMouseMove(dwFlags, hWidget->Rotate2Normal(point));
76 }
77 
OnMouseWheel(CXFA_FFWidget * hWidget,Mask<XFA_FWL_KeyFlag> dwFlags,const CFX_PointF & point,const CFX_Vector & delta)78 bool CXFA_FFWidgetHandler::OnMouseWheel(CXFA_FFWidget* hWidget,
79                                         Mask<XFA_FWL_KeyFlag> dwFlags,
80                                         const CFX_PointF& point,
81                                         const CFX_Vector& delta) {
82   return hWidget->OnMouseWheel(dwFlags, hWidget->Rotate2Normal(point), delta);
83 }
84 
OnRButtonDown(CXFA_FFWidget * hWidget,Mask<XFA_FWL_KeyFlag> dwFlags,const CFX_PointF & point)85 bool CXFA_FFWidgetHandler::OnRButtonDown(CXFA_FFWidget* hWidget,
86                                          Mask<XFA_FWL_KeyFlag> dwFlags,
87                                          const CFX_PointF& point) {
88   if (!hWidget->AcceptsFocusOnButtonDown(
89           dwFlags, hWidget->Rotate2Normal(point),
90           CFWL_MessageMouse::MouseCommand::kRightButtonDown)) {
91     return false;
92   }
93   // May re-enter JS.
94   if (m_pDocView->SetFocus(hWidget)) {
95     m_pDocView->GetDoc()->SetFocusWidget(hWidget);
96   }
97   return hWidget->OnRButtonDown(dwFlags, hWidget->Rotate2Normal(point));
98 }
99 
OnRButtonUp(CXFA_FFWidget * hWidget,Mask<XFA_FWL_KeyFlag> dwFlags,const CFX_PointF & point)100 bool CXFA_FFWidgetHandler::OnRButtonUp(CXFA_FFWidget* hWidget,
101                                        Mask<XFA_FWL_KeyFlag> dwFlags,
102                                        const CFX_PointF& point) {
103   return hWidget->OnRButtonUp(dwFlags, hWidget->Rotate2Normal(point));
104 }
105 
OnRButtonDblClk(CXFA_FFWidget * hWidget,Mask<XFA_FWL_KeyFlag> dwFlags,const CFX_PointF & point)106 bool CXFA_FFWidgetHandler::OnRButtonDblClk(CXFA_FFWidget* hWidget,
107                                            Mask<XFA_FWL_KeyFlag> dwFlags,
108                                            const CFX_PointF& point) {
109   return hWidget->OnRButtonDblClk(dwFlags, hWidget->Rotate2Normal(point));
110 }
111 
OnKeyDown(CXFA_FFWidget * hWidget,XFA_FWL_VKEYCODE dwKeyCode,Mask<XFA_FWL_KeyFlag> dwFlags)112 bool CXFA_FFWidgetHandler::OnKeyDown(CXFA_FFWidget* hWidget,
113                                      XFA_FWL_VKEYCODE dwKeyCode,
114                                      Mask<XFA_FWL_KeyFlag> dwFlags) {
115   bool bRet = hWidget->OnKeyDown(dwKeyCode, dwFlags);
116   m_pDocView->UpdateDocView();
117   return bRet;
118 }
119 
OnChar(CXFA_FFWidget * hWidget,uint32_t dwChar,Mask<XFA_FWL_KeyFlag> dwFlags)120 bool CXFA_FFWidgetHandler::OnChar(CXFA_FFWidget* hWidget,
121                                   uint32_t dwChar,
122                                   Mask<XFA_FWL_KeyFlag> dwFlags) {
123   return hWidget->OnChar(dwChar, dwFlags);
124 }
125 
GetText(CXFA_FFWidget * widget)126 WideString CXFA_FFWidgetHandler::GetText(CXFA_FFWidget* widget) {
127   return widget->GetText();
128 }
129 
GetSelectedText(CXFA_FFWidget * widget)130 WideString CXFA_FFWidgetHandler::GetSelectedText(CXFA_FFWidget* widget) {
131   if (!widget->CanCopy())
132     return WideString();
133 
134   return widget->Copy().value_or(WideString());
135 }
136 
PasteText(CXFA_FFWidget * widget,const WideString & text)137 void CXFA_FFWidgetHandler::PasteText(CXFA_FFWidget* widget,
138                                      const WideString& text) {
139   if (!widget->CanPaste())
140     return;
141 
142   widget->Paste(text);
143 }
144 
SelectAllText(CXFA_FFWidget * widget)145 bool CXFA_FFWidgetHandler::SelectAllText(CXFA_FFWidget* widget) {
146   if (!widget->CanSelectAll())
147     return false;
148 
149   widget->SelectAll();
150   return true;
151 }
152 
CanUndo(CXFA_FFWidget * widget)153 bool CXFA_FFWidgetHandler::CanUndo(CXFA_FFWidget* widget) {
154   return widget->CanUndo();
155 }
156 
CanRedo(CXFA_FFWidget * widget)157 bool CXFA_FFWidgetHandler::CanRedo(CXFA_FFWidget* widget) {
158   return widget->CanRedo();
159 }
160 
Undo(CXFA_FFWidget * widget)161 bool CXFA_FFWidgetHandler::Undo(CXFA_FFWidget* widget) {
162   return widget->Undo();
163 }
164 
Redo(CXFA_FFWidget * widget)165 bool CXFA_FFWidgetHandler::Redo(CXFA_FFWidget* widget) {
166   return widget->Redo();
167 }
168 
HitTest(CXFA_FFWidget * pWidget,const CFX_PointF & point)169 FWL_WidgetHit CXFA_FFWidgetHandler::HitTest(CXFA_FFWidget* pWidget,
170                                             const CFX_PointF& point) {
171   if (!pWidget->GetLayoutItem()->TestStatusBits(XFA_WidgetStatus::kVisible))
172     return FWL_WidgetHit::Unknown;
173   return pWidget->HitTest(pWidget->Rotate2Normal(point));
174 }
175 
RenderWidget(CXFA_FFWidget * hWidget,CFGAS_GEGraphics * pGS,const CFX_Matrix & matrix,bool bHighlight)176 void CXFA_FFWidgetHandler::RenderWidget(CXFA_FFWidget* hWidget,
177                                         CFGAS_GEGraphics* pGS,
178                                         const CFX_Matrix& matrix,
179                                         bool bHighlight) {
180   hWidget->RenderWidget(
181       pGS, matrix,
182       bHighlight ? CXFA_FFWidget::kHighlight : CXFA_FFWidget::kNoHighlight);
183 }
184 
HasEvent(CXFA_Node * pNode,XFA_EVENTTYPE eEventType)185 bool CXFA_FFWidgetHandler::HasEvent(CXFA_Node* pNode,
186                                     XFA_EVENTTYPE eEventType) {
187   if (eEventType == XFA_EVENT_Unknown)
188     return false;
189   if (!pNode || pNode->GetElementType() == XFA_Element::Draw)
190     return false;
191 
192   switch (eEventType) {
193     case XFA_EVENT_Calculate: {
194       CXFA_Calculate* calc = pNode->GetCalculateIfExists();
195       return calc && calc->GetScriptIfExists();
196     }
197     case XFA_EVENT_Validate: {
198       CXFA_Validate* validate = pNode->GetValidateIfExists();
199       return validate && validate->GetScriptIfExists();
200     }
201     default:
202       break;
203   }
204   return !pNode->GetEventByActivity(kXFAEventActivity[eEventType], false)
205               .empty();
206 }
207 
ProcessEvent(CXFA_Node * pNode,CXFA_EventParam * pParam)208 XFA_EventError CXFA_FFWidgetHandler::ProcessEvent(CXFA_Node* pNode,
209                                                   CXFA_EventParam* pParam) {
210   if (!pParam || pParam->m_eType == XFA_EVENT_Unknown)
211     return XFA_EventError::kNotExist;
212   if (!pNode || pNode->GetElementType() == XFA_Element::Draw)
213     return XFA_EventError::kNotExist;
214 
215   switch (pParam->m_eType) {
216     case XFA_EVENT_Calculate:
217       return pNode->ProcessCalculate(m_pDocView.Get());
218     case XFA_EVENT_Validate:
219       if (m_pDocView->GetDoc()->IsValidationsEnabled())
220         return pNode->ProcessValidate(m_pDocView.Get(), 0);
221       return XFA_EventError::kDisabled;
222     case XFA_EVENT_InitCalculate: {
223       CXFA_Calculate* calc = pNode->GetCalculateIfExists();
224       if (!calc)
225         return XFA_EventError::kNotExist;
226       if (pNode->IsUserInteractive())
227         return XFA_EventError::kDisabled;
228       return pNode->ExecuteScript(m_pDocView.Get(), calc->GetScriptIfExists(),
229                                   pParam);
230     }
231     default:
232       break;
233   }
234   return pNode->ProcessEvent(m_pDocView.Get(),
235                              kXFAEventActivity[pParam->m_eType], pParam);
236 }
237