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_ffnumericedit.h"
8 
9 #include <utility>
10 
11 #include "third_party/base/ptr_util.h"
12 #include "xfa/fwl/cfwl_edit.h"
13 #include "xfa/fwl/cfwl_eventvalidate.h"
14 #include "xfa/fwl/cfwl_notedriver.h"
15 #include "xfa/fxfa/cxfa_ffdoc.h"
16 #include "xfa/fxfa/parser/cxfa_localevalue.h"
17 #include "xfa/fxfa/parser/cxfa_node.h"
18 #include "xfa/fxfa/parser/xfa_utils.h"
19 
CXFA_FFNumericEdit(CXFA_Node * pNode)20 CXFA_FFNumericEdit::CXFA_FFNumericEdit(CXFA_Node* pNode)
21     : CXFA_FFTextEdit(pNode) {}
22 
23 CXFA_FFNumericEdit::~CXFA_FFNumericEdit() = default;
24 
LoadWidget()25 bool CXFA_FFNumericEdit::LoadWidget() {
26   ASSERT(!IsLoaded());
27   auto pNewEdit = pdfium::MakeUnique<CFWL_Edit>(
28       GetFWLApp(), pdfium::MakeUnique<CFWL_WidgetProperties>(), nullptr);
29   CFWL_Edit* pWidget = pNewEdit.get();
30   SetNormalWidget(std::move(pNewEdit));
31   pWidget->SetAdapterIface(this);
32 
33   CFWL_NoteDriver* pNoteDriver = pWidget->GetOwnerApp()->GetNoteDriver();
34   pNoteDriver->RegisterEventTarget(pWidget, pWidget);
35   m_pOldDelegate = pWidget->GetDelegate();
36   pWidget->SetDelegate(this);
37 
38   {
39     CFWL_Widget::ScopedUpdateLock update_lock(pWidget);
40     pWidget->SetText(m_pNode->GetValue(XFA_VALUEPICTURE_Display));
41     UpdateWidgetProperty();
42   }
43 
44   return CXFA_FFField::LoadWidget();
45 }
46 
UpdateWidgetProperty()47 void CXFA_FFNumericEdit::UpdateWidgetProperty() {
48   CFWL_Edit* pWidget = static_cast<CFWL_Edit*>(GetNormalWidget());
49   if (!pWidget)
50     return;
51 
52   uint32_t dwExtendedStyle =
53       FWL_STYLEEXT_EDT_ShowScrollbarFocus | FWL_STYLEEXT_EDT_OuterScrollbar |
54       FWL_STYLEEXT_EDT_Validate | FWL_STYLEEXT_EDT_Number;
55   dwExtendedStyle |= UpdateUIProperty();
56   if (!m_pNode->IsHorizontalScrollPolicyOff())
57     dwExtendedStyle |= FWL_STYLEEXT_EDT_AutoHScroll;
58 
59   Optional<int32_t> numCells = m_pNode->GetNumberOfCells();
60   if (numCells && *numCells > 0) {
61     dwExtendedStyle |= FWL_STYLEEXT_EDT_CombText;
62     pWidget->SetLimit(*numCells);
63   }
64   dwExtendedStyle |= GetAlignment();
65   if (!m_pNode->IsOpenAccess() || !GetDoc()->GetXFADoc()->IsInteractive())
66     dwExtendedStyle |= FWL_STYLEEXT_EDT_ReadOnly;
67 
68   GetNormalWidget()->ModifyStylesEx(dwExtendedStyle, 0xFFFFFFFF);
69 }
70 
OnProcessEvent(CFWL_Event * pEvent)71 void CXFA_FFNumericEdit::OnProcessEvent(CFWL_Event* pEvent) {
72   if (pEvent->GetType() == CFWL_Event::Type::Validate) {
73     CFWL_EventValidate* event = static_cast<CFWL_EventValidate*>(pEvent);
74     event->bValidate = OnValidate(GetNormalWidget(), event->wsInsert);
75     return;
76   }
77   CXFA_FFTextEdit::OnProcessEvent(pEvent);
78 }
79 
OnValidate(CFWL_Widget * pWidget,WideString & wsText)80 bool CXFA_FFNumericEdit::OnValidate(CFWL_Widget* pWidget, WideString& wsText) {
81   WideString wsPattern = m_pNode->GetPictureContent(XFA_VALUEPICTURE_Edit);
82   if (!wsPattern.IsEmpty())
83     return true;
84 
85   WideString wsFormat;
86   CXFA_LocaleValue widgetValue = XFA_GetLocaleValue(m_pNode.Get());
87   widgetValue.GetNumericFormat(wsFormat, m_pNode->GetLeadDigits(),
88                                m_pNode->GetFracDigits());
89   return widgetValue.ValidateNumericTemp(wsText, wsFormat,
90                                          m_pNode->GetLocale());
91 }
92