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