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_ffwidget.h"
10 #include "xfa_fffield.h"
11 #include "xfa_ffpageview.h"
12 #include "xfa_ffapp.h"
13 #include "xfa_ffdoc.h"
14 #include "xfa_fwltheme.h"
15 #include "xfa_textlayout.h"
16 #include "xfa_ffdocview.h"
CXFA_FFField(CXFA_FFPageView * pPageView,CXFA_WidgetAcc * pDataAcc)17 CXFA_FFField::CXFA_FFField(CXFA_FFPageView* pPageView, CXFA_WidgetAcc* pDataAcc)
18 : CXFA_FFWidget(pPageView, pDataAcc), m_pNormalWidget(NULL) {
19 m_rtUI.Set(0, 0, 0, 0);
20 m_rtCaption.Set(0, 0, 0, 0);
21 }
~CXFA_FFField()22 CXFA_FFField::~CXFA_FFField() {
23 CXFA_FFField::UnloadWidget();
24 }
GetBBox(CFX_RectF & rtBox,FX_DWORD dwStatus,FX_BOOL bDrawFocus)25 FX_BOOL CXFA_FFField::GetBBox(CFX_RectF& rtBox,
26 FX_DWORD dwStatus,
27 FX_BOOL bDrawFocus) {
28 if (bDrawFocus) {
29 XFA_ELEMENT type = (XFA_ELEMENT)m_pDataAcc->GetUIType();
30 if (type == XFA_ELEMENT_Button || type == XFA_ELEMENT_CheckButton ||
31 type == XFA_ELEMENT_ImageEdit || type == XFA_ELEMENT_Signature ||
32 type == XFA_ELEMENT_ChoiceList) {
33 rtBox = m_rtUI;
34 CFX_Matrix mt;
35 GetRotateMatrix(mt);
36 mt.TransformRect(rtBox);
37 return TRUE;
38 }
39 return FALSE;
40 }
41 #ifndef _XFA_EMB
42 return CXFA_FFWidget::GetBBox(rtBox, dwStatus);
43 #endif
44 GetRectWithoutRotate(rtBox);
45 if (m_pNormalWidget) {
46 CFX_RectF rtWidget;
47 m_pNormalWidget->GetWidgetRect(rtWidget);
48 rtBox.Union(rtWidget);
49 }
50 CFX_Matrix mt;
51 GetRotateMatrix(mt);
52 mt.TransformRect(rtBox);
53 return TRUE;
54 }
RenderWidget(CFX_Graphics * pGS,CFX_Matrix * pMatrix,FX_DWORD dwStatus,int32_t iRotate)55 void CXFA_FFField::RenderWidget(CFX_Graphics* pGS,
56 CFX_Matrix* pMatrix,
57 FX_DWORD dwStatus,
58 int32_t iRotate) {
59 if (!IsMatchVisibleStatus(dwStatus)) {
60 return;
61 }
62 CFX_Matrix mtRotate;
63 GetRotateMatrix(mtRotate);
64 if (pMatrix) {
65 mtRotate.Concat(*pMatrix);
66 }
67 CXFA_FFWidget::RenderWidget(pGS, &mtRotate, dwStatus);
68 CXFA_Border borderUI = m_pDataAcc->GetUIBorder();
69 DrawBorder(pGS, borderUI, m_rtUI, &mtRotate);
70 RenderCaption(pGS, &mtRotate);
71 DrawHighlight(pGS, &mtRotate, dwStatus, FALSE);
72 CFX_RectF rtWidget;
73 m_pNormalWidget->GetWidgetRect(rtWidget);
74 CFX_Matrix mt;
75 mt.Set(1, 0, 0, 1, rtWidget.left, rtWidget.top);
76 mt.Concat(mtRotate);
77 GetApp()->GetWidgetMgrDelegate()->OnDrawWidget(m_pNormalWidget->GetWidget(),
78 pGS, &mt);
79 }
DrawHighlight(CFX_Graphics * pGS,CFX_Matrix * pMatrix,FX_DWORD dwStatus,FX_BOOL bEllipse)80 void CXFA_FFField::DrawHighlight(CFX_Graphics* pGS,
81 CFX_Matrix* pMatrix,
82 FX_DWORD dwStatus,
83 FX_BOOL bEllipse) {
84 if (m_rtUI.IsEmpty() || !m_pDataAcc->GetDoc()->GetXFADoc()->IsInteractive()) {
85 return;
86 }
87 if ((dwStatus & XFA_WIDGETSTATUS_Highlight) &&
88 m_pDataAcc->GetAccess() == XFA_ATTRIBUTEENUM_Open) {
89 CXFA_FFDoc* pDoc = GetDoc();
90 CFX_Color crHighlight(pDoc->GetDocProvider()->GetHighlightColor(pDoc));
91 pGS->SetFillColor(&crHighlight);
92 CFX_Path path;
93 path.Create();
94 if (bEllipse) {
95 path.AddEllipse(m_rtUI);
96 } else {
97 path.AddRectangle(m_rtUI.left, m_rtUI.top, m_rtUI.width, m_rtUI.height);
98 }
99 pGS->FillPath(&path, FXFILL_WINDING, pMatrix);
100 }
101 }
DrawFocus(CFX_Graphics * pGS,CFX_Matrix * pMatrix)102 void CXFA_FFField::DrawFocus(CFX_Graphics* pGS, CFX_Matrix* pMatrix) {
103 if (m_dwStatus & XFA_WIDGETSTATUS_Focused) {
104 CFX_Color cr(0xFF000000);
105 pGS->SetStrokeColor(&cr);
106 FX_FLOAT DashPattern[2] = {1, 1};
107 pGS->SetLineDash(0.0f, DashPattern, 2);
108 pGS->SetLineWidth(0, FALSE);
109 CFX_Path path;
110 path.Create();
111 path.AddRectangle(m_rtUI.left, m_rtUI.top, m_rtUI.width, m_rtUI.height);
112 pGS->StrokePath(&path, pMatrix);
113 }
114 }
SetFWLThemeProvider()115 void CXFA_FFField::SetFWLThemeProvider() {
116 if (m_pNormalWidget) {
117 m_pNormalWidget->m_pIface->SetThemeProvider(GetApp()->GetFWLTheme());
118 }
119 }
IsLoaded()120 FX_BOOL CXFA_FFField::IsLoaded() {
121 return m_pNormalWidget != NULL && CXFA_FFWidget::IsLoaded();
122 }
LoadWidget()123 FX_BOOL CXFA_FFField::LoadWidget() {
124 SetFWLThemeProvider();
125 m_pDataAcc->LoadCaption();
126 PerformLayout();
127 return TRUE;
128 }
UnloadWidget()129 void CXFA_FFField::UnloadWidget() {
130 delete m_pNormalWidget;
131 m_pNormalWidget = nullptr;
132 }
SetEditScrollOffset()133 void CXFA_FFField::SetEditScrollOffset() {
134 XFA_ELEMENT eType = m_pDataAcc->GetUIType();
135 if (eType == XFA_ELEMENT_TextEdit || eType == XFA_ELEMENT_NumericEdit ||
136 eType == XFA_ELEMENT_PasswordEdit) {
137 FX_FLOAT fScrollOffset = 0;
138 CXFA_FFField* pPrev = static_cast<CXFA_FFField*>(GetPrev());
139 if (pPrev) {
140 CFX_RectF rtMargin;
141 m_pDataAcc->GetUIMargin(rtMargin);
142 fScrollOffset = -rtMargin.top;
143 }
144 while (pPrev) {
145 fScrollOffset += pPrev->m_rtUI.height;
146 pPrev = static_cast<CXFA_FFField*>(pPrev->GetPrev());
147 }
148 ((CFWL_Edit*)m_pNormalWidget)->SetScrollOffset(fScrollOffset);
149 }
150 }
PerformLayout()151 FX_BOOL CXFA_FFField::PerformLayout() {
152 CXFA_FFWidget::PerformLayout();
153 CapPlacement();
154 LayoutCaption();
155 SetFWLRect();
156 SetEditScrollOffset();
157 if (m_pNormalWidget) {
158 m_pNormalWidget->Update();
159 }
160 return TRUE;
161 }
CapPlacement()162 void CXFA_FFField::CapPlacement() {
163 CFX_RectF rtWidget;
164 GetRectWithoutRotate(rtWidget);
165 CXFA_Margin mgWidget = m_pDataAcc->GetMargin();
166 if (mgWidget) {
167 CXFA_LayoutItem* pItem = this;
168 FX_FLOAT fLeftInset = 0, fRightInset = 0, fTopInset = 0, fBottomInset = 0;
169 mgWidget.GetLeftInset(fLeftInset);
170 mgWidget.GetRightInset(fRightInset);
171 mgWidget.GetTopInset(fTopInset);
172 mgWidget.GetBottomInset(fBottomInset);
173 if (pItem->GetPrev() == NULL && pItem->GetNext() == NULL) {
174 rtWidget.Deflate(fLeftInset, fTopInset, fRightInset, fBottomInset);
175 } else {
176 if (pItem->GetPrev() == NULL) {
177 rtWidget.Deflate(fLeftInset, fTopInset, fRightInset, 0);
178 } else if (pItem->GetNext() == NULL) {
179 rtWidget.Deflate(fLeftInset, 0, fRightInset, fBottomInset);
180 } else {
181 rtWidget.Deflate(fLeftInset, 0, fRightInset, 0);
182 }
183 }
184 }
185 XFA_ATTRIBUTEENUM iCapPlacement = XFA_ATTRIBUTEENUM_Unknown;
186 FX_FLOAT fCapReserve = 0;
187 CXFA_Caption caption = m_pDataAcc->GetCaption();
188 if (caption.IsExistInXML() &&
189 caption.GetPresence() != XFA_ATTRIBUTEENUM_Hidden) {
190 iCapPlacement = (XFA_ATTRIBUTEENUM)caption.GetPlacementType();
191 if (iCapPlacement == XFA_ATTRIBUTEENUM_Top && GetPrev()) {
192 m_rtCaption.Set(0, 0, 0, 0);
193 } else if (iCapPlacement == XFA_ATTRIBUTEENUM_Bottom && GetNext()) {
194 m_rtCaption.Set(0, 0, 0, 0);
195 } else {
196 fCapReserve = caption.GetReserve();
197 CXFA_LayoutItem* pItem = this;
198 if (pItem->GetPrev() == NULL && pItem->GetNext() == NULL) {
199 m_rtCaption.Set(rtWidget.left, rtWidget.top, rtWidget.width,
200 rtWidget.height);
201 } else {
202 pItem = pItem->GetFirst();
203 pItem->GetRect(m_rtCaption);
204 pItem = pItem->GetNext();
205 while (pItem) {
206 CFX_RectF rtRect;
207 pItem->GetRect(rtRect);
208 m_rtCaption.height += rtRect.Height();
209 pItem = pItem->GetNext();
210 }
211 XFA_RectWidthoutMargin(m_rtCaption, mgWidget);
212 }
213 CXFA_TextLayout* pCapTextLayout = m_pDataAcc->GetCaptionTextLayout();
214 if (fCapReserve <= 0 && pCapTextLayout) {
215 CFX_SizeF size;
216 size.Set(0, 0);
217 CFX_SizeF minSize;
218 minSize.Set(0, 0);
219 CFX_SizeF maxSize;
220 maxSize.Set(0, 0);
221 pCapTextLayout->CalcSize(minSize, maxSize, size);
222 if (iCapPlacement == XFA_ATTRIBUTEENUM_Top ||
223 iCapPlacement == XFA_ATTRIBUTEENUM_Bottom) {
224 fCapReserve = size.y;
225 } else {
226 fCapReserve = size.x;
227 }
228 }
229 }
230 }
231 m_rtUI = rtWidget;
232 switch (iCapPlacement) {
233 case XFA_ATTRIBUTEENUM_Left: {
234 m_rtCaption.width = fCapReserve;
235 CapLeftRightPlacement(caption, rtWidget, iCapPlacement);
236 m_rtUI.width -= fCapReserve;
237 m_rtUI.left += fCapReserve;
238 } break;
239 case XFA_ATTRIBUTEENUM_Top: {
240 m_rtCaption.height = fCapReserve;
241 CapTopBottomPlacement(caption, rtWidget, iCapPlacement);
242 m_rtUI.top += fCapReserve;
243 m_rtUI.height -= fCapReserve;
244 } break;
245 case XFA_ATTRIBUTEENUM_Right: {
246 m_rtCaption.left = m_rtCaption.right() - fCapReserve;
247 m_rtCaption.width = fCapReserve;
248 CapLeftRightPlacement(caption, rtWidget, iCapPlacement);
249 m_rtUI.width -= fCapReserve;
250 } break;
251 case XFA_ATTRIBUTEENUM_Bottom: {
252 m_rtCaption.top = m_rtCaption.bottom() - fCapReserve;
253 m_rtCaption.height = fCapReserve;
254 CapTopBottomPlacement(caption, rtWidget, iCapPlacement);
255 m_rtUI.height -= fCapReserve;
256 } break;
257 case XFA_ATTRIBUTEENUM_Inline:
258 break;
259 default:
260 break;
261 }
262 CXFA_Border borderUI = m_pDataAcc->GetUIBorder();
263 if (borderUI) {
264 CXFA_Margin margin = borderUI.GetMargin();
265 if (margin.IsExistInXML()) {
266 XFA_RectWidthoutMargin(m_rtUI, margin);
267 }
268 }
269 m_rtUI.Normalize();
270 }
CapTopBottomPlacement(CXFA_Caption caption,const CFX_RectF & rtWidget,int32_t iCapPlacement)271 void CXFA_FFField::CapTopBottomPlacement(CXFA_Caption caption,
272 const CFX_RectF& rtWidget,
273 int32_t iCapPlacement) {
274 CFX_RectF rtUIMargin;
275 m_pDataAcc->GetUIMargin(rtUIMargin);
276 m_rtCaption.left += rtUIMargin.left;
277 if (CXFA_Margin mgCap = caption.GetMargin()) {
278 XFA_RectWidthoutMargin(m_rtCaption, mgCap);
279 if (m_rtCaption.height < 0) {
280 m_rtCaption.top += m_rtCaption.height;
281 }
282 }
283 FX_FLOAT fWidth = rtUIMargin.left + rtUIMargin.width;
284 FX_FLOAT fHeight = m_rtCaption.height + rtUIMargin.top + rtUIMargin.height;
285 if (fWidth > rtWidget.width) {
286 m_rtUI.width += fWidth - rtWidget.width;
287 }
288 if (fHeight == XFA_DEFAULTUI_HEIGHT && m_rtUI.height < XFA_MINUI_HEIGHT) {
289 m_rtUI.height = XFA_MINUI_HEIGHT;
290 m_rtCaption.top += rtUIMargin.top + rtUIMargin.height;
291 } else if (fHeight > rtWidget.height) {
292 m_rtUI.height += fHeight - rtWidget.height;
293 if (iCapPlacement == XFA_ATTRIBUTEENUM_Bottom) {
294 m_rtCaption.top += fHeight - rtWidget.height;
295 }
296 }
297 }
CapLeftRightPlacement(CXFA_Caption caption,const CFX_RectF & rtWidget,int32_t iCapPlacement)298 void CXFA_FFField::CapLeftRightPlacement(CXFA_Caption caption,
299 const CFX_RectF& rtWidget,
300 int32_t iCapPlacement) {
301 CFX_RectF rtUIMargin;
302 m_pDataAcc->GetUIMargin(rtUIMargin);
303 m_rtCaption.top += rtUIMargin.top;
304 m_rtCaption.height -= rtUIMargin.top;
305 if (CXFA_Margin mgCap = caption.GetMargin()) {
306 XFA_RectWidthoutMargin(m_rtCaption, mgCap);
307 if (m_rtCaption.height < 0) {
308 m_rtCaption.top += m_rtCaption.height;
309 }
310 }
311 FX_FLOAT fWidth = m_rtCaption.width + rtUIMargin.left + rtUIMargin.width;
312 FX_FLOAT fHeight = rtUIMargin.top + rtUIMargin.height;
313 if (fWidth > rtWidget.width) {
314 m_rtUI.width += fWidth - rtWidget.width;
315 if (iCapPlacement == XFA_ATTRIBUTEENUM_Right) {
316 m_rtCaption.left += fWidth - rtWidget.width;
317 }
318 }
319 if (fHeight == XFA_DEFAULTUI_HEIGHT && m_rtUI.height < XFA_MINUI_HEIGHT) {
320 m_rtUI.height = XFA_MINUI_HEIGHT;
321 m_rtCaption.top += rtUIMargin.top + rtUIMargin.height;
322 } else if (fHeight > rtWidget.height) {
323 m_rtUI.height += fHeight - rtWidget.height;
324 }
325 }
UpdateFWL()326 void CXFA_FFField::UpdateFWL() {
327 if (m_pNormalWidget) {
328 m_pNormalWidget->Update();
329 }
330 }
UpdateUIProperty()331 FX_DWORD CXFA_FFField::UpdateUIProperty() {
332 CXFA_Node* pUiNode = m_pDataAcc->GetUIChild();
333 FX_DWORD dwStyle = 0;
334 if (pUiNode && pUiNode->GetClassID() == XFA_ELEMENT_DefaultUi) {
335 dwStyle = FWL_STYLEEXT_EDT_ReadOnly;
336 }
337 return dwStyle;
338 }
SetFWLRect()339 void CXFA_FFField::SetFWLRect() {
340 if (!m_pNormalWidget) {
341 return;
342 }
343 CFX_RectF rtUi = m_rtUI;
344 if (rtUi.width < 1.0) {
345 FXSYS_assert(rtUi.width < 1.0);
346 rtUi.width = 1.0;
347 }
348 if (!m_pDataAcc->GetDoc()->GetXFADoc()->IsInteractive()) {
349 FX_FLOAT fFontSize = m_pDataAcc->GetFontSize();
350 if (rtUi.height < fFontSize) {
351 rtUi.height = fFontSize;
352 }
353 }
354 m_pNormalWidget->SetWidgetRect(rtUi);
355 }
OnMouseEnter()356 FX_BOOL CXFA_FFField::OnMouseEnter() {
357 if (!m_pNormalWidget) {
358 return FALSE;
359 }
360 CFWL_MsgMouse ms;
361 ms.m_dwCmd = FWL_MSGMOUSECMD_MouseEnter;
362 ms.m_pDstTarget = m_pNormalWidget->m_pIface;
363 ms.m_pSrcTarget = NULL;
364 TranslateFWLMessage(&ms);
365 return TRUE;
366 }
OnMouseExit()367 FX_BOOL CXFA_FFField::OnMouseExit() {
368 if (!m_pNormalWidget) {
369 return FALSE;
370 }
371 CFWL_MsgMouse ms;
372 ms.m_dwCmd = FWL_MSGMOUSECMD_MouseLeave;
373 ms.m_pDstTarget = m_pNormalWidget->m_pIface;
374 TranslateFWLMessage(&ms);
375 return TRUE;
376 }
FWLToClient(FX_FLOAT & fx,FX_FLOAT & fy)377 void CXFA_FFField::FWLToClient(FX_FLOAT& fx, FX_FLOAT& fy) {
378 if (!m_pNormalWidget) {
379 return;
380 }
381 CFX_RectF rtWidget;
382 m_pNormalWidget->GetWidgetRect(rtWidget);
383 fx -= rtWidget.left;
384 fy -= rtWidget.top;
385 }
OnLButtonDown(FX_DWORD dwFlags,FX_FLOAT fx,FX_FLOAT fy)386 FX_BOOL CXFA_FFField::OnLButtonDown(FX_DWORD dwFlags,
387 FX_FLOAT fx,
388 FX_FLOAT fy) {
389 if (!m_pNormalWidget) {
390 return FALSE;
391 }
392 if (m_pDataAcc->GetAccess() != XFA_ATTRIBUTEENUM_Open ||
393 !m_pDataAcc->GetDoc()->GetXFADoc()->IsInteractive()) {
394 return FALSE;
395 }
396 if (!PtInActiveRect(fx, fy)) {
397 return FALSE;
398 }
399 SetButtonDown(TRUE);
400 CFWL_MsgMouse ms;
401 ms.m_dwCmd = FWL_MSGMOUSECMD_LButtonDown;
402 ms.m_dwFlags = dwFlags;
403 ms.m_fx = fx;
404 ms.m_fy = fy;
405 FWLToClient(ms.m_fx, ms.m_fy);
406 ms.m_pDstTarget = m_pNormalWidget->m_pIface;
407 TranslateFWLMessage(&ms);
408 return TRUE;
409 }
OnLButtonUp(FX_DWORD dwFlags,FX_FLOAT fx,FX_FLOAT fy)410 FX_BOOL CXFA_FFField::OnLButtonUp(FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy) {
411 if (!m_pNormalWidget) {
412 return FALSE;
413 }
414 if (!IsButtonDown()) {
415 return FALSE;
416 }
417 SetButtonDown(FALSE);
418 CFWL_MsgMouse ms;
419 ms.m_dwCmd = FWL_MSGMOUSECMD_LButtonUp;
420 ms.m_dwFlags = dwFlags;
421 ms.m_fx = fx;
422 ms.m_fy = fy;
423 FWLToClient(ms.m_fx, ms.m_fy);
424 ms.m_pDstTarget = m_pNormalWidget->m_pIface;
425 TranslateFWLMessage(&ms);
426 return TRUE;
427 }
OnLButtonDblClk(FX_DWORD dwFlags,FX_FLOAT fx,FX_FLOAT fy)428 FX_BOOL CXFA_FFField::OnLButtonDblClk(FX_DWORD dwFlags,
429 FX_FLOAT fx,
430 FX_FLOAT fy) {
431 if (!m_pNormalWidget) {
432 return FALSE;
433 }
434 CFWL_MsgMouse ms;
435 ms.m_dwCmd = FWL_MSGMOUSECMD_LButtonDblClk;
436 ms.m_dwFlags = dwFlags;
437 ms.m_fx = fx;
438 ms.m_fy = fy;
439 FWLToClient(ms.m_fx, ms.m_fy);
440 ms.m_pDstTarget = m_pNormalWidget->m_pIface;
441 TranslateFWLMessage(&ms);
442 return TRUE;
443 }
OnMouseMove(FX_DWORD dwFlags,FX_FLOAT fx,FX_FLOAT fy)444 FX_BOOL CXFA_FFField::OnMouseMove(FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy) {
445 if (!m_pNormalWidget) {
446 return FALSE;
447 }
448 CFWL_MsgMouse ms;
449 ms.m_dwCmd = FWL_MSGMOUSECMD_MouseMove;
450 ms.m_dwFlags = dwFlags;
451 ms.m_fx = fx;
452 ms.m_fy = fy;
453 FWLToClient(ms.m_fx, ms.m_fy);
454 ms.m_pDstTarget = m_pNormalWidget->m_pIface;
455 TranslateFWLMessage(&ms);
456 return TRUE;
457 }
OnMouseWheel(FX_DWORD dwFlags,int16_t zDelta,FX_FLOAT fx,FX_FLOAT fy)458 FX_BOOL CXFA_FFField::OnMouseWheel(FX_DWORD dwFlags,
459 int16_t zDelta,
460 FX_FLOAT fx,
461 FX_FLOAT fy) {
462 return FALSE;
463 if (!m_pNormalWidget) {
464 return FALSE;
465 }
466 CFWL_MsgMouseWheel ms;
467 ms.m_dwFlags = dwFlags;
468 ms.m_fx = fx;
469 ms.m_fy = fy;
470 FWLToClient(ms.m_fx, ms.m_fy);
471 ms.m_fDeltaX = zDelta;
472 ms.m_fDeltaY = 0;
473 ms.m_pDstTarget = m_pNormalWidget->m_pIface;
474 TranslateFWLMessage(&ms);
475 return TRUE;
476 }
OnRButtonDown(FX_DWORD dwFlags,FX_FLOAT fx,FX_FLOAT fy)477 FX_BOOL CXFA_FFField::OnRButtonDown(FX_DWORD dwFlags,
478 FX_FLOAT fx,
479 FX_FLOAT fy) {
480 if (!m_pNormalWidget) {
481 return FALSE;
482 }
483 if (m_pDataAcc->GetAccess() != XFA_ATTRIBUTEENUM_Open ||
484 !m_pDataAcc->GetDoc()->GetXFADoc()->IsInteractive()) {
485 return FALSE;
486 }
487 if (!PtInActiveRect(fx, fy)) {
488 return FALSE;
489 }
490 SetButtonDown(TRUE);
491 CFWL_MsgMouse ms;
492 ms.m_dwCmd = FWL_MSGMOUSECMD_RButtonDown;
493 ms.m_dwFlags = dwFlags;
494 ms.m_fx = fx;
495 ms.m_fy = fy;
496 FWLToClient(ms.m_fx, ms.m_fy);
497 ms.m_pDstTarget = m_pNormalWidget->m_pIface;
498 TranslateFWLMessage(&ms);
499 return TRUE;
500 }
OnRButtonUp(FX_DWORD dwFlags,FX_FLOAT fx,FX_FLOAT fy)501 FX_BOOL CXFA_FFField::OnRButtonUp(FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy) {
502 if (!m_pNormalWidget) {
503 return FALSE;
504 }
505 if (!IsButtonDown()) {
506 return FALSE;
507 }
508 SetButtonDown(FALSE);
509 CFWL_MsgMouse ms;
510 ms.m_dwCmd = FWL_MSGMOUSECMD_RButtonUp;
511 ms.m_dwFlags = dwFlags;
512 ms.m_fx = fx;
513 ms.m_fy = fy;
514 FWLToClient(ms.m_fx, ms.m_fy);
515 ms.m_pDstTarget = m_pNormalWidget->m_pIface;
516 TranslateFWLMessage(&ms);
517 return TRUE;
518 }
OnRButtonDblClk(FX_DWORD dwFlags,FX_FLOAT fx,FX_FLOAT fy)519 FX_BOOL CXFA_FFField::OnRButtonDblClk(FX_DWORD dwFlags,
520 FX_FLOAT fx,
521 FX_FLOAT fy) {
522 if (!m_pNormalWidget) {
523 return FALSE;
524 }
525 CFWL_MsgMouse ms;
526 ms.m_dwCmd = FWL_MSGMOUSECMD_RButtonDblClk;
527 ms.m_dwFlags = dwFlags;
528 ms.m_fx = fx;
529 ms.m_fy = fy;
530 FWLToClient(ms.m_fx, ms.m_fy);
531 ms.m_pDstTarget = m_pNormalWidget->m_pIface;
532 TranslateFWLMessage(&ms);
533 return TRUE;
534 }
535
OnSetFocus(CXFA_FFWidget * pOldWidget)536 FX_BOOL CXFA_FFField::OnSetFocus(CXFA_FFWidget* pOldWidget) {
537 CXFA_FFWidget::OnSetFocus(pOldWidget);
538 if (!m_pNormalWidget) {
539 return FALSE;
540 }
541 CFWL_MsgSetFocus ms;
542 ms.m_pDstTarget = m_pNormalWidget->m_pIface;
543 ms.m_pSrcTarget = NULL;
544 TranslateFWLMessage(&ms);
545 m_dwStatus |= XFA_WIDGETSTATUS_Focused;
546 AddInvalidateRect();
547 return TRUE;
548 }
OnKillFocus(CXFA_FFWidget * pNewWidget)549 FX_BOOL CXFA_FFField::OnKillFocus(CXFA_FFWidget* pNewWidget) {
550 if (!m_pNormalWidget) {
551 return CXFA_FFWidget::OnKillFocus(pNewWidget);
552 }
553 CFWL_MsgKillFocus ms;
554 ms.m_pDstTarget = m_pNormalWidget->m_pIface;
555 ms.m_pSrcTarget = NULL;
556 TranslateFWLMessage(&ms);
557 m_dwStatus &= ~XFA_WIDGETSTATUS_Focused;
558 AddInvalidateRect();
559 CXFA_FFWidget::OnKillFocus(pNewWidget);
560 return TRUE;
561 }
OnKeyDown(FX_DWORD dwKeyCode,FX_DWORD dwFlags)562 FX_BOOL CXFA_FFField::OnKeyDown(FX_DWORD dwKeyCode, FX_DWORD dwFlags) {
563 if (!m_pNormalWidget || !m_pDataAcc->GetDoc()->GetXFADoc()->IsInteractive()) {
564 return FALSE;
565 }
566 CFWL_MsgKey ms;
567 ms.m_dwCmd = FWL_MSGKEYCMD_KeyDown;
568 ms.m_dwFlags = dwFlags;
569 ms.m_dwKeyCode = dwKeyCode;
570 ms.m_pDstTarget = m_pNormalWidget->m_pIface;
571 ms.m_pSrcTarget = NULL;
572 TranslateFWLMessage(&ms);
573 return TRUE;
574 }
OnKeyUp(FX_DWORD dwKeyCode,FX_DWORD dwFlags)575 FX_BOOL CXFA_FFField::OnKeyUp(FX_DWORD dwKeyCode, FX_DWORD dwFlags) {
576 if (!m_pNormalWidget || !m_pDataAcc->GetDoc()->GetXFADoc()->IsInteractive()) {
577 return FALSE;
578 }
579 CFWL_MsgKey ms;
580 ms.m_dwCmd = FWL_MSGKEYCMD_KeyUp;
581 ms.m_dwFlags = dwFlags;
582 ms.m_dwKeyCode = dwKeyCode;
583 ms.m_pDstTarget = m_pNormalWidget->m_pIface;
584 ms.m_pSrcTarget = NULL;
585 TranslateFWLMessage(&ms);
586 return TRUE;
587 }
OnChar(FX_DWORD dwChar,FX_DWORD dwFlags)588 FX_BOOL CXFA_FFField::OnChar(FX_DWORD dwChar, FX_DWORD dwFlags) {
589 if (!m_pDataAcc->GetDoc()->GetXFADoc()->IsInteractive()) {
590 return FALSE;
591 }
592 if (dwChar == FWL_VKEY_Tab) {
593 return TRUE;
594 }
595 if (!m_pNormalWidget) {
596 return FALSE;
597 }
598 if (m_pDataAcc->GetAccess() != XFA_ATTRIBUTEENUM_Open) {
599 return FALSE;
600 }
601 CFWL_MsgKey ms;
602 ms.m_dwCmd = FWL_MSGKEYCMD_Char;
603 ms.m_dwFlags = dwFlags;
604 ms.m_dwKeyCode = dwChar;
605 ms.m_pDstTarget = m_pNormalWidget->m_pIface;
606 ms.m_pSrcTarget = NULL;
607 TranslateFWLMessage(&ms);
608 return TRUE;
609 }
OnHitTest(FX_FLOAT fx,FX_FLOAT fy)610 FX_DWORD CXFA_FFField::OnHitTest(FX_FLOAT fx, FX_FLOAT fy) {
611 if (m_pNormalWidget) {
612 FX_FLOAT ffx = fx, ffy = fy;
613 FWLToClient(ffx, ffy);
614 FX_DWORD dwWidgetHit = m_pNormalWidget->HitTest(ffx, ffy);
615 if (dwWidgetHit != FWL_WGTHITTEST_Unknown) {
616 return FWL_WGTHITTEST_Client;
617 }
618 }
619 CFX_RectF rtBox;
620 GetRectWithoutRotate(rtBox);
621 if (!rtBox.Contains(fx, fy)) {
622 return FWL_WGTHITTEST_Unknown;
623 }
624 if (m_rtCaption.Contains(fx, fy)) {
625 return FWL_WGTHITTEST_Titlebar;
626 }
627 return FWL_WGTHITTEST_Border;
628 }
OnSetCursor(FX_FLOAT fx,FX_FLOAT fy)629 FX_BOOL CXFA_FFField::OnSetCursor(FX_FLOAT fx, FX_FLOAT fy) {
630 return TRUE;
631 }
PtInActiveRect(FX_FLOAT fx,FX_FLOAT fy)632 FX_BOOL CXFA_FFField::PtInActiveRect(FX_FLOAT fx, FX_FLOAT fy) {
633 if (!m_pNormalWidget) {
634 return FALSE;
635 }
636 CFX_RectF rtWidget;
637 m_pNormalWidget->GetWidgetRect(rtWidget);
638 if (rtWidget.Contains(fx, fy)) {
639 return TRUE;
640 }
641 return FALSE;
642 }
LayoutCaption()643 void CXFA_FFField::LayoutCaption() {
644 CXFA_TextLayout* pCapTextLayout = m_pDataAcc->GetCaptionTextLayout();
645 if (!pCapTextLayout) {
646 return;
647 }
648 CFX_SizeF size;
649 size.Set(m_rtCaption.width, m_rtCaption.height);
650 FX_FLOAT fHeight = 0;
651 pCapTextLayout->Layout(size, &fHeight);
652 if (m_rtCaption.height < fHeight) {
653 m_rtCaption.height = fHeight;
654 }
655 }
RenderCaption(CFX_Graphics * pGS,CFX_Matrix * pMatrix)656 void CXFA_FFField::RenderCaption(CFX_Graphics* pGS, CFX_Matrix* pMatrix) {
657 CXFA_TextLayout* pCapTextLayout = m_pDataAcc->GetCaptionTextLayout();
658 if (!pCapTextLayout) {
659 return;
660 }
661 CXFA_Caption caption = m_pDataAcc->GetCaption();
662 if (caption.IsExistInXML() &&
663 caption.GetPresence() == XFA_ATTRIBUTEENUM_Visible) {
664 if (!pCapTextLayout->IsLoaded()) {
665 CFX_SizeF size;
666 size.Set(m_rtCaption.width, m_rtCaption.height);
667 pCapTextLayout->Layout(size);
668 }
669 CFX_RectF rtWidget;
670 GetRectWithoutRotate(rtWidget);
671 CFX_RectF rtClip = m_rtCaption;
672 rtClip.Intersect(rtWidget);
673 CFX_RenderDevice* pRenderDevice = pGS->GetRenderDevice();
674 CFX_Matrix mt;
675 mt.Set(1, 0, 0, 1, m_rtCaption.left, m_rtCaption.top);
676 if (pMatrix) {
677 pMatrix->TransformRect(rtClip);
678 mt.Concat(*pMatrix);
679 }
680 pCapTextLayout->DrawString(pRenderDevice, mt, rtClip);
681 }
682 }
ProcessCommittedData()683 FX_BOOL CXFA_FFField::ProcessCommittedData() {
684 if (m_pDataAcc->GetAccess() != XFA_ATTRIBUTEENUM_Open) {
685 return FALSE;
686 }
687 if (!IsDataChanged()) {
688 return FALSE;
689 }
690 if (CalculateOverride() != 1) {
691 return FALSE;
692 }
693 if (!CommitData()) {
694 return FALSE;
695 }
696 m_pDocView->SetChangeMark();
697 m_pDocView->AddValidateWidget(m_pDataAcc);
698 return TRUE;
699 }
CalculateOverride()700 int32_t CXFA_FFField::CalculateOverride() {
701 CXFA_WidgetAcc* pAcc = m_pDataAcc->GetExclGroup();
702 if (!pAcc) {
703 return CalculateWidgetAcc(m_pDataAcc);
704 }
705 if (CalculateWidgetAcc(pAcc) == 0) {
706 return 0;
707 }
708 CXFA_Node* pNode = pAcc->GetExclGroupFirstMember();
709 if (!pNode) {
710 return 1;
711 }
712 CXFA_WidgetAcc* pWidgetAcc = NULL;
713 while (pNode) {
714 pWidgetAcc = (CXFA_WidgetAcc*)pNode->GetWidgetData();
715 if (!pWidgetAcc) {
716 return 1;
717 }
718 if (CalculateWidgetAcc(pWidgetAcc) == 0) {
719 return 0;
720 }
721 pNode = pWidgetAcc->GetExclGroupNextMember(pNode);
722 }
723 return 1;
724 }
CalculateWidgetAcc(CXFA_WidgetAcc * pAcc)725 int32_t CXFA_FFField::CalculateWidgetAcc(CXFA_WidgetAcc* pAcc) {
726 CXFA_Calculate calc = pAcc->GetCalculate();
727 if (!calc) {
728 return 1;
729 }
730 XFA_VERSION version = pAcc->GetDoc()->GetXFADoc()->GetCurVersionMode();
731 if (calc) {
732 int32_t iOverride = calc.GetOverride();
733 switch (iOverride) {
734 case XFA_ATTRIBUTEENUM_Error: {
735 if (version <= XFA_VERSION_204) {
736 return 1;
737 }
738 IXFA_AppProvider* pAppProvider = GetApp()->GetAppProvider();
739 if (pAppProvider) {
740 CFX_WideString wsMessage;
741 CFX_WideString wsWarning;
742 pAppProvider->LoadString(XFA_IDS_NotModifyField, wsWarning);
743 wsMessage += wsWarning;
744 CFX_WideString wsTitle;
745 pAppProvider->LoadString(XFA_IDS_CalcOverride, wsTitle);
746 pAppProvider->MsgBox(wsMessage, wsTitle, XFA_MBICON_Warning,
747 XFA_MB_OK);
748 }
749 }
750 return 0;
751 case XFA_ATTRIBUTEENUM_Warning: {
752 if (version <= XFA_VERSION_204) {
753 CXFA_Script script = calc.GetScript();
754 if (!script) {
755 return 1;
756 }
757 CFX_WideString wsExpression;
758 script.GetExpression(wsExpression);
759 if (wsExpression.IsEmpty()) {
760 return 1;
761 }
762 }
763 if (pAcc->GetNode()->HasFlag(XFA_NODEFLAG_UserInteractive)) {
764 return 1;
765 }
766 IXFA_AppProvider* pAppProvider = GetApp()->GetAppProvider();
767 if (pAppProvider) {
768 CFX_WideString wsMessage;
769 calc.GetMessageText(wsMessage);
770 if (!wsMessage.IsEmpty()) {
771 wsMessage += L"\r\n";
772 }
773 CFX_WideString wsWarning;
774 pAppProvider->LoadString(XFA_IDS_ModifyField, wsWarning);
775 wsMessage += wsWarning;
776 CFX_WideString wsTitle;
777 pAppProvider->LoadString(XFA_IDS_CalcOverride, wsTitle);
778 if (pAppProvider->MsgBox(wsMessage, wsTitle, XFA_MBICON_Warning,
779 XFA_MB_YesNo) == XFA_IDYes) {
780 pAcc->GetNode()->SetFlag(XFA_NODEFLAG_UserInteractive, TRUE, FALSE);
781 return 1;
782 }
783 }
784 return 0;
785 }
786 case XFA_ATTRIBUTEENUM_Ignore:
787 return 0;
788 case XFA_ATTRIBUTEENUM_Disabled:
789 pAcc->GetNode()->SetFlag(XFA_NODEFLAG_UserInteractive, TRUE, FALSE);
790 default:
791 return 1;
792 }
793 }
794 return 1;
795 }
CommitData()796 FX_BOOL CXFA_FFField::CommitData() {
797 return FALSE;
798 }
IsDataChanged()799 FX_BOOL CXFA_FFField::IsDataChanged() {
800 return FALSE;
801 }
TranslateFWLMessage(CFWL_Message * pMessage)802 void CXFA_FFField::TranslateFWLMessage(CFWL_Message* pMessage) {
803 GetApp()->GetWidgetMgrDelegate()->OnProcessMessageToForm(pMessage);
804 }
OnProcessMessage(CFWL_Message * pMessage)805 int32_t CXFA_FFField::OnProcessMessage(CFWL_Message* pMessage) {
806 return FWL_ERR_Succeeded;
807 }
OnProcessEvent(CFWL_Event * pEvent)808 FWL_ERR CXFA_FFField::OnProcessEvent(CFWL_Event* pEvent) {
809 FX_DWORD dwEventID = pEvent->GetClassID();
810 switch (dwEventID) {
811 case FWL_EVTHASH_Mouse: {
812 CFWL_EvtMouse* event = (CFWL_EvtMouse*)pEvent;
813 if (event->m_dwCmd == FWL_MSGMOUSECMD_MouseEnter) {
814 CXFA_EventParam eParam;
815 eParam.m_eType = XFA_EVENT_MouseEnter;
816 eParam.m_pTarget = m_pDataAcc;
817 m_pDataAcc->ProcessEvent(XFA_ATTRIBUTEENUM_MouseEnter, &eParam);
818 } else if (event->m_dwCmd == FWL_MSGMOUSECMD_MouseLeave) {
819 CXFA_EventParam eParam;
820 eParam.m_eType = XFA_EVENT_MouseExit;
821 eParam.m_pTarget = m_pDataAcc;
822 m_pDataAcc->ProcessEvent(XFA_ATTRIBUTEENUM_MouseExit, &eParam);
823 } else if (event->m_dwCmd == FWL_MSGMOUSECMD_LButtonDown) {
824 CXFA_EventParam eParam;
825 eParam.m_eType = XFA_EVENT_MouseDown;
826 eParam.m_pTarget = m_pDataAcc;
827 m_pDataAcc->ProcessEvent(XFA_ATTRIBUTEENUM_MouseDown, &eParam);
828 } else if (event->m_dwCmd == FWL_MSGMOUSECMD_LButtonUp) {
829 CXFA_EventParam eParam;
830 eParam.m_eType = XFA_EVENT_MouseUp;
831 eParam.m_pTarget = m_pDataAcc;
832 m_pDataAcc->ProcessEvent(XFA_ATTRIBUTEENUM_MouseUp, &eParam);
833 }
834 break;
835 }
836 case FWL_EVTHASH_Click: {
837 CXFA_EventParam eParam;
838 eParam.m_eType = XFA_EVENT_Click;
839 eParam.m_pTarget = m_pDataAcc;
840 m_pDataAcc->ProcessEvent(XFA_ATTRIBUTEENUM_Click, &eParam);
841 break;
842 }
843 default: {}
844 }
845 return FWL_ERR_Succeeded;
846 }
OnDrawWidget(CFX_Graphics * pGraphics,const CFX_Matrix * pMatrix)847 FWL_ERR CXFA_FFField::OnDrawWidget(CFX_Graphics* pGraphics,
848 const CFX_Matrix* pMatrix) {
849 return FWL_ERR_Succeeded;
850 }
851