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