Home | History | Annotate | Download | only in fxfa
      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 
     22 CXFA_FFDateTimeEdit::CXFA_FFDateTimeEdit(CXFA_Node* pNode)
     23     : CXFA_FFTextEdit(pNode) {}
     24 
     25 CXFA_FFDateTimeEdit::~CXFA_FFDateTimeEdit() {}
     26 
     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 
     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 
     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 
     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 
    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 
    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 
    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 
    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 
    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 
    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