• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2014 PDFium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6 
7 #include "xfa/fxfa/app/xfa_fftextedit.h"
8 
9 #include <vector>
10 
11 #include "xfa/fwl/cfwl_datetimepicker.h"
12 #include "xfa/fwl/cfwl_edit.h"
13 #include "xfa/fwl/cfwl_eventcheckword.h"
14 #include "xfa/fwl/cfwl_eventselectchanged.h"
15 #include "xfa/fwl/cfwl_eventtextchanged.h"
16 #include "xfa/fwl/cfwl_eventvalidate.h"
17 #include "xfa/fwl/cfwl_messagekillfocus.h"
18 #include "xfa/fwl/cfwl_messagemouse.h"
19 #include "xfa/fwl/cfwl_messagesetfocus.h"
20 #include "xfa/fwl/cfwl_notedriver.h"
21 #include "xfa/fxfa/app/xfa_fffield.h"
22 #include "xfa/fxfa/app/xfa_fwladapter.h"
23 #include "xfa/fxfa/cxfa_eventparam.h"
24 #include "xfa/fxfa/parser/xfa_localevalue.h"
25 #include "xfa/fxfa/xfa_ffapp.h"
26 #include "xfa/fxfa/xfa_ffdoc.h"
27 #include "xfa/fxfa/xfa_ffdocview.h"
28 #include "xfa/fxfa/xfa_ffpageview.h"
29 #include "xfa/fxfa/xfa_ffwidget.h"
30 
CXFA_FFTextEdit(CXFA_WidgetAcc * pDataAcc)31 CXFA_FFTextEdit::CXFA_FFTextEdit(CXFA_WidgetAcc* pDataAcc)
32     : CXFA_FFField(pDataAcc), m_pOldDelegate(nullptr) {}
33 
~CXFA_FFTextEdit()34 CXFA_FFTextEdit::~CXFA_FFTextEdit() {
35   if (m_pNormalWidget) {
36     CFWL_NoteDriver* pNoteDriver =
37         m_pNormalWidget->GetOwnerApp()->GetNoteDriver();
38     pNoteDriver->UnregisterEventTarget(m_pNormalWidget);
39   }
40 }
41 
LoadWidget()42 bool CXFA_FFTextEdit::LoadWidget() {
43   CFWL_Edit* pFWLEdit = new CFWL_Edit(
44       GetFWLApp(), pdfium::MakeUnique<CFWL_WidgetProperties>(), nullptr);
45   m_pNormalWidget = pFWLEdit;
46   m_pNormalWidget->SetLayoutItem(this);
47 
48   CFWL_NoteDriver* pNoteDriver =
49       m_pNormalWidget->GetOwnerApp()->GetNoteDriver();
50   pNoteDriver->RegisterEventTarget(m_pNormalWidget, m_pNormalWidget);
51 
52   m_pOldDelegate = m_pNormalWidget->GetDelegate();
53   m_pNormalWidget->SetDelegate(this);
54   m_pNormalWidget->LockUpdate();
55 
56   UpdateWidgetProperty();
57   CFX_WideString wsText;
58   m_pDataAcc->GetValue(wsText, XFA_VALUEPICTURE_Display);
59   pFWLEdit->SetText(wsText);
60   m_pNormalWidget->UnlockUpdate();
61   return CXFA_FFField::LoadWidget();
62 }
UpdateWidgetProperty()63 void CXFA_FFTextEdit::UpdateWidgetProperty() {
64   CFWL_Edit* pWidget = (CFWL_Edit*)m_pNormalWidget;
65   if (!pWidget) {
66     return;
67   }
68   uint32_t dwStyle = 0;
69   uint32_t dwExtendedStyle = FWL_STYLEEXT_EDT_ShowScrollbarFocus |
70                              FWL_STYLEEXT_EDT_OuterScrollbar |
71                              FWL_STYLEEXT_EDT_LastLineHeight;
72   dwExtendedStyle |= UpdateUIProperty();
73   if (m_pDataAcc->IsMultiLine()) {
74     dwExtendedStyle |= FWL_STYLEEXT_EDT_MultiLine | FWL_STYLEEXT_EDT_WantReturn;
75     if (m_pDataAcc->GetVerticalScrollPolicy() != XFA_ATTRIBUTEENUM_Off) {
76       dwStyle |= FWL_WGTSTYLE_VScroll;
77       dwExtendedStyle |= FWL_STYLEEXT_EDT_AutoVScroll;
78     }
79   } else if (m_pDataAcc->GetHorizontalScrollPolicy() != XFA_ATTRIBUTEENUM_Off) {
80     dwExtendedStyle |= FWL_STYLEEXT_EDT_AutoHScroll;
81   }
82   if (m_pDataAcc->GetAccess() != XFA_ATTRIBUTEENUM_Open ||
83       !m_pDataAcc->GetDoc()->GetXFADoc()->IsInteractive()) {
84     dwExtendedStyle |= FWL_STYLEEXT_EDT_ReadOnly;
85     dwExtendedStyle |= FWL_STYLEEXT_EDT_MultiLine;
86   }
87   XFA_Element eType = XFA_Element::Unknown;
88   int32_t iMaxChars = m_pDataAcc->GetMaxChars(eType);
89   if (eType == XFA_Element::ExData) {
90     iMaxChars = 0;
91   }
92   int32_t iNumCells = m_pDataAcc->GetNumberOfCells();
93   if (iNumCells == 0) {
94     dwExtendedStyle |= FWL_STYLEEXT_EDT_CombText;
95     pWidget->SetLimit(iMaxChars > 0 ? iMaxChars : 1);
96   } else if (iNumCells > 0) {
97     dwExtendedStyle |= FWL_STYLEEXT_EDT_CombText;
98     pWidget->SetLimit(iNumCells);
99   } else {
100     pWidget->SetLimit(iMaxChars);
101   }
102   dwExtendedStyle |= GetAlignment();
103   m_pNormalWidget->ModifyStyles(dwStyle, 0xFFFFFFFF);
104   m_pNormalWidget->ModifyStylesEx(dwExtendedStyle, 0xFFFFFFFF);
105 }
106 
OnLButtonDown(uint32_t dwFlags,const CFX_PointF & point)107 bool CXFA_FFTextEdit::OnLButtonDown(uint32_t dwFlags, const CFX_PointF& point) {
108   if (!PtInActiveRect(point))
109     return false;
110   if (!IsFocused()) {
111     m_dwStatus |= XFA_WidgetStatus_Focused;
112     UpdateFWLData();
113     AddInvalidateRect();
114   }
115 
116   SetButtonDown(true);
117   CFWL_MessageMouse ms(nullptr, m_pNormalWidget);
118   ms.m_dwCmd = FWL_MouseCommand::LeftButtonDown;
119   ms.m_dwFlags = dwFlags;
120   ms.m_pos = FWLToClient(point);
121   TranslateFWLMessage(&ms);
122   return true;
123 }
124 
OnRButtonDown(uint32_t dwFlags,const CFX_PointF & point)125 bool CXFA_FFTextEdit::OnRButtonDown(uint32_t dwFlags, const CFX_PointF& point) {
126   if (m_pDataAcc->GetAccess() != XFA_ATTRIBUTEENUM_Open)
127     return false;
128   if (!PtInActiveRect(point))
129     return false;
130   if (!IsFocused()) {
131     m_dwStatus |= XFA_WidgetStatus_Focused;
132     UpdateFWLData();
133     AddInvalidateRect();
134   }
135 
136   SetButtonDown(true);
137   CFWL_MessageMouse ms(nullptr, nullptr);
138   ms.m_dwCmd = FWL_MouseCommand::RightButtonDown;
139   ms.m_dwFlags = dwFlags;
140   ms.m_pos = FWLToClient(point);
141   TranslateFWLMessage(&ms);
142   return true;
143 }
144 
OnRButtonUp(uint32_t dwFlags,const CFX_PointF & point)145 bool CXFA_FFTextEdit::OnRButtonUp(uint32_t dwFlags, const CFX_PointF& point) {
146   if (!CXFA_FFField::OnRButtonUp(dwFlags, point))
147     return false;
148 
149   GetDoc()->GetDocEnvironment()->PopupMenu(this, point);
150   return true;
151 }
152 
OnSetFocus(CXFA_FFWidget * pOldWidget)153 bool CXFA_FFTextEdit::OnSetFocus(CXFA_FFWidget* pOldWidget) {
154   m_dwStatus &= ~XFA_WidgetStatus_TextEditValueChanged;
155   if (!IsFocused()) {
156     m_dwStatus |= XFA_WidgetStatus_Focused;
157     UpdateFWLData();
158     AddInvalidateRect();
159   }
160   CXFA_FFWidget::OnSetFocus(pOldWidget);
161   CFWL_MessageSetFocus ms(nullptr, m_pNormalWidget);
162   TranslateFWLMessage(&ms);
163   return true;
164 }
OnKillFocus(CXFA_FFWidget * pNewWidget)165 bool CXFA_FFTextEdit::OnKillFocus(CXFA_FFWidget* pNewWidget) {
166   CFWL_MessageKillFocus ms(nullptr, m_pNormalWidget);
167   TranslateFWLMessage(&ms);
168   m_dwStatus &= ~XFA_WidgetStatus_Focused;
169   SetEditScrollOffset();
170   ProcessCommittedData();
171   UpdateFWLData();
172   AddInvalidateRect();
173   CXFA_FFWidget::OnKillFocus(pNewWidget);
174   m_dwStatus &= ~XFA_WidgetStatus_TextEditValueChanged;
175   return true;
176 }
CommitData()177 bool CXFA_FFTextEdit::CommitData() {
178   CFX_WideString wsText = static_cast<CFWL_Edit*>(m_pNormalWidget)->GetText();
179   if (m_pDataAcc->SetValue(wsText, XFA_VALUEPICTURE_Edit)) {
180     m_pDataAcc->UpdateUIDisplay(this);
181     return true;
182   }
183   ValidateNumberField(wsText);
184   return false;
185 }
ValidateNumberField(const CFX_WideString & wsText)186 void CXFA_FFTextEdit::ValidateNumberField(const CFX_WideString& wsText) {
187   CXFA_WidgetAcc* pAcc = GetDataAcc();
188   if (pAcc && pAcc->GetUIType() == XFA_Element::NumericEdit) {
189     IXFA_AppProvider* pAppProvider = GetApp()->GetAppProvider();
190     if (pAppProvider) {
191       CFX_WideString wsSomField;
192       pAcc->GetNode()->GetSOMExpression(wsSomField);
193 
194       CFX_WideString wsMessage;
195       wsMessage.Format(L"%s can not contain %s", wsText.c_str(),
196                        wsSomField.c_str());
197       pAppProvider->MsgBox(wsMessage, pAppProvider->GetAppTitle(),
198                            XFA_MBICON_Error, XFA_MB_OK);
199     }
200   }
201 }
IsDataChanged()202 bool CXFA_FFTextEdit::IsDataChanged() {
203   return (m_dwStatus & XFA_WidgetStatus_TextEditValueChanged) != 0;
204 }
GetAlignment()205 uint32_t CXFA_FFTextEdit::GetAlignment() {
206   uint32_t dwExtendedStyle = 0;
207   if (CXFA_Para para = m_pDataAcc->GetPara()) {
208     int32_t iHorz = para.GetHorizontalAlign();
209     switch (iHorz) {
210       case XFA_ATTRIBUTEENUM_Center:
211         dwExtendedStyle |= FWL_STYLEEXT_EDT_HCenter;
212         break;
213       case XFA_ATTRIBUTEENUM_Justify:
214         dwExtendedStyle |= FWL_STYLEEXT_EDT_Justified;
215         break;
216       case XFA_ATTRIBUTEENUM_JustifyAll:
217         break;
218       case XFA_ATTRIBUTEENUM_Radix:
219         break;
220       case XFA_ATTRIBUTEENUM_Right:
221         dwExtendedStyle |= FWL_STYLEEXT_EDT_HFar;
222         break;
223       default:
224         dwExtendedStyle |= FWL_STYLEEXT_EDT_HNear;
225         break;
226     }
227     int32_t iVert = para.GetVerticalAlign();
228     switch (iVert) {
229       case XFA_ATTRIBUTEENUM_Middle:
230         dwExtendedStyle |= FWL_STYLEEXT_EDT_VCenter;
231         break;
232       case XFA_ATTRIBUTEENUM_Bottom:
233         dwExtendedStyle |= FWL_STYLEEXT_EDT_VFar;
234         break;
235       default:
236         dwExtendedStyle |= FWL_STYLEEXT_EDT_VNear;
237         break;
238     }
239   }
240   return dwExtendedStyle;
241 }
UpdateFWLData()242 bool CXFA_FFTextEdit::UpdateFWLData() {
243   if (!m_pNormalWidget) {
244     return false;
245   }
246   XFA_VALUEPICTURE eType = XFA_VALUEPICTURE_Display;
247   if (IsFocused()) {
248     eType = XFA_VALUEPICTURE_Edit;
249   }
250   bool bUpdate = false;
251   if (m_pDataAcc->GetUIType() == XFA_Element::TextEdit &&
252       m_pDataAcc->GetNumberOfCells() < 0) {
253     XFA_Element elementType = XFA_Element::Unknown;
254     int32_t iMaxChars = m_pDataAcc->GetMaxChars(elementType);
255     if (elementType == XFA_Element::ExData) {
256       iMaxChars = eType == XFA_VALUEPICTURE_Edit ? iMaxChars : 0;
257     }
258     if (((CFWL_Edit*)m_pNormalWidget)->GetLimit() != iMaxChars) {
259       ((CFWL_Edit*)m_pNormalWidget)->SetLimit(iMaxChars);
260       bUpdate = true;
261     }
262   }
263   if (m_pDataAcc->GetUIType() == XFA_Element::Barcode) {
264     int32_t nDataLen = 0;
265     if (eType == XFA_VALUEPICTURE_Edit)
266       m_pDataAcc->GetBarcodeAttribute_DataLength(nDataLen);
267     static_cast<CFWL_Edit*>(m_pNormalWidget)->SetLimit(nDataLen);
268     bUpdate = true;
269   }
270   CFX_WideString wsText;
271   m_pDataAcc->GetValue(wsText, eType);
272   CFX_WideString wsOldText =
273       static_cast<CFWL_Edit*>(m_pNormalWidget)->GetText();
274   if (wsText != wsOldText || (eType == XFA_VALUEPICTURE_Edit && bUpdate)) {
275     ((CFWL_Edit*)m_pNormalWidget)->SetText(wsText);
276     bUpdate = true;
277   }
278   if (bUpdate) {
279     m_pNormalWidget->Update();
280   }
281   return true;
282 }
OnTextChanged(CFWL_Widget * pWidget,const CFX_WideString & wsChanged,const CFX_WideString & wsPrevText)283 void CXFA_FFTextEdit::OnTextChanged(CFWL_Widget* pWidget,
284                                     const CFX_WideString& wsChanged,
285                                     const CFX_WideString& wsPrevText) {
286   m_dwStatus |= XFA_WidgetStatus_TextEditValueChanged;
287   CXFA_EventParam eParam;
288   eParam.m_eType = XFA_EVENT_Change;
289   eParam.m_wsChange = wsChanged;
290   eParam.m_pTarget = m_pDataAcc;
291   eParam.m_wsPrevText = wsPrevText;
292   CFWL_Edit* pEdit = ((CFWL_Edit*)m_pNormalWidget);
293   if (m_pDataAcc->GetUIType() == XFA_Element::DateTimeEdit) {
294     CFWL_DateTimePicker* pDateTime = (CFWL_DateTimePicker*)pEdit;
295     eParam.m_wsNewText = pDateTime->GetEditText();
296     int32_t iSels = pDateTime->CountSelRanges();
297     if (iSels) {
298       eParam.m_iSelEnd = pDateTime->GetSelRange(0, &eParam.m_iSelStart);
299     }
300   } else {
301     eParam.m_wsNewText = pEdit->GetText();
302     int32_t iSels = pEdit->CountSelRanges();
303     if (iSels) {
304       eParam.m_iSelEnd = pEdit->GetSelRange(0, &eParam.m_iSelStart);
305     }
306   }
307   m_pDataAcc->ProcessEvent(XFA_ATTRIBUTEENUM_Change, &eParam);
308 }
OnTextFull(CFWL_Widget * pWidget)309 void CXFA_FFTextEdit::OnTextFull(CFWL_Widget* pWidget) {
310   CXFA_EventParam eParam;
311   eParam.m_eType = XFA_EVENT_Full;
312   eParam.m_pTarget = m_pDataAcc;
313   m_pDataAcc->ProcessEvent(XFA_ATTRIBUTEENUM_Full, &eParam);
314 }
315 
CheckWord(const CFX_ByteStringC & sWord)316 bool CXFA_FFTextEdit::CheckWord(const CFX_ByteStringC& sWord) {
317   if (sWord.IsEmpty() || m_pDataAcc->GetUIType() != XFA_Element::TextEdit)
318     return true;
319   return false;
320 }
321 
OnProcessMessage(CFWL_Message * pMessage)322 void CXFA_FFTextEdit::OnProcessMessage(CFWL_Message* pMessage) {
323   m_pOldDelegate->OnProcessMessage(pMessage);
324 }
325 
OnProcessEvent(CFWL_Event * pEvent)326 void CXFA_FFTextEdit::OnProcessEvent(CFWL_Event* pEvent) {
327   CXFA_FFField::OnProcessEvent(pEvent);
328   switch (pEvent->GetType()) {
329     case CFWL_Event::Type::TextChanged: {
330       CFWL_EventTextChanged* event =
331           static_cast<CFWL_EventTextChanged*>(pEvent);
332       CFX_WideString wsChange;
333       OnTextChanged(m_pNormalWidget, wsChange, event->wsPrevText);
334       break;
335     }
336     case CFWL_Event::Type::TextFull: {
337       OnTextFull(m_pNormalWidget);
338       break;
339     }
340     case CFWL_Event::Type::CheckWord: {
341       CFX_WideString wstr(L"FWL_EVENT_DTP_SelectChanged");
342       CFWL_EventCheckWord* event = static_cast<CFWL_EventCheckWord*>(pEvent);
343       event->bCheckWord = CheckWord(event->bsWord.AsStringC());
344       break;
345     }
346     default:
347       break;
348   }
349   m_pOldDelegate->OnProcessEvent(pEvent);
350 }
351 
OnDrawWidget(CFX_Graphics * pGraphics,const CFX_Matrix * pMatrix)352 void CXFA_FFTextEdit::OnDrawWidget(CFX_Graphics* pGraphics,
353                                    const CFX_Matrix* pMatrix) {
354   m_pOldDelegate->OnDrawWidget(pGraphics, pMatrix);
355 }
356 
CXFA_FFNumericEdit(CXFA_WidgetAcc * pDataAcc)357 CXFA_FFNumericEdit::CXFA_FFNumericEdit(CXFA_WidgetAcc* pDataAcc)
358     : CXFA_FFTextEdit(pDataAcc) {}
359 
~CXFA_FFNumericEdit()360 CXFA_FFNumericEdit::~CXFA_FFNumericEdit() {}
361 
LoadWidget()362 bool CXFA_FFNumericEdit::LoadWidget() {
363   CFWL_Edit* pWidget = new CFWL_Edit(
364       GetFWLApp(), pdfium::MakeUnique<CFWL_WidgetProperties>(), nullptr);
365   m_pNormalWidget = pWidget;
366 
367   m_pNormalWidget->SetLayoutItem(this);
368   CFWL_NoteDriver* pNoteDriver =
369       m_pNormalWidget->GetOwnerApp()->GetNoteDriver();
370   pNoteDriver->RegisterEventTarget(m_pNormalWidget, m_pNormalWidget);
371 
372   m_pOldDelegate = m_pNormalWidget->GetDelegate();
373   m_pNormalWidget->SetDelegate(this);
374   m_pNormalWidget->LockUpdate();
375 
376   CFX_WideString wsText;
377   m_pDataAcc->GetValue(wsText, XFA_VALUEPICTURE_Display);
378   pWidget->SetText(wsText);
379   UpdateWidgetProperty();
380   m_pNormalWidget->UnlockUpdate();
381   return CXFA_FFField::LoadWidget();
382 }
UpdateWidgetProperty()383 void CXFA_FFNumericEdit::UpdateWidgetProperty() {
384   CFWL_Edit* pWidget = (CFWL_Edit*)m_pNormalWidget;
385   if (!pWidget) {
386     return;
387   }
388   uint32_t dwExtendedStyle =
389       FWL_STYLEEXT_EDT_ShowScrollbarFocus | FWL_STYLEEXT_EDT_OuterScrollbar |
390       FWL_STYLEEXT_EDT_Validate | FWL_STYLEEXT_EDT_Number |
391       FWL_STYLEEXT_EDT_LastLineHeight;
392   dwExtendedStyle |= UpdateUIProperty();
393   if (m_pDataAcc->GetHorizontalScrollPolicy() != XFA_ATTRIBUTEENUM_Off) {
394     dwExtendedStyle |= FWL_STYLEEXT_EDT_AutoHScroll;
395   }
396   int32_t iNumCells = m_pDataAcc->GetNumberOfCells();
397   if (iNumCells > 0) {
398     dwExtendedStyle |= FWL_STYLEEXT_EDT_CombText;
399     pWidget->SetLimit(iNumCells);
400   }
401   dwExtendedStyle |= GetAlignment();
402   if (m_pDataAcc->GetAccess() != XFA_ATTRIBUTEENUM_Open ||
403       !m_pDataAcc->GetDoc()->GetXFADoc()->IsInteractive()) {
404     dwExtendedStyle |= FWL_STYLEEXT_EDT_ReadOnly;
405   }
406   m_pNormalWidget->ModifyStylesEx(dwExtendedStyle, 0xFFFFFFFF);
407 }
408 
OnProcessEvent(CFWL_Event * pEvent)409 void CXFA_FFNumericEdit::OnProcessEvent(CFWL_Event* pEvent) {
410   if (pEvent->GetType() == CFWL_Event::Type::Validate) {
411     CFWL_EventValidate* event = static_cast<CFWL_EventValidate*>(pEvent);
412     event->bValidate = OnValidate(m_pNormalWidget, event->wsInsert);
413     return;
414   }
415   CXFA_FFTextEdit::OnProcessEvent(pEvent);
416 }
417 
OnValidate(CFWL_Widget * pWidget,CFX_WideString & wsText)418 bool CXFA_FFNumericEdit::OnValidate(CFWL_Widget* pWidget,
419                                     CFX_WideString& wsText) {
420   CFX_WideString wsPattern;
421   m_pDataAcc->GetPictureContent(wsPattern, XFA_VALUEPICTURE_Edit);
422   if (!wsPattern.IsEmpty()) {
423     return true;
424   }
425   int32_t iLeads = 0;
426   m_pDataAcc->GetLeadDigits(iLeads);
427   int32_t iFracs = 0;
428   m_pDataAcc->GetFracDigits(iFracs);
429   CFX_WideString wsFormat;
430   CXFA_LocaleValue widgetValue = XFA_GetLocaleValue(m_pDataAcc);
431   widgetValue.GetNumbericFormat(wsFormat, iLeads, iFracs);
432   return widgetValue.ValidateNumericTemp(wsText, wsFormat,
433                                          m_pDataAcc->GetLocal());
434 }
435 
CXFA_FFPasswordEdit(CXFA_WidgetAcc * pDataAcc)436 CXFA_FFPasswordEdit::CXFA_FFPasswordEdit(CXFA_WidgetAcc* pDataAcc)
437     : CXFA_FFTextEdit(pDataAcc) {}
438 
~CXFA_FFPasswordEdit()439 CXFA_FFPasswordEdit::~CXFA_FFPasswordEdit() {}
440 
LoadWidget()441 bool CXFA_FFPasswordEdit::LoadWidget() {
442   CFWL_Edit* pWidget = new CFWL_Edit(
443       GetFWLApp(), pdfium::MakeUnique<CFWL_WidgetProperties>(), nullptr);
444   m_pNormalWidget = pWidget;
445   m_pNormalWidget->SetLayoutItem(this);
446 
447   CFWL_NoteDriver* pNoteDriver =
448       m_pNormalWidget->GetOwnerApp()->GetNoteDriver();
449   pNoteDriver->RegisterEventTarget(m_pNormalWidget, m_pNormalWidget);
450 
451   m_pOldDelegate = m_pNormalWidget->GetDelegate();
452   m_pNormalWidget->SetDelegate(this);
453   m_pNormalWidget->LockUpdate();
454 
455   CFX_WideString wsText;
456   m_pDataAcc->GetValue(wsText, XFA_VALUEPICTURE_Display);
457   pWidget->SetText(wsText);
458   UpdateWidgetProperty();
459   m_pNormalWidget->UnlockUpdate();
460   return CXFA_FFField::LoadWidget();
461 }
UpdateWidgetProperty()462 void CXFA_FFPasswordEdit::UpdateWidgetProperty() {
463   CFWL_Edit* pWidget = (CFWL_Edit*)m_pNormalWidget;
464   if (!pWidget) {
465     return;
466   }
467   uint32_t dwExtendedStyle =
468       FWL_STYLEEXT_EDT_ShowScrollbarFocus | FWL_STYLEEXT_EDT_OuterScrollbar |
469       FWL_STYLEEXT_EDT_Password | FWL_STYLEEXT_EDT_LastLineHeight;
470   dwExtendedStyle |= UpdateUIProperty();
471   CFX_WideString wsPassWord;
472   m_pDataAcc->GetPasswordChar(wsPassWord);
473   if (!wsPassWord.IsEmpty()) {
474     pWidget->SetAliasChar(wsPassWord.GetAt(0));
475   }
476   if (m_pDataAcc->GetHorizontalScrollPolicy() != XFA_ATTRIBUTEENUM_Off) {
477     dwExtendedStyle |= FWL_STYLEEXT_EDT_AutoHScroll;
478   }
479   if (m_pDataAcc->GetAccess() != XFA_ATTRIBUTEENUM_Open ||
480       !m_pDataAcc->GetDoc()->GetXFADoc()->IsInteractive()) {
481     dwExtendedStyle |= FWL_STYLEEXT_EDT_ReadOnly;
482   }
483   dwExtendedStyle |= GetAlignment();
484   m_pNormalWidget->ModifyStylesEx(dwExtendedStyle, 0xFFFFFFFF);
485 }
CXFA_FFDateTimeEdit(CXFA_WidgetAcc * pDataAcc)486 CXFA_FFDateTimeEdit::CXFA_FFDateTimeEdit(CXFA_WidgetAcc* pDataAcc)
487     : CXFA_FFTextEdit(pDataAcc) {}
488 
~CXFA_FFDateTimeEdit()489 CXFA_FFDateTimeEdit::~CXFA_FFDateTimeEdit() {}
490 
GetBBox(uint32_t dwStatus,bool bDrawFocus)491 CFX_RectF CXFA_FFDateTimeEdit::GetBBox(uint32_t dwStatus, bool bDrawFocus) {
492   if (bDrawFocus)
493     return CFX_RectF();
494   return CXFA_FFWidget::GetBBox(dwStatus);
495 }
496 
PtInActiveRect(const CFX_PointF & point)497 bool CXFA_FFDateTimeEdit::PtInActiveRect(const CFX_PointF& point) {
498   return m_pNormalWidget &&
499          static_cast<CFWL_DateTimePicker*>(m_pNormalWidget)
500              ->GetBBox()
501              .Contains(point);
502 }
503 
LoadWidget()504 bool CXFA_FFDateTimeEdit::LoadWidget() {
505   CFWL_DateTimePicker* pWidget = new CFWL_DateTimePicker(GetFWLApp());
506   m_pNormalWidget = pWidget;
507   m_pNormalWidget->SetLayoutItem(this);
508   CFWL_NoteDriver* pNoteDriver =
509       m_pNormalWidget->GetOwnerApp()->GetNoteDriver();
510   pNoteDriver->RegisterEventTarget(m_pNormalWidget, m_pNormalWidget);
511 
512   m_pOldDelegate = m_pNormalWidget->GetDelegate();
513   m_pNormalWidget->SetDelegate(this);
514   m_pNormalWidget->LockUpdate();
515 
516   CFX_WideString wsText;
517   m_pDataAcc->GetValue(wsText, XFA_VALUEPICTURE_Display);
518   pWidget->SetEditText(wsText);
519   if (CXFA_Value value = m_pDataAcc->GetFormValue()) {
520     switch (value.GetChildValueClassID()) {
521       case XFA_Element::Date: {
522         if (!wsText.IsEmpty()) {
523           CXFA_LocaleValue lcValue = XFA_GetLocaleValue(m_pDataAcc);
524           CFX_Unitime date = lcValue.GetDate();
525           if ((FX_UNITIME)date != 0) {
526             pWidget->SetCurSel(date.GetYear(), date.GetMonth(), date.GetDay());
527           }
528         }
529       } break;
530       default:
531         break;
532     }
533   }
534   UpdateWidgetProperty();
535   m_pNormalWidget->UnlockUpdate();
536   return CXFA_FFField::LoadWidget();
537 }
UpdateWidgetProperty()538 void CXFA_FFDateTimeEdit::UpdateWidgetProperty() {
539   CFWL_DateTimePicker* pWidget = (CFWL_DateTimePicker*)m_pNormalWidget;
540   if (!pWidget) {
541     return;
542   }
543   uint32_t dwExtendedStyle = FWL_STYLEEXT_DTP_ShortDateFormat;
544   dwExtendedStyle |= UpdateUIProperty();
545   dwExtendedStyle |= GetAlignment();
546   m_pNormalWidget->ModifyStylesEx(dwExtendedStyle, 0xFFFFFFFF);
547   uint32_t dwEditStyles = FWL_STYLEEXT_EDT_LastLineHeight;
548   int32_t iNumCells = m_pDataAcc->GetNumberOfCells();
549   if (iNumCells > 0) {
550     dwEditStyles |= FWL_STYLEEXT_EDT_CombText;
551     pWidget->SetEditLimit(iNumCells);
552   }
553   if (m_pDataAcc->GetAccess() != XFA_ATTRIBUTEENUM_Open ||
554       !m_pDataAcc->GetDoc()->GetXFADoc()->IsInteractive()) {
555     dwEditStyles |= FWL_STYLEEXT_EDT_ReadOnly;
556   }
557   if (m_pDataAcc->GetHorizontalScrollPolicy() != XFA_ATTRIBUTEENUM_Off) {
558     dwEditStyles |= FWL_STYLEEXT_EDT_AutoHScroll;
559   }
560   pWidget->ModifyEditStylesEx(dwEditStyles, 0xFFFFFFFF);
561 }
GetAlignment()562 uint32_t CXFA_FFDateTimeEdit::GetAlignment() {
563   uint32_t dwExtendedStyle = 0;
564   if (CXFA_Para para = m_pDataAcc->GetPara()) {
565     int32_t iHorz = para.GetHorizontalAlign();
566     switch (iHorz) {
567       case XFA_ATTRIBUTEENUM_Center:
568         dwExtendedStyle |= FWL_STYLEEXT_DTP_EditHCenter;
569         break;
570       case XFA_ATTRIBUTEENUM_Justify:
571         dwExtendedStyle |= FWL_STYLEEXT_DTP_EditJustified;
572         break;
573       case XFA_ATTRIBUTEENUM_JustifyAll:
574         break;
575       case XFA_ATTRIBUTEENUM_Radix:
576         break;
577       case XFA_ATTRIBUTEENUM_Right:
578         dwExtendedStyle |= FWL_STYLEEXT_DTP_EditHFar;
579         break;
580       default:
581         dwExtendedStyle |= FWL_STYLEEXT_DTP_EditHNear;
582         break;
583     }
584     int32_t iVert = para.GetVerticalAlign();
585     switch (iVert) {
586       case XFA_ATTRIBUTEENUM_Middle:
587         dwExtendedStyle |= FWL_STYLEEXT_DTP_EditVCenter;
588         break;
589       case XFA_ATTRIBUTEENUM_Bottom:
590         dwExtendedStyle |= FWL_STYLEEXT_DTP_EditVFar;
591         break;
592       default:
593         dwExtendedStyle |= FWL_STYLEEXT_DTP_EditVNear;
594         break;
595     }
596   }
597   return dwExtendedStyle;
598 }
CommitData()599 bool CXFA_FFDateTimeEdit::CommitData() {
600   CFX_WideString wsText =
601       static_cast<CFWL_DateTimePicker*>(m_pNormalWidget)->GetEditText();
602   if (m_pDataAcc->SetValue(wsText, XFA_VALUEPICTURE_Edit)) {
603     m_pDataAcc->UpdateUIDisplay(this);
604     return true;
605   }
606   return false;
607 }
UpdateFWLData()608 bool CXFA_FFDateTimeEdit::UpdateFWLData() {
609   if (!m_pNormalWidget) {
610     return false;
611   }
612   XFA_VALUEPICTURE eType = XFA_VALUEPICTURE_Display;
613   if (IsFocused()) {
614     eType = XFA_VALUEPICTURE_Edit;
615   }
616   CFX_WideString wsText;
617   m_pDataAcc->GetValue(wsText, eType);
618   ((CFWL_DateTimePicker*)m_pNormalWidget)->SetEditText(wsText);
619   if (IsFocused() && !wsText.IsEmpty()) {
620     CXFA_LocaleValue lcValue = XFA_GetLocaleValue(m_pDataAcc);
621     CFX_Unitime date = lcValue.GetDate();
622     if (lcValue.IsValid()) {
623       if ((FX_UNITIME)date != 0) {
624         ((CFWL_DateTimePicker*)m_pNormalWidget)
625             ->SetCurSel(date.GetYear(), date.GetMonth(), date.GetDay());
626       }
627     }
628   }
629   m_pNormalWidget->Update();
630   return true;
631 }
IsDataChanged()632 bool CXFA_FFDateTimeEdit::IsDataChanged() {
633   if (m_dwStatus & XFA_WidgetStatus_TextEditValueChanged) {
634     return true;
635   }
636   CFX_WideString wsText =
637       static_cast<CFWL_DateTimePicker*>(m_pNormalWidget)->GetEditText();
638   CFX_WideString wsOldValue;
639   m_pDataAcc->GetValue(wsOldValue, XFA_VALUEPICTURE_Edit);
640   return wsOldValue != wsText;
641 }
642 
OnSelectChanged(CFWL_Widget * pWidget,int32_t iYear,int32_t iMonth,int32_t iDay)643 void CXFA_FFDateTimeEdit::OnSelectChanged(CFWL_Widget* pWidget,
644                                           int32_t iYear,
645                                           int32_t iMonth,
646                                           int32_t iDay) {
647   CFX_WideString wsPicture;
648   m_pDataAcc->GetPictureContent(wsPicture, XFA_VALUEPICTURE_Edit);
649   CXFA_LocaleValue date(XFA_VT_DATE, GetDoc()->GetXFADoc()->GetLocalMgr());
650   CFX_Unitime dt;
651   dt.Set(iYear, iMonth, iDay);
652   date.SetDate(dt);
653   CFX_WideString wsDate;
654   date.FormatPatterns(wsDate, wsPicture, m_pDataAcc->GetLocal(),
655                       XFA_VALUEPICTURE_Edit);
656   CFWL_DateTimePicker* pDateTime = (CFWL_DateTimePicker*)m_pNormalWidget;
657   pDateTime->SetEditText(wsDate);
658   pDateTime->Update();
659   GetDoc()->GetDocEnvironment()->SetFocusWidget(GetDoc(), nullptr);
660   CXFA_EventParam eParam;
661   eParam.m_eType = XFA_EVENT_Change;
662   eParam.m_pTarget = m_pDataAcc;
663   m_pDataAcc->GetValue(eParam.m_wsNewText, XFA_VALUEPICTURE_Raw);
664   m_pDataAcc->ProcessEvent(XFA_ATTRIBUTEENUM_Change, &eParam);
665 }
666 
OnProcessEvent(CFWL_Event * pEvent)667 void CXFA_FFDateTimeEdit::OnProcessEvent(CFWL_Event* pEvent) {
668   if (pEvent->GetType() == CFWL_Event::Type::SelectChanged) {
669     CFWL_EventSelectChanged* event =
670         static_cast<CFWL_EventSelectChanged*>(pEvent);
671     OnSelectChanged(m_pNormalWidget, event->iYear, event->iMonth, event->iDay);
672     return;
673   }
674   CXFA_FFTextEdit::OnProcessEvent(pEvent);
675 }
676