1 // Copyright 2014 PDFium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6
7 #include "xfa/fxfa/cxfa_ffwidgethandler.h"
8
9 #include <vector>
10
11 #include "fxjs/xfa/cjx_object.h"
12 #include "xfa/fxfa/cxfa_ffdoc.h"
13 #include "xfa/fxfa/cxfa_ffdocview.h"
14 #include "xfa/fxfa/cxfa_fffield.h"
15 #include "xfa/fxfa/cxfa_ffwidget.h"
16 #include "xfa/fxfa/cxfa_fwladapterwidgetmgr.h"
17 #include "xfa/fxfa/layout/cxfa_layoutprocessor.h"
18 #include "xfa/fxfa/parser/cxfa_calculate.h"
19 #include "xfa/fxfa/parser/cxfa_checkbutton.h"
20 #include "xfa/fxfa/parser/cxfa_measurement.h"
21 #include "xfa/fxfa/parser/cxfa_node.h"
22 #include "xfa/fxfa/parser/cxfa_ui.h"
23 #include "xfa/fxfa/parser/cxfa_validate.h"
24
CXFA_FFWidgetHandler(CXFA_FFDocView * pDocView)25 CXFA_FFWidgetHandler::CXFA_FFWidgetHandler(CXFA_FFDocView* pDocView)
26 : m_pDocView(pDocView) {}
27
~CXFA_FFWidgetHandler()28 CXFA_FFWidgetHandler::~CXFA_FFWidgetHandler() {}
29
OnMouseEnter(CXFA_FFWidget * hWidget)30 bool CXFA_FFWidgetHandler::OnMouseEnter(CXFA_FFWidget* hWidget) {
31 m_pDocView->LockUpdate();
32 bool bRet = hWidget->OnMouseEnter();
33 m_pDocView->UnlockUpdate();
34 m_pDocView->UpdateDocView();
35 return bRet;
36 }
37
OnMouseExit(CXFA_FFWidget * hWidget)38 bool CXFA_FFWidgetHandler::OnMouseExit(CXFA_FFWidget* hWidget) {
39 m_pDocView->LockUpdate();
40 bool bRet = hWidget->OnMouseExit();
41 m_pDocView->UnlockUpdate();
42 m_pDocView->UpdateDocView();
43 return bRet;
44 }
45
OnLButtonDown(CXFA_FFWidget * hWidget,uint32_t dwFlags,const CFX_PointF & point)46 bool CXFA_FFWidgetHandler::OnLButtonDown(CXFA_FFWidget* hWidget,
47 uint32_t dwFlags,
48 const CFX_PointF& point) {
49 m_pDocView->LockUpdate();
50 bool bRet = hWidget->AcceptsFocusOnButtonDown(
51 dwFlags, hWidget->Rotate2Normal(point), FWL_MouseCommand::LeftButtonDown);
52 if (bRet) {
53 if (m_pDocView->SetFocus(hWidget)) {
54 m_pDocView->GetDoc()->GetDocEnvironment()->SetFocusWidget(
55 m_pDocView->GetDoc(), hWidget);
56 }
57 bRet = hWidget->OnLButtonDown(dwFlags, hWidget->Rotate2Normal(point));
58 }
59 m_pDocView->UnlockUpdate();
60 m_pDocView->UpdateDocView();
61 return bRet;
62 }
63
OnLButtonUp(CXFA_FFWidget * hWidget,uint32_t dwFlags,const CFX_PointF & point)64 bool CXFA_FFWidgetHandler::OnLButtonUp(CXFA_FFWidget* hWidget,
65 uint32_t dwFlags,
66 const CFX_PointF& point) {
67 m_pDocView->LockUpdate();
68 m_pDocView->m_bLayoutEvent = true;
69 bool bRet = hWidget->OnLButtonUp(dwFlags, hWidget->Rotate2Normal(point));
70 m_pDocView->UnlockUpdate();
71 m_pDocView->UpdateDocView();
72 return bRet;
73 }
74
OnLButtonDblClk(CXFA_FFWidget * hWidget,uint32_t dwFlags,const CFX_PointF & point)75 bool CXFA_FFWidgetHandler::OnLButtonDblClk(CXFA_FFWidget* hWidget,
76 uint32_t dwFlags,
77 const CFX_PointF& point) {
78 bool bRet = hWidget->OnLButtonDblClk(dwFlags, hWidget->Rotate2Normal(point));
79 return bRet;
80 }
81
OnMouseMove(CXFA_FFWidget * hWidget,uint32_t dwFlags,const CFX_PointF & point)82 bool CXFA_FFWidgetHandler::OnMouseMove(CXFA_FFWidget* hWidget,
83 uint32_t dwFlags,
84 const CFX_PointF& point) {
85 bool bRet = hWidget->OnMouseMove(dwFlags, hWidget->Rotate2Normal(point));
86 return bRet;
87 }
88
OnMouseWheel(CXFA_FFWidget * hWidget,uint32_t dwFlags,int16_t zDelta,const CFX_PointF & point)89 bool CXFA_FFWidgetHandler::OnMouseWheel(CXFA_FFWidget* hWidget,
90 uint32_t dwFlags,
91 int16_t zDelta,
92 const CFX_PointF& point) {
93 bool bRet =
94 hWidget->OnMouseWheel(dwFlags, zDelta, hWidget->Rotate2Normal(point));
95 return bRet;
96 }
97
OnRButtonDown(CXFA_FFWidget * hWidget,uint32_t dwFlags,const CFX_PointF & point)98 bool CXFA_FFWidgetHandler::OnRButtonDown(CXFA_FFWidget* hWidget,
99 uint32_t dwFlags,
100 const CFX_PointF& point) {
101 bool bRet =
102 hWidget->AcceptsFocusOnButtonDown(dwFlags, hWidget->Rotate2Normal(point),
103 FWL_MouseCommand::RightButtonDown);
104 if (bRet) {
105 if (m_pDocView->SetFocus(hWidget)) {
106 m_pDocView->GetDoc()->GetDocEnvironment()->SetFocusWidget(
107 m_pDocView->GetDoc(), hWidget);
108 }
109 bRet = hWidget->OnRButtonDown(dwFlags, hWidget->Rotate2Normal(point));
110 }
111 return bRet;
112 }
113
OnRButtonUp(CXFA_FFWidget * hWidget,uint32_t dwFlags,const CFX_PointF & point)114 bool CXFA_FFWidgetHandler::OnRButtonUp(CXFA_FFWidget* hWidget,
115 uint32_t dwFlags,
116 const CFX_PointF& point) {
117 bool bRet = hWidget->OnRButtonUp(dwFlags, hWidget->Rotate2Normal(point));
118 return bRet;
119 }
120
OnRButtonDblClk(CXFA_FFWidget * hWidget,uint32_t dwFlags,const CFX_PointF & point)121 bool CXFA_FFWidgetHandler::OnRButtonDblClk(CXFA_FFWidget* hWidget,
122 uint32_t dwFlags,
123 const CFX_PointF& point) {
124 bool bRet = hWidget->OnRButtonDblClk(dwFlags, hWidget->Rotate2Normal(point));
125 return bRet;
126 }
127
OnKeyDown(CXFA_FFWidget * hWidget,uint32_t dwKeyCode,uint32_t dwFlags)128 bool CXFA_FFWidgetHandler::OnKeyDown(CXFA_FFWidget* hWidget,
129 uint32_t dwKeyCode,
130 uint32_t dwFlags) {
131 bool bRet = hWidget->OnKeyDown(dwKeyCode, dwFlags);
132 m_pDocView->UpdateDocView();
133 return bRet;
134 }
135
OnKeyUp(CXFA_FFWidget * hWidget,uint32_t dwKeyCode,uint32_t dwFlags)136 bool CXFA_FFWidgetHandler::OnKeyUp(CXFA_FFWidget* hWidget,
137 uint32_t dwKeyCode,
138 uint32_t dwFlags) {
139 bool bRet = hWidget->OnKeyUp(dwKeyCode, dwFlags);
140 return bRet;
141 }
142
OnChar(CXFA_FFWidget * hWidget,uint32_t dwChar,uint32_t dwFlags)143 bool CXFA_FFWidgetHandler::OnChar(CXFA_FFWidget* hWidget,
144 uint32_t dwChar,
145 uint32_t dwFlags) {
146 bool bRet = hWidget->OnChar(dwChar, dwFlags);
147 return bRet;
148 }
149
GetText(CXFA_FFWidget * widget)150 WideString CXFA_FFWidgetHandler::GetText(CXFA_FFWidget* widget) {
151 return widget->GetText();
152 }
153
GetSelectedText(CXFA_FFWidget * widget)154 WideString CXFA_FFWidgetHandler::GetSelectedText(CXFA_FFWidget* widget) {
155 if (!widget->CanCopy())
156 return WideString();
157
158 return widget->Copy().value_or(WideString());
159 }
160
PasteText(CXFA_FFWidget * widget,const WideString & text)161 void CXFA_FFWidgetHandler::PasteText(CXFA_FFWidget* widget,
162 const WideString& text) {
163 if (!widget->CanPaste())
164 return;
165
166 widget->Paste(text);
167 }
168
CanUndo(CXFA_FFWidget * widget)169 bool CXFA_FFWidgetHandler::CanUndo(CXFA_FFWidget* widget) {
170 return widget->CanUndo();
171 }
172
CanRedo(CXFA_FFWidget * widget)173 bool CXFA_FFWidgetHandler::CanRedo(CXFA_FFWidget* widget) {
174 return widget->CanRedo();
175 }
176
Undo(CXFA_FFWidget * widget)177 bool CXFA_FFWidgetHandler::Undo(CXFA_FFWidget* widget) {
178 return widget->Undo();
179 }
180
Redo(CXFA_FFWidget * widget)181 bool CXFA_FFWidgetHandler::Redo(CXFA_FFWidget* widget) {
182 return widget->Redo();
183 }
184
HitTest(CXFA_FFWidget * pWidget,const CFX_PointF & point)185 FWL_WidgetHit CXFA_FFWidgetHandler::HitTest(CXFA_FFWidget* pWidget,
186 const CFX_PointF& point) {
187 if (!pWidget->GetLayoutItem()->TestStatusBits(XFA_WidgetStatus_Visible))
188 return FWL_WidgetHit::Unknown;
189 return pWidget->HitTest(pWidget->Rotate2Normal(point));
190 }
191
OnSetCursor(CXFA_FFWidget * hWidget,const CFX_PointF & point)192 bool CXFA_FFWidgetHandler::OnSetCursor(CXFA_FFWidget* hWidget,
193 const CFX_PointF& point) {
194 return hWidget->OnSetCursor(hWidget->Rotate2Normal(point));
195 }
196
RenderWidget(CXFA_FFWidget * hWidget,CXFA_Graphics * pGS,const CFX_Matrix & matrix,bool bHighlight)197 void CXFA_FFWidgetHandler::RenderWidget(CXFA_FFWidget* hWidget,
198 CXFA_Graphics* pGS,
199 const CFX_Matrix& matrix,
200 bool bHighlight) {
201 hWidget->RenderWidget(
202 pGS, matrix,
203 bHighlight ? CXFA_FFWidget::kHighlight : CXFA_FFWidget::kNoHighlight);
204 }
205
HasEvent(CXFA_Node * pNode,XFA_EVENTTYPE eEventType)206 bool CXFA_FFWidgetHandler::HasEvent(CXFA_Node* pNode,
207 XFA_EVENTTYPE eEventType) {
208 if (eEventType == XFA_EVENT_Unknown)
209 return false;
210 if (!pNode || pNode->GetElementType() == XFA_Element::Draw)
211 return false;
212
213 switch (eEventType) {
214 case XFA_EVENT_Calculate: {
215 CXFA_Calculate* calc = pNode->GetCalculateIfExists();
216 return calc && calc->GetScriptIfExists();
217 }
218 case XFA_EVENT_Validate: {
219 CXFA_Validate* validate = pNode->GetValidateIfExists();
220 return validate && validate->GetScriptIfExists();
221 }
222 default:
223 break;
224 }
225 return !pNode->GetEventByActivity(gs_EventActivity[eEventType], false)
226 .empty();
227 }
228
ProcessEvent(CXFA_Node * pNode,CXFA_EventParam * pParam)229 XFA_EventError CXFA_FFWidgetHandler::ProcessEvent(CXFA_Node* pNode,
230 CXFA_EventParam* pParam) {
231 if (!pParam || pParam->m_eType == XFA_EVENT_Unknown)
232 return XFA_EventError::kNotExist;
233 if (!pNode || pNode->GetElementType() == XFA_Element::Draw)
234 return XFA_EventError::kNotExist;
235
236 switch (pParam->m_eType) {
237 case XFA_EVENT_Calculate:
238 return pNode->ProcessCalculate(m_pDocView.Get());
239 case XFA_EVENT_Validate:
240 if (m_pDocView->GetDoc()->GetDocEnvironment()->IsValidationsEnabled(
241 m_pDocView->GetDoc())) {
242 return pNode->ProcessValidate(m_pDocView.Get(), 0);
243 }
244 return XFA_EventError::kDisabled;
245 case XFA_EVENT_InitCalculate: {
246 CXFA_Calculate* calc = pNode->GetCalculateIfExists();
247 if (!calc)
248 return XFA_EventError::kNotExist;
249 if (pNode->IsUserInteractive())
250 return XFA_EventError::kDisabled;
251 return pNode->ExecuteScript(m_pDocView.Get(), calc->GetScriptIfExists(),
252 pParam);
253 }
254 default:
255 break;
256 }
257 return pNode->ProcessEvent(m_pDocView.Get(),
258 gs_EventActivity[pParam->m_eType], pParam);
259 }
260