blob: cb3a1cda13976a860a155fb6c7f08f8c88a10489 [file] [log] [blame]
// 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 "core/fxcrt/cfx_datetime.h"
#include "third_party/base/check.h"
#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/cxfa_ffdocview.h"
#include "xfa/fxfa/parser/cxfa_localevalue.h"
#include "xfa/fxfa/parser/cxfa_para.h"
#include "xfa/fxfa/parser/cxfa_value.h"
#include "xfa/fxfa/parser/xfa_utils.h"
CXFA_FFDateTimeEdit::CXFA_FFDateTimeEdit(CXFA_Node* pNode)
: CXFA_FFTextEdit(pNode) {}
CXFA_FFDateTimeEdit::~CXFA_FFDateTimeEdit() = default;
CFWL_DateTimePicker* CXFA_FFDateTimeEdit::GetPickerWidget() {
return static_cast<CFWL_DateTimePicker*>(GetNormalWidget());
}
CFX_RectF CXFA_FFDateTimeEdit::GetBBox(FocusOption focus) {
if (focus == kDrawFocus)
return CFX_RectF();
return CXFA_FFWidget::GetBBox(kDoNotDrawFocus);
}
bool CXFA_FFDateTimeEdit::PtInActiveRect(const CFX_PointF& point) {
CFWL_DateTimePicker* pPicker = GetPickerWidget();
return pPicker && pPicker->GetBBox().Contains(point);
}
bool CXFA_FFDateTimeEdit::LoadWidget() {
DCHECK(!IsLoaded());
CFWL_DateTimePicker* pWidget =
cppgc::MakeGarbageCollected<CFWL_DateTimePicker>(
GetFWLApp()->GetHeap()->GetAllocationHandle(), GetFWLApp());
SetNormalWidget(pWidget);
pWidget->SetAdapterIface(this);
CFWL_NoteDriver* pNoteDriver = pWidget->GetFWLApp()->GetNoteDriver();
pNoteDriver->RegisterEventTarget(pWidget, pWidget);
m_pOldDelegate = pWidget->GetDelegate();
pWidget->SetDelegate(this);
{
CFWL_Widget::ScopedUpdateLock update_lock(pWidget);
WideString wsText = m_pNode->GetValue(XFA_ValuePicture::kDisplay);
pWidget->SetEditText(wsText);
CXFA_Value* value = m_pNode->GetFormValueIfExists();
if (value) {
switch (value->GetChildValueClassID()) {
case XFA_Element::Date: {
if (!wsText.IsEmpty()) {
CXFA_LocaleValue lcValue = XFA_GetLocaleValue(m_pNode.Get());
CFX_DateTime date = lcValue.GetDate();
if (date.IsSet())
pWidget->SetCurSel(date.GetYear(), date.GetMonth(),
date.GetDay());
}
} break;
default:
break;
}
}
UpdateWidgetProperty();
}
return CXFA_FFField::LoadWidget();
}
void CXFA_FFDateTimeEdit::UpdateWidgetProperty() {
CFWL_DateTimePicker* pPicker = GetPickerWidget();
if (!pPicker)
return;
uint32_t dwExtendedStyle = FWL_STYLEEXT_DTP_ShortDateFormat;
dwExtendedStyle |= UpdateUIProperty();
dwExtendedStyle |= GetAlignment();
GetNormalWidget()->ModifyStyleExts(dwExtendedStyle, 0xFFFFFFFF);
uint32_t dwEditStyles = 0;
absl::optional<int32_t> numCells = m_pNode->GetNumberOfCells();
if (numCells.has_value() && numCells.value() > 0) {
dwEditStyles |= FWL_STYLEEXT_EDT_CombText;
pPicker->SetEditLimit(numCells.value());
}
if (!m_pNode->IsOpenAccess() || !GetDoc()->GetXFADoc()->IsInteractive())
dwEditStyles |= FWL_STYLEEXT_EDT_ReadOnly;
if (!m_pNode->IsHorizontalScrollPolicyOff())
dwEditStyles |= FWL_STYLEEXT_EDT_AutoHScroll;
pPicker->ModifyEditStyleExts(dwEditStyles, 0xFFFFFFFF);
}
uint32_t CXFA_FFDateTimeEdit::GetAlignment() {
CXFA_Para* para = m_pNode->GetParaIfExists();
if (!para)
return 0;
uint32_t dwExtendedStyle = 0;
switch (para->GetHorizontalAlign()) {
case XFA_AttributeValue::Center:
dwExtendedStyle |= FWL_STYLEEXT_DTP_EditHCenter;
break;
case XFA_AttributeValue::Justify:
dwExtendedStyle |= FWL_STYLEEXT_DTP_EditJustified;
break;
case XFA_AttributeValue::JustifyAll:
case XFA_AttributeValue::Radix:
break;
case XFA_AttributeValue::Right:
dwExtendedStyle |= FWL_STYLEEXT_DTP_EditHFar;
break;
default:
dwExtendedStyle |= FWL_STYLEEXT_DTP_EditHNear;
break;
}
switch (para->GetVerticalAlign()) {
case XFA_AttributeValue::Middle:
dwExtendedStyle |= FWL_STYLEEXT_DTP_EditVCenter;
break;
case XFA_AttributeValue::Bottom:
dwExtendedStyle |= FWL_STYLEEXT_DTP_EditVFar;
break;
default:
dwExtendedStyle |= FWL_STYLEEXT_DTP_EditVNear;
break;
}
return dwExtendedStyle;
}
bool CXFA_FFDateTimeEdit::CommitData() {
CFWL_DateTimePicker* pPicker = GetPickerWidget();
if (!m_pNode->SetValue(XFA_ValuePicture::kEdit, pPicker->GetEditText()))
return false;
GetDoc()->GetDocView()->UpdateUIDisplay(m_pNode.Get(), this);
return true;
}
bool CXFA_FFDateTimeEdit::UpdateFWLData() {
if (!GetNormalWidget())
return false;
XFA_ValuePicture eType = XFA_ValuePicture::kDisplay;
if (IsFocused())
eType = XFA_ValuePicture::kEdit;
WideString wsText = m_pNode->GetValue(eType);
CFWL_DateTimePicker* pPicker = GetPickerWidget();
pPicker->SetEditText(wsText);
if (IsFocused() && !wsText.IsEmpty()) {
CXFA_LocaleValue lcValue = XFA_GetLocaleValue(m_pNode.Get());
CFX_DateTime date = lcValue.GetDate();
if (lcValue.IsValid()) {
if (date.IsSet())
pPicker->SetCurSel(date.GetYear(), date.GetMonth(), date.GetDay());
}
}
GetNormalWidget()->Update();
return true;
}
bool CXFA_FFDateTimeEdit::IsDataChanged() {
if (GetLayoutItem()->TestStatusBits(XFA_WidgetStatus::kTextEditValueChanged))
return true;
WideString wsText = GetPickerWidget()->GetEditText();
return m_pNode->GetValue(XFA_ValuePicture::kEdit) != wsText;
}
void CXFA_FFDateTimeEdit::OnSelectChanged(CFWL_Widget* pWidget,
int32_t iYear,
int32_t iMonth,
int32_t iDay) {
WideString wsPicture = m_pNode->GetPictureContent(XFA_ValuePicture::kEdit);
CXFA_LocaleValue date(CXFA_LocaleValue::ValueType::kDate,
GetDoc()->GetXFADoc()->GetLocaleMgr());
date.SetDate(CFX_DateTime(iYear, iMonth, iDay, 0, 0, 0, 0));
WideString wsDate;
date.FormatPatterns(wsDate, wsPicture, m_pNode->GetLocale(),
XFA_ValuePicture::kEdit);
CFWL_DateTimePicker* pPicker = GetPickerWidget();
pPicker->SetEditText(wsDate);
pPicker->Update();
GetDoc()->SetFocusWidget(nullptr);
CXFA_EventParam eParam;
eParam.m_eType = XFA_EVENT_Change;
eParam.m_pTarget = m_pNode.Get();
eParam.m_wsPrevText = m_pNode->GetValue(XFA_ValuePicture::kRaw);
m_pNode->ProcessEvent(GetDocView(), XFA_AttributeValue::Change, &eParam);
}
void CXFA_FFDateTimeEdit::OnProcessEvent(CFWL_Event* pEvent) {
if (pEvent->GetType() == CFWL_Event::Type::SelectChanged) {
auto* event = static_cast<CFWL_EventSelectChanged*>(pEvent);
OnSelectChanged(GetNormalWidget(), event->GetYear(), event->GetMonth(),
event->GetDay());
return;
}
CXFA_FFTextEdit::OnProcessEvent(pEvent);
}
bool CXFA_FFDateTimeEdit::CanUndo() {
return GetPickerWidget()->CanUndo();
}
bool CXFA_FFDateTimeEdit::CanRedo() {
return GetPickerWidget()->CanRedo();
}
bool CXFA_FFDateTimeEdit::CanCopy() {
return GetPickerWidget()->HasSelection();
}
bool CXFA_FFDateTimeEdit::CanCut() {
if (GetPickerWidget()->GetStyleExts() & FWL_STYLEEXT_EDT_ReadOnly)
return false;
return GetPickerWidget()->HasSelection();
}
bool CXFA_FFDateTimeEdit::CanPaste() {
return !(GetPickerWidget()->GetStyleExts() & FWL_STYLEEXT_EDT_ReadOnly);
}
bool CXFA_FFDateTimeEdit::CanSelectAll() {
return GetPickerWidget()->GetEditTextLength() > 0;
}
absl::optional<WideString> CXFA_FFDateTimeEdit::Copy() {
return GetPickerWidget()->Copy();
}
bool CXFA_FFDateTimeEdit::Undo() {
return GetPickerWidget()->Undo();
}
bool CXFA_FFDateTimeEdit::Redo() {
return GetPickerWidget()->Redo();
}
absl::optional<WideString> CXFA_FFDateTimeEdit::Cut() {
return GetPickerWidget()->Cut();
}
bool CXFA_FFDateTimeEdit::Paste(const WideString& wsPaste) {
return GetPickerWidget()->Paste(wsPaste);
}
void CXFA_FFDateTimeEdit::SelectAll() {
GetPickerWidget()->SelectAll();
}
void CXFA_FFDateTimeEdit::Delete() {
GetPickerWidget()->ClearText();
}
void CXFA_FFDateTimeEdit::DeSelect() {
GetPickerWidget()->ClearSelection();
}
WideString CXFA_FFDateTimeEdit::GetText() {
return GetPickerWidget()->GetEditText();
}