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/app/xfa_fffield.h"
8
9 #include "xfa/fwl/cfwl_edit.h"
10 #include "xfa/fwl/cfwl_eventmouse.h"
11 #include "xfa/fwl/cfwl_messagekey.h"
12 #include "xfa/fwl/cfwl_messagekillfocus.h"
13 #include "xfa/fwl/cfwl_messagemouse.h"
14 #include "xfa/fwl/cfwl_messagemousewheel.h"
15 #include "xfa/fwl/cfwl_messagesetfocus.h"
16 #include "xfa/fwl/cfwl_picturebox.h"
17 #include "xfa/fwl/cfwl_widgetmgr.h"
18 #include "xfa/fxfa/app/cxfa_textlayout.h"
19 #include "xfa/fxfa/app/xfa_fwltheme.h"
20 #include "xfa/fxfa/xfa_ffapp.h"
21 #include "xfa/fxfa/xfa_ffdoc.h"
22 #include "xfa/fxfa/xfa_ffdocview.h"
23 #include "xfa/fxfa/xfa_ffpageview.h"
24 #include "xfa/fxfa/xfa_ffwidget.h"
25 #include "xfa/fxgraphics/cfx_color.h"
26 #include "xfa/fxgraphics/cfx_path.h"
27
CXFA_FFField(CXFA_WidgetAcc * pDataAcc)28 CXFA_FFField::CXFA_FFField(CXFA_WidgetAcc* pDataAcc)
29 : CXFA_FFWidget(pDataAcc), m_pNormalWidget(nullptr) {}
30
~CXFA_FFField()31 CXFA_FFField::~CXFA_FFField() {
32 CXFA_FFField::UnloadWidget();
33 }
34
GetBBox(uint32_t dwStatus,bool bDrawFocus)35 CFX_RectF CXFA_FFField::GetBBox(uint32_t dwStatus, bool bDrawFocus) {
36 if (!bDrawFocus)
37 return CXFA_FFWidget::GetBBox(dwStatus);
38
39 XFA_Element type = m_pDataAcc->GetUIType();
40 if (type != XFA_Element::Button && type != XFA_Element::CheckButton &&
41 type != XFA_Element::ImageEdit && type != XFA_Element::Signature &&
42 type != XFA_Element::ChoiceList) {
43 return CFX_RectF();
44 }
45
46 CFX_RectF rtBox = m_rtUI;
47 GetRotateMatrix().TransformRect(rtBox);
48 return rtBox;
49 }
50
RenderWidget(CFX_Graphics * pGS,CFX_Matrix * pMatrix,uint32_t dwStatus)51 void CXFA_FFField::RenderWidget(CFX_Graphics* pGS,
52 CFX_Matrix* pMatrix,
53 uint32_t dwStatus) {
54 if (!IsMatchVisibleStatus(dwStatus))
55 return;
56
57 CFX_Matrix mtRotate = GetRotateMatrix();
58 if (pMatrix)
59 mtRotate.Concat(*pMatrix);
60
61 CXFA_FFWidget::RenderWidget(pGS, &mtRotate, dwStatus);
62 CXFA_Border borderUI = m_pDataAcc->GetUIBorder();
63 DrawBorder(pGS, borderUI, m_rtUI, &mtRotate);
64 RenderCaption(pGS, &mtRotate);
65 DrawHighlight(pGS, &mtRotate, dwStatus, false);
66
67 CFX_RectF rtWidget = m_pNormalWidget->GetWidgetRect();
68 CFX_Matrix mt(1, 0, 0, 1, rtWidget.left, rtWidget.top);
69 mt.Concat(mtRotate);
70 GetApp()->GetWidgetMgrDelegate()->OnDrawWidget(m_pNormalWidget, pGS, &mt);
71 }
DrawHighlight(CFX_Graphics * pGS,CFX_Matrix * pMatrix,uint32_t dwStatus,bool bEllipse)72 void CXFA_FFField::DrawHighlight(CFX_Graphics* pGS,
73 CFX_Matrix* pMatrix,
74 uint32_t dwStatus,
75 bool bEllipse) {
76 if (m_rtUI.IsEmpty() || !m_pDataAcc->GetDoc()->GetXFADoc()->IsInteractive()) {
77 return;
78 }
79 if ((dwStatus & XFA_WidgetStatus_Highlight) &&
80 m_pDataAcc->GetAccess() == XFA_ATTRIBUTEENUM_Open) {
81 CXFA_FFDoc* pDoc = GetDoc();
82 CFX_Color crHighlight(pDoc->GetDocEnvironment()->GetHighlightColor(pDoc));
83 pGS->SetFillColor(&crHighlight);
84 CFX_Path path;
85 if (bEllipse)
86 path.AddEllipse(m_rtUI);
87 else
88 path.AddRectangle(m_rtUI.left, m_rtUI.top, m_rtUI.width, m_rtUI.height);
89
90 pGS->FillPath(&path, FXFILL_WINDING, pMatrix);
91 }
92 }
DrawFocus(CFX_Graphics * pGS,CFX_Matrix * pMatrix)93 void CXFA_FFField::DrawFocus(CFX_Graphics* pGS, CFX_Matrix* pMatrix) {
94 if (m_dwStatus & XFA_WidgetStatus_Focused) {
95 CFX_Color cr(0xFF000000);
96 pGS->SetStrokeColor(&cr);
97 FX_FLOAT DashPattern[2] = {1, 1};
98 pGS->SetLineDash(0.0f, DashPattern, 2);
99 pGS->SetLineWidth(0, false);
100
101 CFX_Path path;
102 path.AddRectangle(m_rtUI.left, m_rtUI.top, m_rtUI.width, m_rtUI.height);
103 pGS->StrokePath(&path, pMatrix);
104 }
105 }
SetFWLThemeProvider()106 void CXFA_FFField::SetFWLThemeProvider() {
107 if (m_pNormalWidget)
108 m_pNormalWidget->SetThemeProvider(GetApp()->GetFWLTheme());
109 }
IsLoaded()110 bool CXFA_FFField::IsLoaded() {
111 return m_pNormalWidget && CXFA_FFWidget::IsLoaded();
112 }
LoadWidget()113 bool CXFA_FFField::LoadWidget() {
114 SetFWLThemeProvider();
115 m_pDataAcc->LoadCaption();
116 PerformLayout();
117 return true;
118 }
UnloadWidget()119 void CXFA_FFField::UnloadWidget() {
120 delete m_pNormalWidget;
121 m_pNormalWidget = nullptr;
122 }
SetEditScrollOffset()123 void CXFA_FFField::SetEditScrollOffset() {
124 XFA_Element eType = m_pDataAcc->GetUIType();
125 if (eType == XFA_Element::TextEdit || eType == XFA_Element::NumericEdit ||
126 eType == XFA_Element::PasswordEdit) {
127 FX_FLOAT fScrollOffset = 0;
128 CXFA_FFField* pPrev = static_cast<CXFA_FFField*>(GetPrev());
129 if (pPrev) {
130 CFX_RectF rtMargin = m_pDataAcc->GetUIMargin();
131 fScrollOffset = -rtMargin.top;
132 }
133 while (pPrev) {
134 fScrollOffset += pPrev->m_rtUI.height;
135 pPrev = static_cast<CXFA_FFField*>(pPrev->GetPrev());
136 }
137 ((CFWL_Edit*)m_pNormalWidget)->SetScrollOffset(fScrollOffset);
138 }
139 }
PerformLayout()140 bool CXFA_FFField::PerformLayout() {
141 CXFA_FFWidget::PerformLayout();
142 CapPlacement();
143 LayoutCaption();
144 SetFWLRect();
145 SetEditScrollOffset();
146 if (m_pNormalWidget) {
147 m_pNormalWidget->Update();
148 }
149 return true;
150 }
CapPlacement()151 void CXFA_FFField::CapPlacement() {
152 CFX_RectF rtWidget = GetRectWithoutRotate();
153 CXFA_Margin mgWidget = m_pDataAcc->GetMargin();
154 if (mgWidget) {
155 CXFA_LayoutItem* pItem = this;
156 FX_FLOAT fLeftInset = 0, fRightInset = 0, fTopInset = 0, fBottomInset = 0;
157 mgWidget.GetLeftInset(fLeftInset);
158 mgWidget.GetRightInset(fRightInset);
159 mgWidget.GetTopInset(fTopInset);
160 mgWidget.GetBottomInset(fBottomInset);
161 if (!pItem->GetPrev() && !pItem->GetNext()) {
162 rtWidget.Deflate(fLeftInset, fTopInset, fRightInset, fBottomInset);
163 } else {
164 if (!pItem->GetPrev())
165 rtWidget.Deflate(fLeftInset, fTopInset, fRightInset, 0);
166 else if (!pItem->GetNext())
167 rtWidget.Deflate(fLeftInset, 0, fRightInset, fBottomInset);
168 else
169 rtWidget.Deflate(fLeftInset, 0, fRightInset, 0);
170 }
171 }
172
173 XFA_ATTRIBUTEENUM iCapPlacement = XFA_ATTRIBUTEENUM_Unknown;
174 FX_FLOAT fCapReserve = 0;
175 CXFA_Caption caption = m_pDataAcc->GetCaption();
176 if (caption && caption.GetPresence() != XFA_ATTRIBUTEENUM_Hidden) {
177 iCapPlacement = (XFA_ATTRIBUTEENUM)caption.GetPlacementType();
178 if (iCapPlacement == XFA_ATTRIBUTEENUM_Top && GetPrev()) {
179 m_rtCaption.Reset();
180 } else if (iCapPlacement == XFA_ATTRIBUTEENUM_Bottom && GetNext()) {
181 m_rtCaption.Reset();
182 } else {
183 fCapReserve = caption.GetReserve();
184 CXFA_LayoutItem* pItem = this;
185 if (!pItem->GetPrev() && !pItem->GetNext()) {
186 m_rtCaption = rtWidget;
187 } else {
188 pItem = pItem->GetFirst();
189 m_rtCaption = pItem->GetRect(false);
190 pItem = pItem->GetNext();
191 while (pItem) {
192 m_rtCaption.height += pItem->GetRect(false).Height();
193 pItem = pItem->GetNext();
194 }
195 XFA_RectWidthoutMargin(m_rtCaption, mgWidget);
196 }
197 CXFA_TextLayout* pCapTextLayout = m_pDataAcc->GetCaptionTextLayout();
198 if (fCapReserve <= 0 && pCapTextLayout) {
199 CFX_SizeF size;
200 CFX_SizeF minSize;
201 CFX_SizeF maxSize;
202 pCapTextLayout->CalcSize(minSize, maxSize, size);
203 if (iCapPlacement == XFA_ATTRIBUTEENUM_Top ||
204 iCapPlacement == XFA_ATTRIBUTEENUM_Bottom) {
205 fCapReserve = size.height;
206 } else {
207 fCapReserve = size.width;
208 }
209 }
210 }
211 }
212 m_rtUI = rtWidget;
213 switch (iCapPlacement) {
214 case XFA_ATTRIBUTEENUM_Left: {
215 m_rtCaption.width = fCapReserve;
216 CapLeftRightPlacement(caption, rtWidget, iCapPlacement);
217 m_rtUI.width -= fCapReserve;
218 m_rtUI.left += fCapReserve;
219 } break;
220 case XFA_ATTRIBUTEENUM_Top: {
221 m_rtCaption.height = fCapReserve;
222 CapTopBottomPlacement(caption, rtWidget, iCapPlacement);
223 m_rtUI.top += fCapReserve;
224 m_rtUI.height -= fCapReserve;
225 } break;
226 case XFA_ATTRIBUTEENUM_Right: {
227 m_rtCaption.left = m_rtCaption.right() - fCapReserve;
228 m_rtCaption.width = fCapReserve;
229 CapLeftRightPlacement(caption, rtWidget, iCapPlacement);
230 m_rtUI.width -= fCapReserve;
231 } break;
232 case XFA_ATTRIBUTEENUM_Bottom: {
233 m_rtCaption.top = m_rtCaption.bottom() - fCapReserve;
234 m_rtCaption.height = fCapReserve;
235 CapTopBottomPlacement(caption, rtWidget, iCapPlacement);
236 m_rtUI.height -= fCapReserve;
237 } break;
238 case XFA_ATTRIBUTEENUM_Inline:
239 break;
240 default:
241 break;
242 }
243 CXFA_Border borderUI = m_pDataAcc->GetUIBorder();
244 if (borderUI) {
245 CXFA_Margin margin = borderUI.GetMargin();
246 if (margin) {
247 XFA_RectWidthoutMargin(m_rtUI, margin);
248 }
249 }
250 m_rtUI.Normalize();
251 }
CapTopBottomPlacement(CXFA_Caption caption,const CFX_RectF & rtWidget,int32_t iCapPlacement)252 void CXFA_FFField::CapTopBottomPlacement(CXFA_Caption caption,
253 const CFX_RectF& rtWidget,
254 int32_t iCapPlacement) {
255 CFX_RectF rtUIMargin = m_pDataAcc->GetUIMargin();
256 m_rtCaption.left += rtUIMargin.left;
257 if (CXFA_Margin mgCap = caption.GetMargin()) {
258 XFA_RectWidthoutMargin(m_rtCaption, mgCap);
259 if (m_rtCaption.height < 0) {
260 m_rtCaption.top += m_rtCaption.height;
261 }
262 }
263 FX_FLOAT fWidth = rtUIMargin.left + rtUIMargin.width;
264 FX_FLOAT fHeight = m_rtCaption.height + rtUIMargin.top + rtUIMargin.height;
265 if (fWidth > rtWidget.width) {
266 m_rtUI.width += fWidth - rtWidget.width;
267 }
268 if (fHeight == XFA_DEFAULTUI_HEIGHT && m_rtUI.height < XFA_MINUI_HEIGHT) {
269 m_rtUI.height = XFA_MINUI_HEIGHT;
270 m_rtCaption.top += rtUIMargin.top + rtUIMargin.height;
271 } else if (fHeight > rtWidget.height) {
272 m_rtUI.height += fHeight - rtWidget.height;
273 if (iCapPlacement == XFA_ATTRIBUTEENUM_Bottom) {
274 m_rtCaption.top += fHeight - rtWidget.height;
275 }
276 }
277 }
CapLeftRightPlacement(CXFA_Caption caption,const CFX_RectF & rtWidget,int32_t iCapPlacement)278 void CXFA_FFField::CapLeftRightPlacement(CXFA_Caption caption,
279 const CFX_RectF& rtWidget,
280 int32_t iCapPlacement) {
281 CFX_RectF rtUIMargin = m_pDataAcc->GetUIMargin();
282 m_rtCaption.top += rtUIMargin.top;
283 m_rtCaption.height -= rtUIMargin.top;
284 if (CXFA_Margin mgCap = caption.GetMargin()) {
285 XFA_RectWidthoutMargin(m_rtCaption, mgCap);
286 if (m_rtCaption.height < 0) {
287 m_rtCaption.top += m_rtCaption.height;
288 }
289 }
290 FX_FLOAT fWidth = m_rtCaption.width + rtUIMargin.left + rtUIMargin.width;
291 FX_FLOAT fHeight = rtUIMargin.top + rtUIMargin.height;
292 if (fWidth > rtWidget.width) {
293 m_rtUI.width += fWidth - rtWidget.width;
294 if (iCapPlacement == XFA_ATTRIBUTEENUM_Right) {
295 m_rtCaption.left += fWidth - rtWidget.width;
296 }
297 }
298 if (fHeight == XFA_DEFAULTUI_HEIGHT && m_rtUI.height < XFA_MINUI_HEIGHT) {
299 m_rtUI.height = XFA_MINUI_HEIGHT;
300 m_rtCaption.top += rtUIMargin.top + rtUIMargin.height;
301 } else if (fHeight > rtWidget.height) {
302 m_rtUI.height += fHeight - rtWidget.height;
303 }
304 }
UpdateFWL()305 void CXFA_FFField::UpdateFWL() {
306 if (m_pNormalWidget) {
307 m_pNormalWidget->Update();
308 }
309 }
UpdateUIProperty()310 uint32_t CXFA_FFField::UpdateUIProperty() {
311 CXFA_Node* pUiNode = m_pDataAcc->GetUIChild();
312 uint32_t dwStyle = 0;
313 if (pUiNode && pUiNode->GetElementType() == XFA_Element::DefaultUi) {
314 dwStyle = FWL_STYLEEXT_EDT_ReadOnly;
315 }
316 return dwStyle;
317 }
SetFWLRect()318 void CXFA_FFField::SetFWLRect() {
319 if (!m_pNormalWidget) {
320 return;
321 }
322 CFX_RectF rtUi = m_rtUI;
323 if (rtUi.width < 1.0)
324 rtUi.width = 1.0;
325 if (!m_pDataAcc->GetDoc()->GetXFADoc()->IsInteractive()) {
326 FX_FLOAT fFontSize = m_pDataAcc->GetFontSize();
327 if (rtUi.height < fFontSize) {
328 rtUi.height = fFontSize;
329 }
330 }
331 m_pNormalWidget->SetWidgetRect(rtUi);
332 }
OnMouseEnter()333 bool CXFA_FFField::OnMouseEnter() {
334 if (!m_pNormalWidget) {
335 return false;
336 }
337 CFWL_MessageMouse ms(nullptr, m_pNormalWidget);
338 ms.m_dwCmd = FWL_MouseCommand::Enter;
339 TranslateFWLMessage(&ms);
340 return true;
341 }
OnMouseExit()342 bool CXFA_FFField::OnMouseExit() {
343 if (!m_pNormalWidget) {
344 return false;
345 }
346 CFWL_MessageMouse ms(nullptr, m_pNormalWidget);
347 ms.m_dwCmd = FWL_MouseCommand::Leave;
348 TranslateFWLMessage(&ms);
349 return true;
350 }
351
FWLToClient(const CFX_PointF & point)352 CFX_PointF CXFA_FFField::FWLToClient(const CFX_PointF& point) {
353 return m_pNormalWidget ? point - m_pNormalWidget->GetWidgetRect().TopLeft()
354 : point;
355 }
356
OnLButtonDown(uint32_t dwFlags,const CFX_PointF & point)357 bool CXFA_FFField::OnLButtonDown(uint32_t dwFlags, const CFX_PointF& point) {
358 if (!m_pNormalWidget)
359 return false;
360 if (m_pDataAcc->GetAccess() != XFA_ATTRIBUTEENUM_Open ||
361 !m_pDataAcc->GetDoc()->GetXFADoc()->IsInteractive()) {
362 return false;
363 }
364 if (!PtInActiveRect(point))
365 return false;
366
367 SetButtonDown(true);
368 CFWL_MessageMouse ms(nullptr, m_pNormalWidget);
369 ms.m_dwCmd = FWL_MouseCommand::LeftButtonDown;
370 ms.m_dwFlags = dwFlags;
371 ms.m_pos = FWLToClient(point);
372 TranslateFWLMessage(&ms);
373 return true;
374 }
375
OnLButtonUp(uint32_t dwFlags,const CFX_PointF & point)376 bool CXFA_FFField::OnLButtonUp(uint32_t dwFlags, const CFX_PointF& point) {
377 if (!m_pNormalWidget)
378 return false;
379 if (!IsButtonDown())
380 return false;
381
382 SetButtonDown(false);
383 CFWL_MessageMouse ms(nullptr, m_pNormalWidget);
384 ms.m_dwCmd = FWL_MouseCommand::LeftButtonUp;
385 ms.m_dwFlags = dwFlags;
386 ms.m_pos = FWLToClient(point);
387 TranslateFWLMessage(&ms);
388 return true;
389 }
390
OnLButtonDblClk(uint32_t dwFlags,const CFX_PointF & point)391 bool CXFA_FFField::OnLButtonDblClk(uint32_t dwFlags, const CFX_PointF& point) {
392 if (!m_pNormalWidget)
393 return false;
394
395 CFWL_MessageMouse ms(nullptr, m_pNormalWidget);
396 ms.m_dwCmd = FWL_MouseCommand::LeftButtonDblClk;
397 ms.m_dwFlags = dwFlags;
398 ms.m_pos = FWLToClient(point);
399 TranslateFWLMessage(&ms);
400 return true;
401 }
402
OnMouseMove(uint32_t dwFlags,const CFX_PointF & point)403 bool CXFA_FFField::OnMouseMove(uint32_t dwFlags, const CFX_PointF& point) {
404 if (!m_pNormalWidget)
405 return false;
406
407 CFWL_MessageMouse ms(nullptr, m_pNormalWidget);
408 ms.m_dwCmd = FWL_MouseCommand::Move;
409 ms.m_dwFlags = dwFlags;
410 ms.m_pos = FWLToClient(point);
411 TranslateFWLMessage(&ms);
412 return true;
413 }
414
OnMouseWheel(uint32_t dwFlags,int16_t zDelta,const CFX_PointF & point)415 bool CXFA_FFField::OnMouseWheel(uint32_t dwFlags,
416 int16_t zDelta,
417 const CFX_PointF& point) {
418 if (!m_pNormalWidget)
419 return false;
420
421 CFWL_MessageMouseWheel ms(nullptr, m_pNormalWidget);
422 ms.m_dwFlags = dwFlags;
423 ms.m_pos = FWLToClient(point);
424 ms.m_delta = CFX_PointF(zDelta, 0);
425 TranslateFWLMessage(&ms);
426 return true;
427 }
428
OnRButtonDown(uint32_t dwFlags,const CFX_PointF & point)429 bool CXFA_FFField::OnRButtonDown(uint32_t dwFlags, const CFX_PointF& point) {
430 if (!m_pNormalWidget)
431 return false;
432 if (m_pDataAcc->GetAccess() != XFA_ATTRIBUTEENUM_Open ||
433 !m_pDataAcc->GetDoc()->GetXFADoc()->IsInteractive()) {
434 return false;
435 }
436 if (!PtInActiveRect(point))
437 return false;
438
439 SetButtonDown(true);
440
441 CFWL_MessageMouse ms(nullptr, m_pNormalWidget);
442 ms.m_dwCmd = FWL_MouseCommand::RightButtonDown;
443 ms.m_dwFlags = dwFlags;
444 ms.m_pos = FWLToClient(point);
445 TranslateFWLMessage(&ms);
446 return true;
447 }
448
OnRButtonUp(uint32_t dwFlags,const CFX_PointF & point)449 bool CXFA_FFField::OnRButtonUp(uint32_t dwFlags, const CFX_PointF& point) {
450 if (!m_pNormalWidget)
451 return false;
452 if (!IsButtonDown())
453 return false;
454
455 SetButtonDown(false);
456 CFWL_MessageMouse ms(nullptr, m_pNormalWidget);
457 ms.m_dwCmd = FWL_MouseCommand::RightButtonUp;
458 ms.m_dwFlags = dwFlags;
459 ms.m_pos = FWLToClient(point);
460 TranslateFWLMessage(&ms);
461 return true;
462 }
463
OnRButtonDblClk(uint32_t dwFlags,const CFX_PointF & point)464 bool CXFA_FFField::OnRButtonDblClk(uint32_t dwFlags, const CFX_PointF& point) {
465 if (!m_pNormalWidget)
466 return false;
467
468 CFWL_MessageMouse ms(nullptr, m_pNormalWidget);
469 ms.m_dwCmd = FWL_MouseCommand::RightButtonDblClk;
470 ms.m_dwFlags = dwFlags;
471 ms.m_pos = FWLToClient(point);
472 TranslateFWLMessage(&ms);
473 return true;
474 }
475
OnSetFocus(CXFA_FFWidget * pOldWidget)476 bool CXFA_FFField::OnSetFocus(CXFA_FFWidget* pOldWidget) {
477 CXFA_FFWidget::OnSetFocus(pOldWidget);
478 if (!m_pNormalWidget) {
479 return false;
480 }
481 CFWL_MessageSetFocus ms(nullptr, m_pNormalWidget);
482 TranslateFWLMessage(&ms);
483 m_dwStatus |= XFA_WidgetStatus_Focused;
484 AddInvalidateRect();
485 return true;
486 }
OnKillFocus(CXFA_FFWidget * pNewWidget)487 bool CXFA_FFField::OnKillFocus(CXFA_FFWidget* pNewWidget) {
488 if (!m_pNormalWidget) {
489 return CXFA_FFWidget::OnKillFocus(pNewWidget);
490 }
491 CFWL_MessageKillFocus ms(nullptr, m_pNormalWidget);
492 TranslateFWLMessage(&ms);
493 m_dwStatus &= ~XFA_WidgetStatus_Focused;
494 AddInvalidateRect();
495 CXFA_FFWidget::OnKillFocus(pNewWidget);
496 return true;
497 }
OnKeyDown(uint32_t dwKeyCode,uint32_t dwFlags)498 bool CXFA_FFField::OnKeyDown(uint32_t dwKeyCode, uint32_t dwFlags) {
499 if (!m_pNormalWidget || !m_pDataAcc->GetDoc()->GetXFADoc()->IsInteractive()) {
500 return false;
501 }
502 CFWL_MessageKey ms(nullptr, m_pNormalWidget);
503 ms.m_dwCmd = FWL_KeyCommand::KeyDown;
504 ms.m_dwFlags = dwFlags;
505 ms.m_dwKeyCode = dwKeyCode;
506 TranslateFWLMessage(&ms);
507 return true;
508 }
OnKeyUp(uint32_t dwKeyCode,uint32_t dwFlags)509 bool CXFA_FFField::OnKeyUp(uint32_t dwKeyCode, uint32_t dwFlags) {
510 if (!m_pNormalWidget || !m_pDataAcc->GetDoc()->GetXFADoc()->IsInteractive()) {
511 return false;
512 }
513 CFWL_MessageKey ms(nullptr, m_pNormalWidget);
514 ms.m_dwCmd = FWL_KeyCommand::KeyUp;
515 ms.m_dwFlags = dwFlags;
516 ms.m_dwKeyCode = dwKeyCode;
517 TranslateFWLMessage(&ms);
518 return true;
519 }
OnChar(uint32_t dwChar,uint32_t dwFlags)520 bool CXFA_FFField::OnChar(uint32_t dwChar, uint32_t dwFlags) {
521 if (!m_pDataAcc->GetDoc()->GetXFADoc()->IsInteractive()) {
522 return false;
523 }
524 if (dwChar == FWL_VKEY_Tab) {
525 return true;
526 }
527 if (!m_pNormalWidget) {
528 return false;
529 }
530 if (m_pDataAcc->GetAccess() != XFA_ATTRIBUTEENUM_Open) {
531 return false;
532 }
533 CFWL_MessageKey ms(nullptr, m_pNormalWidget);
534 ms.m_dwCmd = FWL_KeyCommand::Char;
535 ms.m_dwFlags = dwFlags;
536 ms.m_dwKeyCode = dwChar;
537 TranslateFWLMessage(&ms);
538 return true;
539 }
OnHitTest(const CFX_PointF & point)540 FWL_WidgetHit CXFA_FFField::OnHitTest(const CFX_PointF& point) {
541 if (m_pNormalWidget &&
542 m_pNormalWidget->HitTest(FWLToClient(point)) != FWL_WidgetHit::Unknown) {
543 return FWL_WidgetHit::Client;
544 }
545
546 if (!GetRectWithoutRotate().Contains(point))
547 return FWL_WidgetHit::Unknown;
548 if (m_rtCaption.Contains(point))
549 return FWL_WidgetHit::Titlebar;
550 return FWL_WidgetHit::Border;
551 }
552
OnSetCursor(const CFX_PointF & point)553 bool CXFA_FFField::OnSetCursor(const CFX_PointF& point) {
554 return true;
555 }
556
PtInActiveRect(const CFX_PointF & point)557 bool CXFA_FFField::PtInActiveRect(const CFX_PointF& point) {
558 return m_pNormalWidget && m_pNormalWidget->GetWidgetRect().Contains(point);
559 }
560
LayoutCaption()561 void CXFA_FFField::LayoutCaption() {
562 CXFA_TextLayout* pCapTextLayout = m_pDataAcc->GetCaptionTextLayout();
563 if (!pCapTextLayout)
564 return;
565
566 FX_FLOAT fHeight = 0;
567 pCapTextLayout->Layout(CFX_SizeF(m_rtCaption.width, m_rtCaption.height),
568 &fHeight);
569 if (m_rtCaption.height < fHeight)
570 m_rtCaption.height = fHeight;
571 }
572
RenderCaption(CFX_Graphics * pGS,CFX_Matrix * pMatrix)573 void CXFA_FFField::RenderCaption(CFX_Graphics* pGS, CFX_Matrix* pMatrix) {
574 CXFA_TextLayout* pCapTextLayout = m_pDataAcc->GetCaptionTextLayout();
575 if (!pCapTextLayout)
576 return;
577
578 CXFA_Caption caption = m_pDataAcc->GetCaption();
579 if (!caption || caption.GetPresence() != XFA_ATTRIBUTEENUM_Visible)
580 return;
581
582 if (!pCapTextLayout->IsLoaded())
583 pCapTextLayout->Layout(CFX_SizeF(m_rtCaption.width, m_rtCaption.height));
584
585 CFX_RectF rtClip = m_rtCaption;
586 rtClip.Intersect(GetRectWithoutRotate());
587 CFX_RenderDevice* pRenderDevice = pGS->GetRenderDevice();
588 CFX_Matrix mt(1, 0, 0, 1, m_rtCaption.left, m_rtCaption.top);
589 if (pMatrix) {
590 pMatrix->TransformRect(rtClip);
591 mt.Concat(*pMatrix);
592 }
593 pCapTextLayout->DrawString(pRenderDevice, mt, rtClip);
594 }
595
ProcessCommittedData()596 bool CXFA_FFField::ProcessCommittedData() {
597 if (m_pDataAcc->GetAccess() != XFA_ATTRIBUTEENUM_Open)
598 return false;
599 if (!IsDataChanged())
600 return false;
601 if (CalculateOverride() != 1)
602 return false;
603 if (!CommitData())
604 return false;
605
606 m_pDocView->SetChangeMark();
607 m_pDocView->AddValidateWidget(m_pDataAcc);
608 return true;
609 }
610
CalculateOverride()611 int32_t CXFA_FFField::CalculateOverride() {
612 CXFA_WidgetAcc* pAcc = m_pDataAcc->GetExclGroup();
613 if (!pAcc) {
614 return CalculateWidgetAcc(m_pDataAcc);
615 }
616 if (CalculateWidgetAcc(pAcc) == 0) {
617 return 0;
618 }
619 CXFA_Node* pNode = pAcc->GetExclGroupFirstMember();
620 if (!pNode) {
621 return 1;
622 }
623 CXFA_WidgetAcc* pWidgetAcc = nullptr;
624 while (pNode) {
625 pWidgetAcc = static_cast<CXFA_WidgetAcc*>(pNode->GetWidgetData());
626 if (!pWidgetAcc) {
627 return 1;
628 }
629 if (CalculateWidgetAcc(pWidgetAcc) == 0) {
630 return 0;
631 }
632 pNode = pWidgetAcc->GetExclGroupNextMember(pNode);
633 }
634 return 1;
635 }
CalculateWidgetAcc(CXFA_WidgetAcc * pAcc)636 int32_t CXFA_FFField::CalculateWidgetAcc(CXFA_WidgetAcc* pAcc) {
637 CXFA_Calculate calc = pAcc->GetCalculate();
638 if (!calc) {
639 return 1;
640 }
641 XFA_VERSION version = pAcc->GetDoc()->GetXFADoc()->GetCurVersionMode();
642 if (calc) {
643 int32_t iOverride = calc.GetOverride();
644 switch (iOverride) {
645 case XFA_ATTRIBUTEENUM_Error: {
646 if (version <= XFA_VERSION_204) {
647 return 1;
648 }
649 IXFA_AppProvider* pAppProvider = GetApp()->GetAppProvider();
650 if (pAppProvider) {
651 pAppProvider->MsgBox(L"You are not allowed to modify this field.",
652 L"Calculate Override", XFA_MBICON_Warning,
653 XFA_MB_OK);
654 }
655 }
656 return 0;
657 case XFA_ATTRIBUTEENUM_Warning: {
658 if (version <= XFA_VERSION_204) {
659 CXFA_Script script = calc.GetScript();
660 if (!script) {
661 return 1;
662 }
663 CFX_WideString wsExpression;
664 script.GetExpression(wsExpression);
665 if (wsExpression.IsEmpty()) {
666 return 1;
667 }
668 }
669 if (pAcc->GetNode()->IsUserInteractive())
670 return 1;
671
672 IXFA_AppProvider* pAppProvider = GetApp()->GetAppProvider();
673 if (pAppProvider) {
674 CFX_WideString wsMessage;
675 calc.GetMessageText(wsMessage);
676 if (!wsMessage.IsEmpty())
677 wsMessage += L"\r\n";
678 wsMessage += L"Are you sure you want to modify this field?";
679 if (pAppProvider->MsgBox(wsMessage, L"Calculate Override",
680 XFA_MBICON_Warning,
681 XFA_MB_YesNo) == XFA_IDYes) {
682 pAcc->GetNode()->SetFlag(XFA_NodeFlag_UserInteractive, false);
683 return 1;
684 }
685 }
686 return 0;
687 }
688 case XFA_ATTRIBUTEENUM_Ignore:
689 return 0;
690 case XFA_ATTRIBUTEENUM_Disabled:
691 pAcc->GetNode()->SetFlag(XFA_NodeFlag_UserInteractive, false);
692 default:
693 return 1;
694 }
695 }
696 return 1;
697 }
CommitData()698 bool CXFA_FFField::CommitData() {
699 return false;
700 }
IsDataChanged()701 bool CXFA_FFField::IsDataChanged() {
702 return false;
703 }
TranslateFWLMessage(CFWL_Message * pMessage)704 void CXFA_FFField::TranslateFWLMessage(CFWL_Message* pMessage) {
705 GetApp()->GetWidgetMgrDelegate()->OnProcessMessageToForm(pMessage);
706 }
OnProcessMessage(CFWL_Message * pMessage)707 void CXFA_FFField::OnProcessMessage(CFWL_Message* pMessage) {}
708
OnProcessEvent(CFWL_Event * pEvent)709 void CXFA_FFField::OnProcessEvent(CFWL_Event* pEvent) {
710 switch (pEvent->GetType()) {
711 case CFWL_Event::Type::Mouse: {
712 CFWL_EventMouse* event = (CFWL_EventMouse*)pEvent;
713 if (event->m_dwCmd == FWL_MouseCommand::Enter) {
714 CXFA_EventParam eParam;
715 eParam.m_eType = XFA_EVENT_MouseEnter;
716 eParam.m_pTarget = m_pDataAcc;
717 m_pDataAcc->ProcessEvent(XFA_ATTRIBUTEENUM_MouseEnter, &eParam);
718 } else if (event->m_dwCmd == FWL_MouseCommand::Leave) {
719 CXFA_EventParam eParam;
720 eParam.m_eType = XFA_EVENT_MouseExit;
721 eParam.m_pTarget = m_pDataAcc;
722 m_pDataAcc->ProcessEvent(XFA_ATTRIBUTEENUM_MouseExit, &eParam);
723 } else if (event->m_dwCmd == FWL_MouseCommand::LeftButtonDown) {
724 CXFA_EventParam eParam;
725 eParam.m_eType = XFA_EVENT_MouseDown;
726 eParam.m_pTarget = m_pDataAcc;
727 m_pDataAcc->ProcessEvent(XFA_ATTRIBUTEENUM_MouseDown, &eParam);
728 } else if (event->m_dwCmd == FWL_MouseCommand::LeftButtonUp) {
729 CXFA_EventParam eParam;
730 eParam.m_eType = XFA_EVENT_MouseUp;
731 eParam.m_pTarget = m_pDataAcc;
732 m_pDataAcc->ProcessEvent(XFA_ATTRIBUTEENUM_MouseUp, &eParam);
733 }
734 break;
735 }
736 case CFWL_Event::Type::Click: {
737 CXFA_EventParam eParam;
738 eParam.m_eType = XFA_EVENT_Click;
739 eParam.m_pTarget = m_pDataAcc;
740 m_pDataAcc->ProcessEvent(XFA_ATTRIBUTEENUM_Click, &eParam);
741 break;
742 }
743 default:
744 break;
745 }
746 }
747
OnDrawWidget(CFX_Graphics * pGraphics,const CFX_Matrix * pMatrix)748 void CXFA_FFField::OnDrawWidget(CFX_Graphics* pGraphics,
749 const CFX_Matrix* pMatrix) {}
750