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 22CXFA_FFDateTimeEdit::CXFA_FFDateTimeEdit(CXFA_Node* pNode) 23 : CXFA_FFTextEdit(pNode) {} 24 25CXFA_FFDateTimeEdit::~CXFA_FFDateTimeEdit() {} 26 27CFX_RectF CXFA_FFDateTimeEdit::GetBBox(uint32_t dwStatus, bool bDrawFocus) { 28 if (bDrawFocus) 29 return CFX_RectF(); 30 return CXFA_FFWidget::GetBBox(dwStatus); 31} 32 33bool 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 38bool 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 76void 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 101uint32_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 139bool 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 150bool 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 173bool 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 182void 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 208void 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