// Copyright 2017 PDFium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com #include "xfa/fxfa/cxfa_ffdatetimeedit.h" #include #include "xfa/fwl/cfwl_datetimepicker.h" #include "xfa/fwl/cfwl_eventselectchanged.h" #include "xfa/fwl/cfwl_notedriver.h" #include "xfa/fwl/cfwl_widget.h" #include "xfa/fxfa/cxfa_eventparam.h" #include "xfa/fxfa/cxfa_ffdoc.h" #include "xfa/fxfa/parser/cxfa_localevalue.h" #include "xfa/fxfa/parser/xfa_utils.h" CXFA_FFDateTimeEdit::CXFA_FFDateTimeEdit(CXFA_WidgetAcc* pDataAcc) : CXFA_FFTextEdit(pDataAcc) {} CXFA_FFDateTimeEdit::~CXFA_FFDateTimeEdit() {} CFX_RectF CXFA_FFDateTimeEdit::GetBBox(uint32_t dwStatus, bool bDrawFocus) { if (bDrawFocus) return CFX_RectF(); return CXFA_FFWidget::GetBBox(dwStatus); } bool CXFA_FFDateTimeEdit::PtInActiveRect(const CFX_PointF& point) { auto* pPicker = static_cast(m_pNormalWidget.get()); return pPicker && pPicker->GetBBox().Contains(point); } bool CXFA_FFDateTimeEdit::LoadWidget() { auto pNewPicker = pdfium::MakeUnique(GetFWLApp()); CFWL_DateTimePicker* pWidget = pNewPicker.get(); m_pNormalWidget = std::move(pNewPicker); m_pNormalWidget->SetLayoutItem(this); CFWL_NoteDriver* pNoteDriver = m_pNormalWidget->GetOwnerApp()->GetNoteDriver(); pNoteDriver->RegisterEventTarget(m_pNormalWidget.get(), m_pNormalWidget.get()); m_pOldDelegate = m_pNormalWidget->GetDelegate(); m_pNormalWidget->SetDelegate(this); m_pNormalWidget->LockUpdate(); WideString wsText; m_pDataAcc->GetValue(wsText, XFA_VALUEPICTURE_Display); pWidget->SetEditText(wsText); if (CXFA_ValueData valueData = m_pDataAcc->GetFormValueData()) { switch (valueData.GetChildValueClassID()) { case XFA_Element::Date: { if (!wsText.IsEmpty()) { CXFA_LocaleValue lcValue = XFA_GetLocaleValue(m_pDataAcc.Get()); CFX_DateTime date = lcValue.GetDate(); if (date.IsSet()) pWidget->SetCurSel(date.GetYear(), date.GetMonth(), date.GetDay()); } } break; default: break; } } UpdateWidgetProperty(); m_pNormalWidget->UnlockUpdate(); return CXFA_FFField::LoadWidget(); } void CXFA_FFDateTimeEdit::UpdateWidgetProperty() { CFWL_DateTimePicker* pWidget = static_cast(m_pNormalWidget.get()); if (!pWidget) return; uint32_t dwExtendedStyle = FWL_STYLEEXT_DTP_ShortDateFormat; dwExtendedStyle |= UpdateUIProperty(); dwExtendedStyle |= GetAlignment(); m_pNormalWidget->ModifyStylesEx(dwExtendedStyle, 0xFFFFFFFF); uint32_t dwEditStyles = 0; int32_t iNumCells = m_pDataAcc->GetNumberOfCells(); if (iNumCells > 0) { dwEditStyles |= FWL_STYLEEXT_EDT_CombText; pWidget->SetEditLimit(iNumCells); } if (m_pDataAcc->GetAccess() != XFA_ATTRIBUTEENUM_Open || !m_pDataAcc->GetDoc()->GetXFADoc()->IsInteractive()) { dwEditStyles |= FWL_STYLEEXT_EDT_ReadOnly; } if (m_pDataAcc->GetHorizontalScrollPolicy() != XFA_ATTRIBUTEENUM_Off) dwEditStyles |= FWL_STYLEEXT_EDT_AutoHScroll; pWidget->ModifyEditStylesEx(dwEditStyles, 0xFFFFFFFF); } uint32_t CXFA_FFDateTimeEdit::GetAlignment() { CXFA_ParaData paraData = m_pDataAcc->GetParaData(); if (!paraData) return 0; uint32_t dwExtendedStyle = 0; switch (paraData.GetHorizontalAlign()) { case XFA_ATTRIBUTEENUM_Center: dwExtendedStyle |= FWL_STYLEEXT_DTP_EditHCenter; break; case XFA_ATTRIBUTEENUM_Justify: dwExtendedStyle |= FWL_STYLEEXT_DTP_EditJustified; break; case XFA_ATTRIBUTEENUM_JustifyAll: case XFA_ATTRIBUTEENUM_Radix: break; case XFA_ATTRIBUTEENUM_Right: dwExtendedStyle |= FWL_STYLEEXT_DTP_EditHFar; break; default: dwExtendedStyle |= FWL_STYLEEXT_DTP_EditHNear; break; } switch (paraData.GetVerticalAlign()) { case XFA_ATTRIBUTEENUM_Middle: dwExtendedStyle |= FWL_STYLEEXT_DTP_EditVCenter; break; case XFA_ATTRIBUTEENUM_Bottom: dwExtendedStyle |= FWL_STYLEEXT_DTP_EditVFar; break; default: dwExtendedStyle |= FWL_STYLEEXT_DTP_EditVNear; break; } return dwExtendedStyle; } bool CXFA_FFDateTimeEdit::CommitData() { auto* pPicker = static_cast(m_pNormalWidget.get()); if (!m_pDataAcc->SetValue(pPicker->GetEditText(), XFA_VALUEPICTURE_Edit)) return false; m_pDataAcc->UpdateUIDisplay(this); return true; } bool CXFA_FFDateTimeEdit::UpdateFWLData() { if (!m_pNormalWidget) return false; XFA_VALUEPICTURE eType = XFA_VALUEPICTURE_Display; if (IsFocused()) eType = XFA_VALUEPICTURE_Edit; WideString wsText; m_pDataAcc->GetValue(wsText, eType); auto* normalWidget = static_cast(m_pNormalWidget.get()); normalWidget->SetEditText(wsText); if (IsFocused() && !wsText.IsEmpty()) { CXFA_LocaleValue lcValue = XFA_GetLocaleValue(m_pDataAcc.Get()); CFX_DateTime date = lcValue.GetDate(); if (lcValue.IsValid()) { if (date.IsSet()) normalWidget->SetCurSel(date.GetYear(), date.GetMonth(), date.GetDay()); } } m_pNormalWidget->Update(); return true; } bool CXFA_FFDateTimeEdit::IsDataChanged() { if (m_dwStatus & XFA_WidgetStatus_TextEditValueChanged) return true; WideString wsText = static_cast(m_pNormalWidget.get())->GetEditText(); WideString wsOldValue; m_pDataAcc->GetValue(wsOldValue, XFA_VALUEPICTURE_Edit); return wsOldValue != wsText; } void CXFA_FFDateTimeEdit::OnSelectChanged(CFWL_Widget* pWidget, int32_t iYear, int32_t iMonth, int32_t iDay) { WideString wsPicture; m_pDataAcc->GetPictureContent(wsPicture, XFA_VALUEPICTURE_Edit); CXFA_LocaleValue date(XFA_VT_DATE, GetDoc()->GetXFADoc()->GetLocalMgr()); date.SetDate(CFX_DateTime(iYear, iMonth, iDay, 0, 0, 0, 0)); WideString wsDate; date.FormatPatterns(wsDate, wsPicture, m_pDataAcc->GetLocal(), XFA_VALUEPICTURE_Edit); auto* pDateTime = static_cast(m_pNormalWidget.get()); pDateTime->SetEditText(wsDate); pDateTime->Update(); GetDoc()->GetDocEnvironment()->SetFocusWidget(GetDoc(), nullptr); CXFA_EventParam eParam; eParam.m_eType = XFA_EVENT_Change; eParam.m_pTarget = m_pDataAcc.Get(); m_pDataAcc->GetValue(eParam.m_wsNewText, XFA_VALUEPICTURE_Raw); m_pDataAcc->ProcessEvent(XFA_ATTRIBUTEENUM_Change, &eParam); } void CXFA_FFDateTimeEdit::OnProcessEvent(CFWL_Event* pEvent) { if (pEvent->GetType() == CFWL_Event::Type::SelectChanged) { auto* event = static_cast(pEvent); OnSelectChanged(m_pNormalWidget.get(), event->iYear, event->iMonth, event->iDay); return; } CXFA_FFTextEdit::OnProcessEvent(pEvent); }