xref: /aosp_15_r20/external/pdfium/xfa/fxfa/cxfa_ffdatetimeedit.cpp (revision 3ac0a46f773bac49fa9476ec2b1cf3f8da5ec3a4)
1 // Copyright 2017 The PDFium Authors
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/cxfa_ffdatetimeedit.h"
8 
9 #include "core/fxcrt/cfx_datetime.h"
10 #include "third_party/base/check.h"
11 #include "xfa/fwl/cfwl_datetimepicker.h"
12 #include "xfa/fwl/cfwl_eventselectchanged.h"
13 #include "xfa/fwl/cfwl_notedriver.h"
14 #include "xfa/fwl/cfwl_widget.h"
15 #include "xfa/fxfa/cxfa_eventparam.h"
16 #include "xfa/fxfa/cxfa_ffdoc.h"
17 #include "xfa/fxfa/cxfa_ffdocview.h"
18 #include "xfa/fxfa/parser/cxfa_localevalue.h"
19 #include "xfa/fxfa/parser/cxfa_para.h"
20 #include "xfa/fxfa/parser/cxfa_value.h"
21 #include "xfa/fxfa/parser/xfa_utils.h"
22 
CXFA_FFDateTimeEdit(CXFA_Node * pNode)23 CXFA_FFDateTimeEdit::CXFA_FFDateTimeEdit(CXFA_Node* pNode)
24     : CXFA_FFTextEdit(pNode) {}
25 
26 CXFA_FFDateTimeEdit::~CXFA_FFDateTimeEdit() = default;
27 
GetPickerWidget()28 CFWL_DateTimePicker* CXFA_FFDateTimeEdit::GetPickerWidget() {
29   return static_cast<CFWL_DateTimePicker*>(GetNormalWidget());
30 }
31 
GetBBox(FocusOption focus)32 CFX_RectF CXFA_FFDateTimeEdit::GetBBox(FocusOption focus) {
33   if (focus == kDrawFocus)
34     return CFX_RectF();
35   return CXFA_FFWidget::GetBBox(kDoNotDrawFocus);
36 }
37 
PtInActiveRect(const CFX_PointF & point)38 bool CXFA_FFDateTimeEdit::PtInActiveRect(const CFX_PointF& point) {
39   CFWL_DateTimePicker* pPicker = GetPickerWidget();
40   return pPicker && pPicker->GetBBox().Contains(point);
41 }
42 
LoadWidget()43 bool CXFA_FFDateTimeEdit::LoadWidget() {
44   DCHECK(!IsLoaded());
45 
46   CFWL_DateTimePicker* pWidget =
47       cppgc::MakeGarbageCollected<CFWL_DateTimePicker>(
48           GetFWLApp()->GetHeap()->GetAllocationHandle(), GetFWLApp());
49   SetNormalWidget(pWidget);
50   pWidget->SetAdapterIface(this);
51 
52   CFWL_NoteDriver* pNoteDriver = pWidget->GetFWLApp()->GetNoteDriver();
53   pNoteDriver->RegisterEventTarget(pWidget, pWidget);
54   m_pOldDelegate = pWidget->GetDelegate();
55   pWidget->SetDelegate(this);
56 
57   {
58     CFWL_Widget::ScopedUpdateLock update_lock(pWidget);
59     WideString wsText = m_pNode->GetValue(XFA_ValuePicture::kDisplay);
60     pWidget->SetEditText(wsText);
61 
62     CXFA_Value* value = m_pNode->GetFormValueIfExists();
63     if (value) {
64       switch (value->GetChildValueClassID()) {
65         case XFA_Element::Date: {
66           if (!wsText.IsEmpty()) {
67             CXFA_LocaleValue lcValue = XFA_GetLocaleValue(m_pNode.Get());
68             CFX_DateTime date = lcValue.GetDate();
69             if (date.IsSet())
70               pWidget->SetCurSel(date.GetYear(), date.GetMonth(),
71                                  date.GetDay());
72           }
73         } break;
74         default:
75           break;
76       }
77     }
78     UpdateWidgetProperty();
79   }
80 
81   return CXFA_FFField::LoadWidget();
82 }
83 
UpdateWidgetProperty()84 void CXFA_FFDateTimeEdit::UpdateWidgetProperty() {
85   CFWL_DateTimePicker* pPicker = GetPickerWidget();
86   if (!pPicker)
87     return;
88 
89   uint32_t dwExtendedStyle = FWL_STYLEEXT_DTP_ShortDateFormat;
90   dwExtendedStyle |= UpdateUIProperty();
91   dwExtendedStyle |= GetAlignment();
92   GetNormalWidget()->ModifyStyleExts(dwExtendedStyle, 0xFFFFFFFF);
93 
94   uint32_t dwEditStyles = 0;
95   absl::optional<int32_t> numCells = m_pNode->GetNumberOfCells();
96   if (numCells.has_value() && numCells.value() > 0) {
97     dwEditStyles |= FWL_STYLEEXT_EDT_CombText;
98     pPicker->SetEditLimit(numCells.value());
99   }
100   if (!m_pNode->IsOpenAccess() || !GetDoc()->GetXFADoc()->IsInteractive())
101     dwEditStyles |= FWL_STYLEEXT_EDT_ReadOnly;
102   if (!m_pNode->IsHorizontalScrollPolicyOff())
103     dwEditStyles |= FWL_STYLEEXT_EDT_AutoHScroll;
104 
105   pPicker->ModifyEditStyleExts(dwEditStyles, 0xFFFFFFFF);
106 }
107 
GetAlignment()108 uint32_t CXFA_FFDateTimeEdit::GetAlignment() {
109   CXFA_Para* para = m_pNode->GetParaIfExists();
110   if (!para)
111     return 0;
112 
113   uint32_t dwExtendedStyle = 0;
114   switch (para->GetHorizontalAlign()) {
115     case XFA_AttributeValue::Center:
116       dwExtendedStyle |= FWL_STYLEEXT_DTP_EditHCenter;
117       break;
118     case XFA_AttributeValue::Justify:
119       dwExtendedStyle |= FWL_STYLEEXT_DTP_EditJustified;
120       break;
121     case XFA_AttributeValue::JustifyAll:
122     case XFA_AttributeValue::Radix:
123       break;
124     case XFA_AttributeValue::Right:
125       dwExtendedStyle |= FWL_STYLEEXT_DTP_EditHFar;
126       break;
127     default:
128       dwExtendedStyle |= FWL_STYLEEXT_DTP_EditHNear;
129       break;
130   }
131 
132   switch (para->GetVerticalAlign()) {
133     case XFA_AttributeValue::Middle:
134       dwExtendedStyle |= FWL_STYLEEXT_DTP_EditVCenter;
135       break;
136     case XFA_AttributeValue::Bottom:
137       dwExtendedStyle |= FWL_STYLEEXT_DTP_EditVFar;
138       break;
139     default:
140       dwExtendedStyle |= FWL_STYLEEXT_DTP_EditVNear;
141       break;
142   }
143   return dwExtendedStyle;
144 }
145 
CommitData()146 bool CXFA_FFDateTimeEdit::CommitData() {
147   CFWL_DateTimePicker* pPicker = GetPickerWidget();
148   if (!m_pNode->SetValue(XFA_ValuePicture::kEdit, pPicker->GetEditText()))
149     return false;
150 
151   GetDoc()->GetDocView()->UpdateUIDisplay(m_pNode.Get(), this);
152   return true;
153 }
154 
UpdateFWLData()155 bool CXFA_FFDateTimeEdit::UpdateFWLData() {
156   if (!GetNormalWidget())
157     return false;
158 
159   XFA_ValuePicture eType = XFA_ValuePicture::kDisplay;
160   if (IsFocused())
161     eType = XFA_ValuePicture::kEdit;
162 
163   WideString wsText = m_pNode->GetValue(eType);
164   CFWL_DateTimePicker* pPicker = GetPickerWidget();
165   pPicker->SetEditText(wsText);
166   if (IsFocused() && !wsText.IsEmpty()) {
167     CXFA_LocaleValue lcValue = XFA_GetLocaleValue(m_pNode.Get());
168     CFX_DateTime date = lcValue.GetDate();
169     if (lcValue.IsValid()) {
170       if (date.IsSet())
171         pPicker->SetCurSel(date.GetYear(), date.GetMonth(), date.GetDay());
172     }
173   }
174   GetNormalWidget()->Update();
175   return true;
176 }
177 
IsDataChanged()178 bool CXFA_FFDateTimeEdit::IsDataChanged() {
179   if (GetLayoutItem()->TestStatusBits(XFA_WidgetStatus::kTextEditValueChanged))
180     return true;
181 
182   WideString wsText = GetPickerWidget()->GetEditText();
183   return m_pNode->GetValue(XFA_ValuePicture::kEdit) != wsText;
184 }
185 
OnSelectChanged(CFWL_Widget * pWidget,int32_t iYear,int32_t iMonth,int32_t iDay)186 void CXFA_FFDateTimeEdit::OnSelectChanged(CFWL_Widget* pWidget,
187                                           int32_t iYear,
188                                           int32_t iMonth,
189                                           int32_t iDay) {
190   WideString wsPicture = m_pNode->GetPictureContent(XFA_ValuePicture::kEdit);
191   CXFA_LocaleValue date(CXFA_LocaleValue::ValueType::kDate,
192                         GetDoc()->GetXFADoc()->GetLocaleMgr());
193   date.SetDate(CFX_DateTime(iYear, iMonth, iDay, 0, 0, 0, 0));
194 
195   WideString wsDate;
196   date.FormatPatterns(wsDate, wsPicture, m_pNode->GetLocale(),
197                       XFA_ValuePicture::kEdit);
198 
199   CFWL_DateTimePicker* pPicker = GetPickerWidget();
200   pPicker->SetEditText(wsDate);
201   pPicker->Update();
202   GetDoc()->SetFocusWidget(nullptr);
203 
204   CXFA_EventParam eParam;
205   eParam.m_eType = XFA_EVENT_Change;
206   eParam.m_wsPrevText = m_pNode->GetValue(XFA_ValuePicture::kRaw);
207   m_pNode->ProcessEvent(GetDocView(), XFA_AttributeValue::Change, &eParam);
208 }
209 
OnProcessEvent(CFWL_Event * pEvent)210 void CXFA_FFDateTimeEdit::OnProcessEvent(CFWL_Event* pEvent) {
211   if (pEvent->GetType() == CFWL_Event::Type::SelectChanged) {
212     auto* event = static_cast<CFWL_EventSelectChanged*>(pEvent);
213     OnSelectChanged(GetNormalWidget(), event->GetYear(), event->GetMonth(),
214                     event->GetDay());
215     return;
216   }
217   CXFA_FFTextEdit::OnProcessEvent(pEvent);
218 }
219 
CanUndo()220 bool CXFA_FFDateTimeEdit::CanUndo() {
221   return GetPickerWidget()->CanUndo();
222 }
223 
CanRedo()224 bool CXFA_FFDateTimeEdit::CanRedo() {
225   return GetPickerWidget()->CanRedo();
226 }
227 
CanCopy()228 bool CXFA_FFDateTimeEdit::CanCopy() {
229   return GetPickerWidget()->HasSelection();
230 }
231 
CanCut()232 bool CXFA_FFDateTimeEdit::CanCut() {
233   if (GetPickerWidget()->GetStyleExts() & FWL_STYLEEXT_EDT_ReadOnly)
234     return false;
235   return GetPickerWidget()->HasSelection();
236 }
237 
CanPaste()238 bool CXFA_FFDateTimeEdit::CanPaste() {
239   return !(GetPickerWidget()->GetStyleExts() & FWL_STYLEEXT_EDT_ReadOnly);
240 }
241 
CanSelectAll()242 bool CXFA_FFDateTimeEdit::CanSelectAll() {
243   return GetPickerWidget()->GetEditTextLength() > 0;
244 }
245 
Copy()246 absl::optional<WideString> CXFA_FFDateTimeEdit::Copy() {
247   return GetPickerWidget()->Copy();
248 }
249 
Undo()250 bool CXFA_FFDateTimeEdit::Undo() {
251   return GetPickerWidget()->Undo();
252 }
253 
Redo()254 bool CXFA_FFDateTimeEdit::Redo() {
255   return GetPickerWidget()->Redo();
256 }
257 
Cut()258 absl::optional<WideString> CXFA_FFDateTimeEdit::Cut() {
259   return GetPickerWidget()->Cut();
260 }
261 
Paste(const WideString & wsPaste)262 bool CXFA_FFDateTimeEdit::Paste(const WideString& wsPaste) {
263   return GetPickerWidget()->Paste(wsPaste);
264 }
265 
SelectAll()266 void CXFA_FFDateTimeEdit::SelectAll() {
267   GetPickerWidget()->SelectAll();
268 }
269 
Delete()270 void CXFA_FFDateTimeEdit::Delete() {
271   GetPickerWidget()->ClearText();
272 }
273 
DeSelect()274 void CXFA_FFDateTimeEdit::DeSelect() {
275   GetPickerWidget()->ClearSelection();
276 }
277 
GetText()278 WideString CXFA_FFDateTimeEdit::GetText() {
279   return GetPickerWidget()->GetEditText();
280 }
281