Home | History | Annotate | Download | only in formfiller
      1 // Copyright 2014 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 "fpdfsdk/include/formfiller/FFL_ComboBox.h"
      8 
      9 #include "fpdfsdk/include/formfiller/FFL_CBA_Fontmap.h"
     10 #include "fpdfsdk/include/formfiller/FFL_FormFiller.h"
     11 #include "fpdfsdk/include/formfiller/FFL_IFormFiller.h"
     12 #include "fpdfsdk/include/fsdk_common.h"
     13 #include "fpdfsdk/include/fsdk_mgr.h"
     14 #include "fpdfsdk/include/pdfwindow/PWL_ComboBox.h"
     15 
     16 CFFL_ComboBox::CFFL_ComboBox(CPDFDoc_Environment* pApp, CPDFSDK_Annot* pAnnot)
     17     : CFFL_FormFiller(pApp, pAnnot), m_pFontMap(NULL) {
     18   m_State.nIndex = 0;
     19   m_State.nStart = 0;
     20   m_State.nEnd = 0;
     21 }
     22 
     23 CFFL_ComboBox::~CFFL_ComboBox() {
     24   for (const auto& it : m_Maps)
     25     it.second->InvalidateFocusHandler(this);
     26   delete m_pFontMap;
     27 }
     28 
     29 PWL_CREATEPARAM CFFL_ComboBox::GetCreateParam() {
     30   PWL_CREATEPARAM cp = CFFL_FormFiller::GetCreateParam();
     31 
     32   int nFlags = m_pWidget->GetFieldFlags();
     33   if (nFlags & FIELDFLAG_EDIT) {
     34     cp.dwFlags |= PCBS_ALLOWCUSTOMTEXT;
     35   }
     36 
     37   if (!m_pFontMap)
     38     m_pFontMap = new CBA_FontMap(m_pWidget, GetSystemHandler());
     39   cp.pFontMap = m_pFontMap;
     40   cp.pFocusHandler = this;
     41 
     42   return cp;
     43 }
     44 
     45 CPWL_Wnd* CFFL_ComboBox::NewPDFWindow(const PWL_CREATEPARAM& cp,
     46                                       CPDFSDK_PageView* pPageView) {
     47   CPWL_ComboBox* pWnd = new CPWL_ComboBox();
     48   pWnd->AttachFFLData(this);
     49   pWnd->Create(cp);
     50 
     51   CFFL_IFormFiller* pFormFiller = m_pApp->GetIFormFiller();
     52   pWnd->SetFillerNotify(pFormFiller);
     53 
     54   int32_t nCurSel = m_pWidget->GetSelectedIndex(0);
     55   CFX_WideString swText;
     56   if (nCurSel < 0)
     57     swText = m_pWidget->GetValue();
     58   else
     59     swText = m_pWidget->GetOptionLabel(nCurSel);
     60 
     61   for (int32_t i = 0, sz = m_pWidget->CountOptions(); i < sz; i++) {
     62     pWnd->AddString(m_pWidget->GetOptionLabel(i).c_str());
     63   }
     64 
     65   pWnd->SetSelect(nCurSel);
     66   pWnd->SetText(swText.c_str());
     67   return pWnd;
     68 }
     69 
     70 FX_BOOL CFFL_ComboBox::OnChar(CPDFSDK_Annot* pAnnot,
     71                               FX_UINT nChar,
     72                               FX_UINT nFlags) {
     73   return CFFL_FormFiller::OnChar(pAnnot, nChar, nFlags);
     74 }
     75 
     76 FX_BOOL CFFL_ComboBox::IsDataChanged(CPDFSDK_PageView* pPageView) {
     77   CPWL_ComboBox* pWnd = (CPWL_ComboBox*)GetPDFWindow(pPageView, FALSE);
     78   if (!pWnd)
     79     return FALSE;
     80 
     81   int32_t nCurSel = pWnd->GetSelect();
     82   if (!(m_pWidget->GetFieldFlags() & FIELDFLAG_EDIT))
     83     return nCurSel != m_pWidget->GetSelectedIndex(0);
     84 
     85   if (nCurSel >= 0)
     86     return nCurSel != m_pWidget->GetSelectedIndex(0);
     87 
     88   return pWnd->GetText() != m_pWidget->GetValue();
     89 }
     90 
     91 void CFFL_ComboBox::SaveData(CPDFSDK_PageView* pPageView) {
     92   CPWL_ComboBox* pWnd =
     93       static_cast<CPWL_ComboBox*>(GetPDFWindow(pPageView, FALSE));
     94   if (!pWnd)
     95     return;
     96 
     97   CFX_WideString swText = pWnd->GetText();
     98   int32_t nCurSel = pWnd->GetSelect();
     99 
    100   bool bSetValue = false;
    101 
    102   if (m_pWidget->GetFieldFlags() & FIELDFLAG_EDIT)
    103     bSetValue = (nCurSel < 0) || (swText != m_pWidget->GetOptionLabel(nCurSel));
    104 
    105   if (bSetValue) {
    106     m_pWidget->SetValue(swText, FALSE);
    107   } else {
    108     m_pWidget->GetSelectedIndex(0);
    109     m_pWidget->SetOptionSelection(nCurSel, TRUE, FALSE);
    110   }
    111 
    112   m_pWidget->ResetFieldAppearance(TRUE);
    113   m_pWidget->UpdateField();
    114   SetChangeMark();
    115 
    116   m_pWidget->GetPDFPage();
    117 }
    118 
    119 void CFFL_ComboBox::GetActionData(CPDFSDK_PageView* pPageView,
    120                                   CPDF_AAction::AActionType type,
    121                                   PDFSDK_FieldAction& fa) {
    122   switch (type) {
    123     case CPDF_AAction::KeyStroke:
    124       if (CPWL_ComboBox* pComboBox =
    125               static_cast<CPWL_ComboBox*>(GetPDFWindow(pPageView, FALSE))) {
    126         if (CPWL_Edit* pEdit = pComboBox->GetEdit()) {
    127           fa.bFieldFull = pEdit->IsTextFull();
    128           int nSelStart = 0;
    129           int nSelEnd = 0;
    130           pEdit->GetSel(nSelStart, nSelEnd);
    131           fa.nSelEnd = nSelEnd;
    132           fa.nSelStart = nSelStart;
    133           fa.sValue = pEdit->GetText();
    134           fa.sChangeEx = GetSelectExportText();
    135 
    136           if (fa.bFieldFull) {
    137             fa.sChange = L"";
    138             fa.sChangeEx = L"";
    139           }
    140         }
    141       }
    142       break;
    143     case CPDF_AAction::Validate:
    144       if (CPWL_ComboBox* pComboBox =
    145               static_cast<CPWL_ComboBox*>(GetPDFWindow(pPageView, FALSE))) {
    146         if (CPWL_Edit* pEdit = pComboBox->GetEdit()) {
    147           fa.sValue = pEdit->GetText();
    148         }
    149       }
    150       break;
    151     case CPDF_AAction::LoseFocus:
    152     case CPDF_AAction::GetFocus:
    153       fa.sValue = m_pWidget->GetValue();
    154       break;
    155     default:
    156       break;
    157   }
    158 }
    159 
    160 void CFFL_ComboBox::SetActionData(CPDFSDK_PageView* pPageView,
    161                                   CPDF_AAction::AActionType type,
    162                                   const PDFSDK_FieldAction& fa) {
    163   switch (type) {
    164     case CPDF_AAction::KeyStroke:
    165       if (CPWL_ComboBox* pComboBox =
    166               static_cast<CPWL_ComboBox*>(GetPDFWindow(pPageView, FALSE))) {
    167         if (CPWL_Edit* pEdit = pComboBox->GetEdit()) {
    168           pEdit->SetSel(fa.nSelStart, fa.nSelEnd);
    169           pEdit->ReplaceSel(fa.sChange.c_str());
    170         }
    171       }
    172       break;
    173     default:
    174       break;
    175   }
    176 }
    177 
    178 FX_BOOL CFFL_ComboBox::IsActionDataChanged(CPDF_AAction::AActionType type,
    179                                            const PDFSDK_FieldAction& faOld,
    180                                            const PDFSDK_FieldAction& faNew) {
    181   switch (type) {
    182     case CPDF_AAction::KeyStroke:
    183       return (!faOld.bFieldFull && faOld.nSelEnd != faNew.nSelEnd) ||
    184              faOld.nSelStart != faNew.nSelStart ||
    185              faOld.sChange != faNew.sChange;
    186     default:
    187       break;
    188   }
    189 
    190   return FALSE;
    191 }
    192 
    193 void CFFL_ComboBox::SaveState(CPDFSDK_PageView* pPageView) {
    194   ASSERT(pPageView);
    195 
    196   if (CPWL_ComboBox* pComboBox =
    197           static_cast<CPWL_ComboBox*>(GetPDFWindow(pPageView, FALSE))) {
    198     m_State.nIndex = pComboBox->GetSelect();
    199 
    200     if (CPWL_Edit* pEdit = pComboBox->GetEdit()) {
    201       pEdit->GetSel(m_State.nStart, m_State.nEnd);
    202       m_State.sValue = pEdit->GetText();
    203     }
    204   }
    205 }
    206 
    207 void CFFL_ComboBox::RestoreState(CPDFSDK_PageView* pPageView) {
    208   ASSERT(pPageView);
    209 
    210   if (CPWL_ComboBox* pComboBox =
    211           static_cast<CPWL_ComboBox*>(GetPDFWindow(pPageView, TRUE))) {
    212     if (m_State.nIndex >= 0) {
    213       pComboBox->SetSelect(m_State.nIndex);
    214     } else {
    215       if (CPWL_Edit* pEdit = pComboBox->GetEdit()) {
    216         pEdit->SetText(m_State.sValue.c_str());
    217         pEdit->SetSel(m_State.nStart, m_State.nEnd);
    218       }
    219     }
    220   }
    221 }
    222 
    223 CPWL_Wnd* CFFL_ComboBox::ResetPDFWindow(CPDFSDK_PageView* pPageView,
    224                                         FX_BOOL bRestoreValue) {
    225   if (bRestoreValue)
    226     SaveState(pPageView);
    227 
    228   DestroyPDFWindow(pPageView);
    229 
    230   CPWL_Wnd* pRet = NULL;
    231 
    232   if (bRestoreValue) {
    233     RestoreState(pPageView);
    234     pRet = GetPDFWindow(pPageView, FALSE);
    235   } else {
    236     pRet = GetPDFWindow(pPageView, TRUE);
    237   }
    238 
    239   m_pWidget->UpdateField();
    240 
    241   return pRet;
    242 }
    243 
    244 #ifdef PDF_ENABLE_XFA
    245 FX_BOOL CFFL_ComboBox::IsFieldFull(CPDFSDK_PageView* pPageView) {
    246   if (CPWL_ComboBox* pComboBox =
    247           static_cast<CPWL_ComboBox*>(GetPDFWindow(pPageView, FALSE))) {
    248     if (CPWL_Edit* pEdit = pComboBox->GetEdit())
    249       return pEdit->IsTextFull();
    250   }
    251   return FALSE;
    252 }
    253 #endif  // PDF_ENABLE_XFA
    254 
    255 void CFFL_ComboBox::OnSetFocus(CPWL_Wnd* pWnd) {
    256   ASSERT(m_pApp);
    257 
    258   if (pWnd->GetClassName() == PWL_CLASSNAME_EDIT) {
    259     CPWL_Edit* pEdit = (CPWL_Edit*)pWnd;
    260     pEdit->SetCharSet(134);
    261     pEdit->SetCodePage(936);
    262 
    263     pEdit->SetReadyToInput();
    264     CFX_WideString wsText = pEdit->GetText();
    265     int nCharacters = wsText.GetLength();
    266     CFX_ByteString bsUTFText = wsText.UTF16LE_Encode();
    267     unsigned short* pBuffer = (unsigned short*)bsUTFText.c_str();
    268     m_pApp->FFI_OnSetFieldInputFocus(m_pWidget->GetFormField(), pBuffer,
    269                                      nCharacters, TRUE);
    270 
    271     pEdit->SetEditNotify(this);
    272   }
    273 }
    274 
    275 void CFFL_ComboBox::OnKillFocus(CPWL_Wnd* pWnd) {
    276   ASSERT(m_pApp);
    277 }
    278 
    279 void CFFL_ComboBox::OnAddUndo(CPWL_Edit* pEdit) {
    280   ASSERT(pEdit);
    281 }
    282 
    283 CFX_WideString CFFL_ComboBox::GetSelectExportText() {
    284   CFX_WideString swRet;
    285 
    286   int nExport = -1;
    287   CPDFSDK_PageView* pPageView = GetCurPageView();
    288   if (CPWL_ComboBox* pComboBox =
    289           (CPWL_ComboBox*)GetPDFWindow(pPageView, FALSE)) {
    290     nExport = pComboBox->GetSelect();
    291   }
    292 
    293   if (nExport >= 0) {
    294     if (CPDF_FormField* pFormField = m_pWidget->GetFormField()) {
    295       swRet = pFormField->GetOptionValue(nExport);
    296       if (swRet.IsEmpty())
    297         swRet = pFormField->GetOptionLabel(nExport);
    298     }
    299   }
    300 
    301   return swRet;
    302 }
    303