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/parser/cxfa_calculate.h"
18 #include "xfa/fxfa/parser/cxfa_checkbutton.h"
19 #include "xfa/fxfa/parser/cxfa_layoutprocessor.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->OnLButtonDown(dwFlags, hWidget->Rotate2Normal(point));
51 if (bRet && m_pDocView->SetFocus(hWidget)) {
52 m_pDocView->GetDoc()->GetDocEnvironment()->SetFocusWidget(
53 m_pDocView->GetDoc(), hWidget);
54 }
55 m_pDocView->UnlockUpdate();
56 m_pDocView->UpdateDocView();
57 return bRet;
58 }
59
OnLButtonUp(CXFA_FFWidget * hWidget,uint32_t dwFlags,const CFX_PointF & point)60 bool CXFA_FFWidgetHandler::OnLButtonUp(CXFA_FFWidget* hWidget,
61 uint32_t dwFlags,
62 const CFX_PointF& point) {
63 m_pDocView->LockUpdate();
64 m_pDocView->m_bLayoutEvent = true;
65 bool bRet = hWidget->OnLButtonUp(dwFlags, hWidget->Rotate2Normal(point));
66 m_pDocView->UnlockUpdate();
67 m_pDocView->UpdateDocView();
68 return bRet;
69 }
70
OnLButtonDblClk(CXFA_FFWidget * hWidget,uint32_t dwFlags,const CFX_PointF & point)71 bool CXFA_FFWidgetHandler::OnLButtonDblClk(CXFA_FFWidget* hWidget,
72 uint32_t dwFlags,
73 const CFX_PointF& point) {
74 bool bRet = hWidget->OnLButtonDblClk(dwFlags, hWidget->Rotate2Normal(point));
75 m_pDocView->RunInvalidate();
76 return bRet;
77 }
78
OnMouseMove(CXFA_FFWidget * hWidget,uint32_t dwFlags,const CFX_PointF & point)79 bool CXFA_FFWidgetHandler::OnMouseMove(CXFA_FFWidget* hWidget,
80 uint32_t dwFlags,
81 const CFX_PointF& point) {
82 bool bRet = hWidget->OnMouseMove(dwFlags, hWidget->Rotate2Normal(point));
83 m_pDocView->RunInvalidate();
84 return bRet;
85 }
86
OnMouseWheel(CXFA_FFWidget * hWidget,uint32_t dwFlags,int16_t zDelta,const CFX_PointF & point)87 bool CXFA_FFWidgetHandler::OnMouseWheel(CXFA_FFWidget* hWidget,
88 uint32_t dwFlags,
89 int16_t zDelta,
90 const CFX_PointF& point) {
91 bool bRet =
92 hWidget->OnMouseWheel(dwFlags, zDelta, hWidget->Rotate2Normal(point));
93 m_pDocView->RunInvalidate();
94 return bRet;
95 }
96
OnRButtonDown(CXFA_FFWidget * hWidget,uint32_t dwFlags,const CFX_PointF & point)97 bool CXFA_FFWidgetHandler::OnRButtonDown(CXFA_FFWidget* hWidget,
98 uint32_t dwFlags,
99 const CFX_PointF& point) {
100 bool bRet = hWidget->OnRButtonDown(dwFlags, hWidget->Rotate2Normal(point));
101 if (bRet && m_pDocView->SetFocus(hWidget)) {
102 m_pDocView->GetDoc()->GetDocEnvironment()->SetFocusWidget(
103 m_pDocView->GetDoc(), hWidget);
104 }
105 m_pDocView->RunInvalidate();
106 return bRet;
107 }
108
OnRButtonUp(CXFA_FFWidget * hWidget,uint32_t dwFlags,const CFX_PointF & point)109 bool CXFA_FFWidgetHandler::OnRButtonUp(CXFA_FFWidget* hWidget,
110 uint32_t dwFlags,
111 const CFX_PointF& point) {
112 bool bRet = hWidget->OnRButtonUp(dwFlags, hWidget->Rotate2Normal(point));
113 m_pDocView->RunInvalidate();
114 return bRet;
115 }
116
OnRButtonDblClk(CXFA_FFWidget * hWidget,uint32_t dwFlags,const CFX_PointF & point)117 bool CXFA_FFWidgetHandler::OnRButtonDblClk(CXFA_FFWidget* hWidget,
118 uint32_t dwFlags,
119 const CFX_PointF& point) {
120 bool bRet = hWidget->OnRButtonDblClk(dwFlags, hWidget->Rotate2Normal(point));
121 m_pDocView->RunInvalidate();
122 return bRet;
123 }
124
OnKeyDown(CXFA_FFWidget * hWidget,uint32_t dwKeyCode,uint32_t dwFlags)125 bool CXFA_FFWidgetHandler::OnKeyDown(CXFA_FFWidget* hWidget,
126 uint32_t dwKeyCode,
127 uint32_t dwFlags) {
128 bool bRet = hWidget->OnKeyDown(dwKeyCode, dwFlags);
129 m_pDocView->RunInvalidate();
130 m_pDocView->UpdateDocView();
131 return bRet;
132 }
133
OnKeyUp(CXFA_FFWidget * hWidget,uint32_t dwKeyCode,uint32_t dwFlags)134 bool CXFA_FFWidgetHandler::OnKeyUp(CXFA_FFWidget* hWidget,
135 uint32_t dwKeyCode,
136 uint32_t dwFlags) {
137 bool bRet = hWidget->OnKeyUp(dwKeyCode, dwFlags);
138 m_pDocView->RunInvalidate();
139 return bRet;
140 }
141
OnChar(CXFA_FFWidget * hWidget,uint32_t dwChar,uint32_t dwFlags)142 bool CXFA_FFWidgetHandler::OnChar(CXFA_FFWidget* hWidget,
143 uint32_t dwChar,
144 uint32_t dwFlags) {
145 bool bRet = hWidget->OnChar(dwChar, dwFlags);
146 m_pDocView->RunInvalidate();
147 return bRet;
148 }
149
GetSelectedText(CXFA_FFWidget * widget)150 WideString CXFA_FFWidgetHandler::GetSelectedText(CXFA_FFWidget* widget) {
151 if (!widget->CanCopy())
152 return WideString();
153
154 return widget->Copy().value_or(WideString());
155 }
156
PasteText(CXFA_FFWidget * widget,const WideString & text)157 void CXFA_FFWidgetHandler::PasteText(CXFA_FFWidget* widget,
158 const WideString& text) {
159 if (!widget->CanPaste())
160 return;
161
162 widget->Paste(text);
163 }
164
OnHitTest(CXFA_FFWidget * hWidget,const CFX_PointF & point)165 FWL_WidgetHit CXFA_FFWidgetHandler::OnHitTest(CXFA_FFWidget* hWidget,
166 const CFX_PointF& point) {
167 if (!(hWidget->GetStatus() & XFA_WidgetStatus_Visible))
168 return FWL_WidgetHit::Unknown;
169 return hWidget->OnHitTest(hWidget->Rotate2Normal(point));
170 }
171
OnSetCursor(CXFA_FFWidget * hWidget,const CFX_PointF & point)172 bool CXFA_FFWidgetHandler::OnSetCursor(CXFA_FFWidget* hWidget,
173 const CFX_PointF& point) {
174 return hWidget->OnSetCursor(hWidget->Rotate2Normal(point));
175 }
176
RenderWidget(CXFA_FFWidget * hWidget,CXFA_Graphics * pGS,const CFX_Matrix & matrix,bool bHighlight)177 void CXFA_FFWidgetHandler::RenderWidget(CXFA_FFWidget* hWidget,
178 CXFA_Graphics* pGS,
179 const CFX_Matrix& matrix,
180 bool bHighlight) {
181 hWidget->RenderWidget(pGS, matrix,
182 bHighlight ? XFA_WidgetStatus_Highlight : 0);
183 }
184
HasEvent(CXFA_WidgetAcc * pWidgetAcc,XFA_EVENTTYPE eEventType)185 bool CXFA_FFWidgetHandler::HasEvent(CXFA_WidgetAcc* pWidgetAcc,
186 XFA_EVENTTYPE eEventType) {
187 if (eEventType == XFA_EVENT_Unknown)
188 return false;
189 if (!pWidgetAcc)
190 return false;
191
192 CXFA_Node* node = pWidgetAcc->GetNode();
193 if (!node || node->GetElementType() == XFA_Element::Draw)
194 return false;
195
196 switch (eEventType) {
197 case XFA_EVENT_Calculate: {
198 CXFA_Calculate* calc = node->GetCalculateIfExists();
199 return calc && calc->GetScriptIfExists();
200 }
201 case XFA_EVENT_Validate: {
202 CXFA_Validate* validate = node->GetValidateIfExists();
203 return validate && validate->GetScriptIfExists();
204 }
205 default:
206 break;
207 }
208 return !pWidgetAcc->GetEventByActivity(gs_EventActivity[eEventType], false)
209 .empty();
210 }
211
ProcessEvent(CXFA_WidgetAcc * pWidgetAcc,CXFA_EventParam * pParam)212 int32_t CXFA_FFWidgetHandler::ProcessEvent(CXFA_WidgetAcc* pWidgetAcc,
213 CXFA_EventParam* pParam) {
214 if (!pParam || pParam->m_eType == XFA_EVENT_Unknown)
215 return XFA_EVENTERROR_NotExist;
216 if (!pWidgetAcc)
217 return XFA_EVENTERROR_NotExist;
218
219 CXFA_Node* node = pWidgetAcc->GetNode();
220 if (!node || node->GetElementType() == XFA_Element::Draw)
221 return XFA_EVENTERROR_NotExist;
222
223 switch (pParam->m_eType) {
224 case XFA_EVENT_Calculate:
225 return node->ProcessCalculate(m_pDocView);
226 case XFA_EVENT_Validate:
227 if (m_pDocView->GetDoc()->GetDocEnvironment()->IsValidationsEnabled(
228 m_pDocView->GetDoc())) {
229 return node->ProcessValidate(m_pDocView, 0);
230 }
231 return XFA_EVENTERROR_Disabled;
232 case XFA_EVENT_InitCalculate: {
233 CXFA_Calculate* calc = node->GetCalculateIfExists();
234 if (!calc)
235 return XFA_EVENTERROR_NotExist;
236 if (node->IsUserInteractive())
237 return XFA_EVENTERROR_Disabled;
238 return node->ExecuteScript(m_pDocView, calc->GetScriptIfExists(), pParam);
239 }
240 default:
241 break;
242 }
243 int32_t iRet =
244 node->ProcessEvent(m_pDocView, gs_EventActivity[pParam->m_eType], pParam);
245 return iRet;
246 }
247
CreateWidget(CXFA_FFWidget * hParent,XFA_WIDGETTYPE eType,CXFA_FFWidget * hBefore)248 CXFA_FFWidget* CXFA_FFWidgetHandler::CreateWidget(CXFA_FFWidget* hParent,
249 XFA_WIDGETTYPE eType,
250 CXFA_FFWidget* hBefore) {
251 CXFA_Node* pParentFormItem = hParent ? hParent->GetNode() : nullptr;
252 CXFA_Node* pBeforeFormItem = hBefore ? hBefore->GetNode() : nullptr;
253 CXFA_Node* pNewFormItem =
254 CreateWidgetFormItem(eType, pParentFormItem, pBeforeFormItem);
255 if (!pNewFormItem)
256 return nullptr;
257
258 CXFA_Node* templateNode = pNewFormItem->GetTemplateNodeIfExists();
259 if (!templateNode)
260 return nullptr;
261
262 templateNode->SetFlag(XFA_NodeFlag_Initialized, true);
263 pNewFormItem->SetFlag(XFA_NodeFlag_Initialized, true);
264 m_pDocView->RunLayout();
265 CXFA_LayoutItem* pLayout =
266 m_pDocView->GetXFALayout()->GetLayoutItem(pNewFormItem);
267 return static_cast<CXFA_FFWidget*>(pLayout);
268 }
269
CreateWidgetFormItem(XFA_WIDGETTYPE eType,CXFA_Node * pParent,CXFA_Node * pBefore) const270 CXFA_Node* CXFA_FFWidgetHandler::CreateWidgetFormItem(
271 XFA_WIDGETTYPE eType,
272 CXFA_Node* pParent,
273 CXFA_Node* pBefore) const {
274 switch (eType) {
275 case XFA_WIDGETTYPE_Barcode:
276 return nullptr;
277 case XFA_WIDGETTYPE_PushButton:
278 return CreatePushButton(pParent, pBefore);
279 case XFA_WIDGETTYPE_CheckButton:
280 return CreateCheckButton(pParent, pBefore);
281 case XFA_WIDGETTYPE_ExcludeGroup:
282 return CreateExclGroup(pParent, pBefore);
283 case XFA_WIDGETTYPE_RadioButton:
284 return CreateRadioButton(pParent, pBefore);
285 case XFA_WIDGETTYPE_Arc:
286 return CreateArc(pParent, pBefore);
287 case XFA_WIDGETTYPE_Rectangle:
288 return CreateRectangle(pParent, pBefore);
289 case XFA_WIDGETTYPE_Image:
290 return CreateImage(pParent, pBefore);
291 case XFA_WIDGETTYPE_Line:
292 return CreateLine(pParent, pBefore);
293 case XFA_WIDGETTYPE_Text:
294 return CreateText(pParent, pBefore);
295 case XFA_WIDGETTYPE_DatetimeEdit:
296 return CreateDatetimeEdit(pParent, pBefore);
297 case XFA_WIDGETTYPE_DecimalField:
298 return CreateDecimalField(pParent, pBefore);
299 case XFA_WIDGETTYPE_NumericField:
300 return CreateNumericField(pParent, pBefore);
301 case XFA_WIDGETTYPE_Signature:
302 return CreateSignature(pParent, pBefore);
303 case XFA_WIDGETTYPE_TextEdit:
304 return CreateTextEdit(pParent, pBefore);
305 case XFA_WIDGETTYPE_DropdownList:
306 return CreateDropdownList(pParent, pBefore);
307 case XFA_WIDGETTYPE_ListBox:
308 return CreateListBox(pParent, pBefore);
309 case XFA_WIDGETTYPE_ImageField:
310 return CreateImageField(pParent, pBefore);
311 case XFA_WIDGETTYPE_PasswordEdit:
312 return CreatePasswordEdit(pParent, pBefore);
313 case XFA_WIDGETTYPE_Subform:
314 return CreateSubform(pParent, pBefore);
315 default:
316 return nullptr;
317 }
318 }
319
CreatePushButton(CXFA_Node * pParent,CXFA_Node * pBefore) const320 CXFA_Node* CXFA_FFWidgetHandler::CreatePushButton(CXFA_Node* pParent,
321 CXFA_Node* pBefore) const {
322 CXFA_Node* pField = CreateField(XFA_Element::Button, pParent, pBefore);
323 CXFA_Node* pCaption = CreateCopyNode(XFA_Element::Caption, pField);
324 CXFA_Node* pValue = CreateCopyNode(XFA_Element::Value, pCaption);
325 CXFA_Node* pText = CreateCopyNode(XFA_Element::Text, pValue);
326 pText->JSObject()->SetContent(L"Button", L"Button", false, false, true);
327
328 CXFA_Node* pPara = CreateCopyNode(XFA_Element::Para, pCaption);
329 pPara->JSObject()->SetEnum(XFA_Attribute::VAlign, XFA_AttributeEnum::Middle,
330 false);
331 pPara->JSObject()->SetEnum(XFA_Attribute::HAlign, XFA_AttributeEnum::Center,
332 false);
333 CreateFontNode(pCaption);
334
335 CXFA_Node* pBorder = CreateCopyNode(XFA_Element::Border, pField);
336 pBorder->JSObject()->SetEnum(XFA_Attribute::Hand, XFA_AttributeEnum::Right,
337 false);
338
339 CXFA_Node* pEdge = CreateCopyNode(XFA_Element::Edge, pBorder);
340 pEdge->JSObject()->SetEnum(XFA_Attribute::Stroke, XFA_AttributeEnum::Raised,
341 false);
342
343 CXFA_Node* pFill = CreateCopyNode(XFA_Element::Fill, pBorder);
344 CXFA_Node* pColor = CreateCopyNode(XFA_Element::Color, pFill);
345 pColor->JSObject()->SetCData(XFA_Attribute::Value, L"212, 208, 200", false,
346 false);
347
348 CXFA_Node* pBind = CreateCopyNode(XFA_Element::Bind, pField);
349 pBind->JSObject()->SetEnum(XFA_Attribute::Match, XFA_AttributeEnum::None,
350 false);
351
352 return pField;
353 }
354
CreateCheckButton(CXFA_Node * pParent,CXFA_Node * pBefore) const355 CXFA_Node* CXFA_FFWidgetHandler::CreateCheckButton(CXFA_Node* pParent,
356 CXFA_Node* pBefore) const {
357 return CreateField(XFA_Element::CheckButton, pParent, pBefore);
358 }
359
CreateExclGroup(CXFA_Node * pParent,CXFA_Node * pBefore) const360 CXFA_Node* CXFA_FFWidgetHandler::CreateExclGroup(CXFA_Node* pParent,
361 CXFA_Node* pBefore) const {
362 return CreateFormItem(XFA_Element::ExclGroup, pParent, pBefore);
363 }
364
CreateRadioButton(CXFA_Node * pParent,CXFA_Node * pBefore) const365 CXFA_Node* CXFA_FFWidgetHandler::CreateRadioButton(CXFA_Node* pParent,
366 CXFA_Node* pBefore) const {
367 CXFA_Node* pField = CreateField(XFA_Element::CheckButton, pParent, pBefore);
368 CXFA_Ui* pUi = pField->GetFirstChildByClass<CXFA_Ui>(XFA_Element::Ui);
369 CXFA_CheckButton* pWidget =
370 pUi->GetFirstChildByClass<CXFA_CheckButton>(XFA_Element::CheckButton);
371 pWidget->JSObject()->SetEnum(XFA_Attribute::Shape, XFA_AttributeEnum::Round,
372 false);
373 return pField;
374 }
375
CreateDatetimeEdit(CXFA_Node * pParent,CXFA_Node * pBefore) const376 CXFA_Node* CXFA_FFWidgetHandler::CreateDatetimeEdit(CXFA_Node* pParent,
377 CXFA_Node* pBefore) const {
378 CXFA_Node* pField = CreateField(XFA_Element::DateTimeEdit, pParent, pBefore);
379 CreateValueNode(XFA_Element::Date, pField);
380 return pField;
381 }
382
CreateDecimalField(CXFA_Node * pParent,CXFA_Node * pBefore) const383 CXFA_Node* CXFA_FFWidgetHandler::CreateDecimalField(CXFA_Node* pParent,
384 CXFA_Node* pBefore) const {
385 CXFA_Node* pField = CreateNumericField(pParent, pBefore);
386 CreateValueNode(XFA_Element::Decimal, pField);
387 return pField;
388 }
389
CreateNumericField(CXFA_Node * pParent,CXFA_Node * pBefore) const390 CXFA_Node* CXFA_FFWidgetHandler::CreateNumericField(CXFA_Node* pParent,
391 CXFA_Node* pBefore) const {
392 return CreateField(XFA_Element::NumericEdit, pParent, pBefore);
393 }
394
CreateSignature(CXFA_Node * pParent,CXFA_Node * pBefore) const395 CXFA_Node* CXFA_FFWidgetHandler::CreateSignature(CXFA_Node* pParent,
396 CXFA_Node* pBefore) const {
397 return CreateField(XFA_Element::Signature, pParent, pBefore);
398 }
399
CreateTextEdit(CXFA_Node * pParent,CXFA_Node * pBefore) const400 CXFA_Node* CXFA_FFWidgetHandler::CreateTextEdit(CXFA_Node* pParent,
401 CXFA_Node* pBefore) const {
402 return CreateField(XFA_Element::TextEdit, pParent, pBefore);
403 }
404
CreateDropdownList(CXFA_Node * pParent,CXFA_Node * pBefore) const405 CXFA_Node* CXFA_FFWidgetHandler::CreateDropdownList(CXFA_Node* pParent,
406 CXFA_Node* pBefore) const {
407 return CreateField(XFA_Element::ChoiceList, pParent, pBefore);
408 }
409
CreateListBox(CXFA_Node * pParent,CXFA_Node * pBefore) const410 CXFA_Node* CXFA_FFWidgetHandler::CreateListBox(CXFA_Node* pParent,
411 CXFA_Node* pBefore) const {
412 CXFA_Node* pField = CreateDropdownList(pParent, pBefore);
413 CXFA_Node* pUi = pField->GetFirstChild();
414 CXFA_Node* pListBox = pUi->GetFirstChild();
415 pListBox->JSObject()->SetEnum(XFA_Attribute::Open, XFA_AttributeEnum::Always,
416 false);
417 pListBox->JSObject()->SetEnum(XFA_Attribute::CommitOn,
418 XFA_AttributeEnum::Exit, false);
419 return pField;
420 }
421
CreateImageField(CXFA_Node * pParent,CXFA_Node * pBefore) const422 CXFA_Node* CXFA_FFWidgetHandler::CreateImageField(CXFA_Node* pParent,
423 CXFA_Node* pBefore) const {
424 return CreateField(XFA_Element::ImageEdit, pParent, pBefore);
425 }
426
CreatePasswordEdit(CXFA_Node * pParent,CXFA_Node * pBefore) const427 CXFA_Node* CXFA_FFWidgetHandler::CreatePasswordEdit(CXFA_Node* pParent,
428 CXFA_Node* pBefore) const {
429 CXFA_Node* pField = CreateField(XFA_Element::PasswordEdit, pParent, pBefore);
430 CXFA_Node* pBind = CreateCopyNode(XFA_Element::Bind, pField);
431 pBind->JSObject()->SetEnum(XFA_Attribute::Match, XFA_AttributeEnum::None,
432 false);
433 return pField;
434 }
435
CreateField(XFA_Element eElement,CXFA_Node * pParent,CXFA_Node * pBefore) const436 CXFA_Node* CXFA_FFWidgetHandler::CreateField(XFA_Element eElement,
437 CXFA_Node* pParent,
438 CXFA_Node* pBefore) const {
439 CXFA_Node* pField = CreateFormItem(XFA_Element::Field, pParent, pBefore);
440 CreateCopyNode(eElement, CreateCopyNode(XFA_Element::Ui, pField));
441 CreateFontNode(pField);
442 return pField;
443 }
444
CreateArc(CXFA_Node * pParent,CXFA_Node * pBefore) const445 CXFA_Node* CXFA_FFWidgetHandler::CreateArc(CXFA_Node* pParent,
446 CXFA_Node* pBefore) const {
447 return CreateDraw(XFA_Element::Arc, pParent, pBefore);
448 }
449
CreateRectangle(CXFA_Node * pParent,CXFA_Node * pBefore) const450 CXFA_Node* CXFA_FFWidgetHandler::CreateRectangle(CXFA_Node* pParent,
451 CXFA_Node* pBefore) const {
452 return CreateDraw(XFA_Element::Rectangle, pParent, pBefore);
453 }
454
CreateImage(CXFA_Node * pParent,CXFA_Node * pBefore) const455 CXFA_Node* CXFA_FFWidgetHandler::CreateImage(CXFA_Node* pParent,
456 CXFA_Node* pBefore) const {
457 CXFA_Node* pField = CreateDraw(XFA_Element::Image, pParent, pBefore);
458 CreateCopyNode(XFA_Element::ImageEdit,
459 CreateCopyNode(XFA_Element::Ui, pField));
460 return pField;
461 }
462
CreateLine(CXFA_Node * pParent,CXFA_Node * pBefore) const463 CXFA_Node* CXFA_FFWidgetHandler::CreateLine(CXFA_Node* pParent,
464 CXFA_Node* pBefore) const {
465 return CreateDraw(XFA_Element::Line, pParent, pBefore);
466 }
467
CreateText(CXFA_Node * pParent,CXFA_Node * pBefore) const468 CXFA_Node* CXFA_FFWidgetHandler::CreateText(CXFA_Node* pParent,
469 CXFA_Node* pBefore) const {
470 CXFA_Node* pField = CreateDraw(XFA_Element::Text, pParent, pBefore);
471 CreateCopyNode(XFA_Element::TextEdit,
472 CreateCopyNode(XFA_Element::Ui, pField));
473 CreateFontNode(pField);
474 return pField;
475 }
476
CreateDraw(XFA_Element eElement,CXFA_Node * pParent,CXFA_Node * pBefore) const477 CXFA_Node* CXFA_FFWidgetHandler::CreateDraw(XFA_Element eElement,
478 CXFA_Node* pParent,
479 CXFA_Node* pBefore) const {
480 CXFA_Node* pDraw = CreateFormItem(XFA_Element::Draw, pParent, pBefore);
481 CreateValueNode(eElement, pDraw);
482 return pDraw;
483 }
484
CreateSubform(CXFA_Node * pParent,CXFA_Node * pBefore) const485 CXFA_Node* CXFA_FFWidgetHandler::CreateSubform(CXFA_Node* pParent,
486 CXFA_Node* pBefore) const {
487 return CreateFormItem(XFA_Element::Subform, pParent, pBefore);
488 }
489
CreateFormItem(XFA_Element eElement,CXFA_Node * pParent,CXFA_Node * pBefore) const490 CXFA_Node* CXFA_FFWidgetHandler::CreateFormItem(XFA_Element eElement,
491 CXFA_Node* pParent,
492 CXFA_Node* pBefore) const {
493 if (!pParent)
494 return nullptr;
495
496 CXFA_Node* pTemplateParent = pParent->GetTemplateNodeIfExists();
497 if (!pTemplateParent)
498 return nullptr;
499
500 CXFA_Node* pNewFormItem = pTemplateParent->CloneTemplateToForm(false);
501 if (pParent)
502 pParent->InsertChild(pNewFormItem, pBefore);
503 return pNewFormItem;
504 }
505
CreateCopyNode(XFA_Element eElement,CXFA_Node * pParent,CXFA_Node * pBefore) const506 CXFA_Node* CXFA_FFWidgetHandler::CreateCopyNode(XFA_Element eElement,
507 CXFA_Node* pParent,
508 CXFA_Node* pBefore) const {
509 if (!pParent)
510 return nullptr;
511
512 CXFA_Node* pTemplateParent = pParent->GetTemplateNodeIfExists();
513 CXFA_Node* pNewNode =
514 CreateTemplateNode(eElement, pTemplateParent,
515 pBefore ? pBefore->GetTemplateNodeIfExists() : nullptr)
516 ->Clone(false);
517 if (pParent)
518 pParent->InsertChild(pNewNode, pBefore);
519 return pNewNode;
520 }
521
CreateTemplateNode(XFA_Element eElement,CXFA_Node * pParent,CXFA_Node * pBefore) const522 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 =
527 pXFADoc->CreateNode(XFA_PacketType::Template, eElement);
528 if (pParent)
529 pParent->InsertChild(pNewTemplateNode, pBefore);
530 return pNewTemplateNode;
531 }
532
CreateFontNode(CXFA_Node * pParent) const533 CXFA_Node* CXFA_FFWidgetHandler::CreateFontNode(CXFA_Node* pParent) const {
534 CXFA_Node* pFont = CreateCopyNode(XFA_Element::Font, pParent);
535 pFont->JSObject()->SetCData(XFA_Attribute::Typeface, L"Myriad Pro", false,
536 false);
537 return pFont;
538 }
539
CreateMarginNode(CXFA_Node * pParent,uint32_t dwFlags,float fInsets[4]) const540 CXFA_Node* CXFA_FFWidgetHandler::CreateMarginNode(CXFA_Node* pParent,
541 uint32_t dwFlags,
542 float fInsets[4]) const {
543 CXFA_Node* pMargin = CreateCopyNode(XFA_Element::Margin, pParent);
544 if (dwFlags & 0x01)
545 pMargin->JSObject()->SetMeasure(XFA_Attribute::LeftInset,
546 CXFA_Measurement(fInsets[0], XFA_Unit::Pt),
547 false);
548 if (dwFlags & 0x02)
549 pMargin->JSObject()->SetMeasure(XFA_Attribute::TopInset,
550 CXFA_Measurement(fInsets[1], XFA_Unit::Pt),
551 false);
552 if (dwFlags & 0x04)
553 pMargin->JSObject()->SetMeasure(XFA_Attribute::RightInset,
554 CXFA_Measurement(fInsets[2], XFA_Unit::Pt),
555 false);
556 if (dwFlags & 0x08)
557 pMargin->JSObject()->SetMeasure(XFA_Attribute::BottomInset,
558 CXFA_Measurement(fInsets[3], XFA_Unit::Pt),
559 false);
560 return pMargin;
561 }
562
CreateValueNode(XFA_Element eValue,CXFA_Node * pParent) const563 CXFA_Node* CXFA_FFWidgetHandler::CreateValueNode(XFA_Element eValue,
564 CXFA_Node* pParent) const {
565 CXFA_Node* pValue = CreateCopyNode(XFA_Element::Value, pParent);
566 CreateCopyNode(eValue, pValue);
567 return pValue;
568 }
569
GetObjFactory() const570 CXFA_Document* CXFA_FFWidgetHandler::GetObjFactory() const {
571 return GetXFADoc();
572 }
573
GetXFADoc() const574 CXFA_Document* CXFA_FFWidgetHandler::GetXFADoc() const {
575 return m_pDocView->GetDoc()->GetXFADoc();
576 }
577