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 <utility>
10
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/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
~CXFA_FFDateTimeEdit()25 CXFA_FFDateTimeEdit::~CXFA_FFDateTimeEdit() {}
26
GetBBox(uint32_t dwStatus,bool bDrawFocus)27 CFX_RectF CXFA_FFDateTimeEdit::GetBBox(uint32_t dwStatus, bool bDrawFocus) {
28 if (bDrawFocus)
29 return CFX_RectF();
30 return CXFA_FFWidget::GetBBox(dwStatus);
31 }
32
PtInActiveRect(const CFX_PointF & point)33 bool CXFA_FFDateTimeEdit::PtInActiveRect(const CFX_PointF& point) {
34 auto* pPicker = static_cast<CFWL_DateTimePicker*>(m_pNormalWidget.get());
35 return pPicker && pPicker->GetBBox().Contains(point);
36 }
37
LoadWidget()38 bool CXFA_FFDateTimeEdit::LoadWidget() {
39 auto pNewPicker = pdfium::MakeUnique<CFWL_DateTimePicker>(GetFWLApp());
40 CFWL_DateTimePicker* pWidget = pNewPicker.get();
41 m_pNormalWidget = std::move(pNewPicker);
42 m_pNormalWidget->SetLayoutItem(this);
43
44 CFWL_NoteDriver* pNoteDriver =
45 m_pNormalWidget->GetOwnerApp()->GetNoteDriver();
46 pNoteDriver->RegisterEventTarget(m_pNormalWidget.get(),
47 m_pNormalWidget.get());
48 m_pOldDelegate = m_pNormalWidget->GetDelegate();
49 m_pNormalWidget->SetDelegate(this);
50 m_pNormalWidget->LockUpdate();
51
52 WideString wsText =
53 m_pNode->GetWidgetAcc()->GetValue(XFA_VALUEPICTURE_Display);
54 pWidget->SetEditText(wsText);
55
56 CXFA_Value* value = m_pNode->GetFormValueIfExists();
57 if (value) {
58 switch (value->GetChildValueClassID()) {
59 case XFA_Element::Date: {
60 if (!wsText.IsEmpty()) {
61 CXFA_LocaleValue lcValue = XFA_GetLocaleValue(m_pNode.Get());
62 CFX_DateTime date = lcValue.GetDate();
63 if (date.IsSet())
64 pWidget->SetCurSel(date.GetYear(), date.GetMonth(), date.GetDay());
65 }
66 } break;
67 default:
68 break;
69 }
70 }
71 UpdateWidgetProperty();
72 m_pNormalWidget->UnlockUpdate();
73 return CXFA_FFField::LoadWidget();
74 }
75
UpdateWidgetProperty()76 void CXFA_FFDateTimeEdit::UpdateWidgetProperty() {
77 CFWL_DateTimePicker* pWidget =
78 static_cast<CFWL_DateTimePicker*>(m_pNormalWidget.get());
79 if (!pWidget)
80 return;
81
82 uint32_t dwExtendedStyle = FWL_STYLEEXT_DTP_ShortDateFormat;
83 dwExtendedStyle |= UpdateUIProperty();
84 dwExtendedStyle |= GetAlignment();
85 m_pNormalWidget->ModifyStylesEx(dwExtendedStyle, 0xFFFFFFFF);
86
87 uint32_t dwEditStyles = 0;
88 Optional<int32_t> numCells = m_pNode->GetWidgetAcc()->GetNumberOfCells();
89 if (numCells && *numCells > 0) {
90 dwEditStyles |= FWL_STYLEEXT_EDT_CombText;
91 pWidget->SetEditLimit(*numCells);
92 }
93 if (!m_pNode->IsOpenAccess() || !GetDoc()->GetXFADoc()->IsInteractive())
94 dwEditStyles |= FWL_STYLEEXT_EDT_ReadOnly;
95 if (!m_pNode->GetWidgetAcc()->IsHorizontalScrollPolicyOff())
96 dwEditStyles |= FWL_STYLEEXT_EDT_AutoHScroll;
97
98 pWidget->ModifyEditStylesEx(dwEditStyles, 0xFFFFFFFF);
99 }
100
GetAlignment()101 uint32_t CXFA_FFDateTimeEdit::GetAlignment() {
102 CXFA_Para* para = m_pNode->GetParaIfExists();
103 if (!para)
104 return 0;
105
106 uint32_t dwExtendedStyle = 0;
107 switch (para->GetHorizontalAlign()) {
108 case XFA_AttributeEnum::Center:
109 dwExtendedStyle |= FWL_STYLEEXT_DTP_EditHCenter;
110 break;
111 case XFA_AttributeEnum::Justify:
112 dwExtendedStyle |= FWL_STYLEEXT_DTP_EditJustified;
113 break;
114 case XFA_AttributeEnum::JustifyAll:
115 case XFA_AttributeEnum::Radix:
116 break;
117 case XFA_AttributeEnum::Right:
118 dwExtendedStyle |= FWL_STYLEEXT_DTP_EditHFar;
119 break;
120 default:
121 dwExtendedStyle |= FWL_STYLEEXT_DTP_EditHNear;
122 break;
123 }
124
125 switch (para->GetVerticalAlign()) {
126 case XFA_AttributeEnum::Middle:
127 dwExtendedStyle |= FWL_STYLEEXT_DTP_EditVCenter;
128 break;
129 case XFA_AttributeEnum::Bottom:
130 dwExtendedStyle |= FWL_STYLEEXT_DTP_EditVFar;
131 break;
132 default:
133 dwExtendedStyle |= FWL_STYLEEXT_DTP_EditVNear;
134 break;
135 }
136 return dwExtendedStyle;
137 }
138
CommitData()139 bool CXFA_FFDateTimeEdit::CommitData() {
140 auto* pPicker = static_cast<CFWL_DateTimePicker*>(m_pNormalWidget.get());
141 if (!m_pNode->GetWidgetAcc()->SetValue(XFA_VALUEPICTURE_Edit,
142 pPicker->GetEditText())) {
143 return false;
144 }
145
146 m_pNode->GetWidgetAcc()->UpdateUIDisplay(GetDoc()->GetDocView(), this);
147 return true;
148 }
149
UpdateFWLData()150 bool CXFA_FFDateTimeEdit::UpdateFWLData() {
151 if (!m_pNormalWidget)
152 return false;
153
154 XFA_VALUEPICTURE eType = XFA_VALUEPICTURE_Display;
155 if (IsFocused())
156 eType = XFA_VALUEPICTURE_Edit;
157
158 WideString wsText = m_pNode->GetWidgetAcc()->GetValue(eType);
159 auto* normalWidget = static_cast<CFWL_DateTimePicker*>(m_pNormalWidget.get());
160 normalWidget->SetEditText(wsText);
161 if (IsFocused() && !wsText.IsEmpty()) {
162 CXFA_LocaleValue lcValue = XFA_GetLocaleValue(m_pNode.Get());
163 CFX_DateTime date = lcValue.GetDate();
164 if (lcValue.IsValid()) {
165 if (date.IsSet())
166 normalWidget->SetCurSel(date.GetYear(), date.GetMonth(), date.GetDay());
167 }
168 }
169 m_pNormalWidget->Update();
170 return true;
171 }
172
IsDataChanged()173 bool CXFA_FFDateTimeEdit::IsDataChanged() {
174 if (m_dwStatus & XFA_WidgetStatus_TextEditValueChanged)
175 return true;
176
177 WideString wsText =
178 static_cast<CFWL_DateTimePicker*>(m_pNormalWidget.get())->GetEditText();
179 return m_pNode->GetWidgetAcc()->GetValue(XFA_VALUEPICTURE_Edit) != wsText;
180 }
181
OnSelectChanged(CFWL_Widget * pWidget,int32_t iYear,int32_t iMonth,int32_t iDay)182 void CXFA_FFDateTimeEdit::OnSelectChanged(CFWL_Widget* pWidget,
183 int32_t iYear,
184 int32_t iMonth,
185 int32_t iDay) {
186 WideString wsPicture =
187 m_pNode->GetWidgetAcc()->GetPictureContent(XFA_VALUEPICTURE_Edit);
188
189 CXFA_LocaleValue date(XFA_VT_DATE, GetDoc()->GetXFADoc()->GetLocalMgr());
190 date.SetDate(CFX_DateTime(iYear, iMonth, iDay, 0, 0, 0, 0));
191
192 WideString wsDate;
193 date.FormatPatterns(wsDate, wsPicture, m_pNode->GetLocale(),
194 XFA_VALUEPICTURE_Edit);
195
196 auto* pDateTime = static_cast<CFWL_DateTimePicker*>(m_pNormalWidget.get());
197 pDateTime->SetEditText(wsDate);
198 pDateTime->Update();
199 GetDoc()->GetDocEnvironment()->SetFocusWidget(GetDoc(), nullptr);
200
201 CXFA_EventParam eParam;
202 eParam.m_eType = XFA_EVENT_Change;
203 eParam.m_pTarget = m_pNode->GetWidgetAcc();
204 eParam.m_wsNewText = m_pNode->GetWidgetAcc()->GetValue(XFA_VALUEPICTURE_Raw);
205 m_pNode->ProcessEvent(GetDocView(), XFA_AttributeEnum::Change, &eParam);
206 }
207
OnProcessEvent(CFWL_Event * pEvent)208 void CXFA_FFDateTimeEdit::OnProcessEvent(CFWL_Event* pEvent) {
209 if (pEvent->GetType() == CFWL_Event::Type::SelectChanged) {
210 auto* event = static_cast<CFWL_EventSelectChanged*>(pEvent);
211 OnSelectChanged(m_pNormalWidget.get(), event->iYear, event->iMonth,
212 event->iDay);
213 return;
214 }
215 CXFA_FFTextEdit::OnProcessEvent(pEvent);
216 }
217