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