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 "xfa/fxfa/app/xfa_fftextedit.h" 8 9 #include <vector> 10 11 #include "xfa/fwl/cfwl_datetimepicker.h" 12 #include "xfa/fwl/cfwl_edit.h" 13 #include "xfa/fwl/cfwl_eventcheckword.h" 14 #include "xfa/fwl/cfwl_eventselectchanged.h" 15 #include "xfa/fwl/cfwl_eventtextchanged.h" 16 #include "xfa/fwl/cfwl_eventvalidate.h" 17 #include "xfa/fwl/cfwl_messagekillfocus.h" 18 #include "xfa/fwl/cfwl_messagemouse.h" 19 #include "xfa/fwl/cfwl_messagesetfocus.h" 20 #include "xfa/fwl/cfwl_notedriver.h" 21 #include "xfa/fxfa/app/xfa_fffield.h" 22 #include "xfa/fxfa/app/xfa_fwladapter.h" 23 #include "xfa/fxfa/cxfa_eventparam.h" 24 #include "xfa/fxfa/parser/xfa_localevalue.h" 25 #include "xfa/fxfa/xfa_ffapp.h" 26 #include "xfa/fxfa/xfa_ffdoc.h" 27 #include "xfa/fxfa/xfa_ffdocview.h" 28 #include "xfa/fxfa/xfa_ffpageview.h" 29 #include "xfa/fxfa/xfa_ffwidget.h" 30 31 CXFA_FFTextEdit::CXFA_FFTextEdit(CXFA_WidgetAcc* pDataAcc) 32 : CXFA_FFField(pDataAcc), m_pOldDelegate(nullptr) {} 33 34 CXFA_FFTextEdit::~CXFA_FFTextEdit() { 35 if (m_pNormalWidget) { 36 CFWL_NoteDriver* pNoteDriver = 37 m_pNormalWidget->GetOwnerApp()->GetNoteDriver(); 38 pNoteDriver->UnregisterEventTarget(m_pNormalWidget); 39 } 40 } 41 42 bool CXFA_FFTextEdit::LoadWidget() { 43 CFWL_Edit* pFWLEdit = new CFWL_Edit( 44 GetFWLApp(), pdfium::MakeUnique<CFWL_WidgetProperties>(), nullptr); 45 m_pNormalWidget = pFWLEdit; 46 m_pNormalWidget->SetLayoutItem(this); 47 48 CFWL_NoteDriver* pNoteDriver = 49 m_pNormalWidget->GetOwnerApp()->GetNoteDriver(); 50 pNoteDriver->RegisterEventTarget(m_pNormalWidget, m_pNormalWidget); 51 52 m_pOldDelegate = m_pNormalWidget->GetDelegate(); 53 m_pNormalWidget->SetDelegate(this); 54 m_pNormalWidget->LockUpdate(); 55 56 UpdateWidgetProperty(); 57 CFX_WideString wsText; 58 m_pDataAcc->GetValue(wsText, XFA_VALUEPICTURE_Display); 59 pFWLEdit->SetText(wsText); 60 m_pNormalWidget->UnlockUpdate(); 61 return CXFA_FFField::LoadWidget(); 62 } 63 void CXFA_FFTextEdit::UpdateWidgetProperty() { 64 CFWL_Edit* pWidget = (CFWL_Edit*)m_pNormalWidget; 65 if (!pWidget) { 66 return; 67 } 68 uint32_t dwStyle = 0; 69 uint32_t dwExtendedStyle = FWL_STYLEEXT_EDT_ShowScrollbarFocus | 70 FWL_STYLEEXT_EDT_OuterScrollbar | 71 FWL_STYLEEXT_EDT_LastLineHeight; 72 dwExtendedStyle |= UpdateUIProperty(); 73 if (m_pDataAcc->IsMultiLine()) { 74 dwExtendedStyle |= FWL_STYLEEXT_EDT_MultiLine | FWL_STYLEEXT_EDT_WantReturn; 75 if (m_pDataAcc->GetVerticalScrollPolicy() != XFA_ATTRIBUTEENUM_Off) { 76 dwStyle |= FWL_WGTSTYLE_VScroll; 77 dwExtendedStyle |= FWL_STYLEEXT_EDT_AutoVScroll; 78 } 79 } else if (m_pDataAcc->GetHorizontalScrollPolicy() != XFA_ATTRIBUTEENUM_Off) { 80 dwExtendedStyle |= FWL_STYLEEXT_EDT_AutoHScroll; 81 } 82 if (m_pDataAcc->GetAccess() != XFA_ATTRIBUTEENUM_Open || 83 !m_pDataAcc->GetDoc()->GetXFADoc()->IsInteractive()) { 84 dwExtendedStyle |= FWL_STYLEEXT_EDT_ReadOnly; 85 dwExtendedStyle |= FWL_STYLEEXT_EDT_MultiLine; 86 } 87 XFA_Element eType = XFA_Element::Unknown; 88 int32_t iMaxChars = m_pDataAcc->GetMaxChars(eType); 89 if (eType == XFA_Element::ExData) { 90 iMaxChars = 0; 91 } 92 int32_t iNumCells = m_pDataAcc->GetNumberOfCells(); 93 if (iNumCells == 0) { 94 dwExtendedStyle |= FWL_STYLEEXT_EDT_CombText; 95 pWidget->SetLimit(iMaxChars > 0 ? iMaxChars : 1); 96 } else if (iNumCells > 0) { 97 dwExtendedStyle |= FWL_STYLEEXT_EDT_CombText; 98 pWidget->SetLimit(iNumCells); 99 } else { 100 pWidget->SetLimit(iMaxChars); 101 } 102 dwExtendedStyle |= GetAlignment(); 103 m_pNormalWidget->ModifyStyles(dwStyle, 0xFFFFFFFF); 104 m_pNormalWidget->ModifyStylesEx(dwExtendedStyle, 0xFFFFFFFF); 105 } 106 107 bool CXFA_FFTextEdit::OnLButtonDown(uint32_t dwFlags, const CFX_PointF& point) { 108 if (!PtInActiveRect(point)) 109 return false; 110 if (!IsFocused()) { 111 m_dwStatus |= XFA_WidgetStatus_Focused; 112 UpdateFWLData(); 113 AddInvalidateRect(); 114 } 115 116 SetButtonDown(true); 117 CFWL_MessageMouse ms(nullptr, m_pNormalWidget); 118 ms.m_dwCmd = FWL_MouseCommand::LeftButtonDown; 119 ms.m_dwFlags = dwFlags; 120 ms.m_pos = FWLToClient(point); 121 TranslateFWLMessage(&ms); 122 return true; 123 } 124 125 bool CXFA_FFTextEdit::OnRButtonDown(uint32_t dwFlags, const CFX_PointF& point) { 126 if (m_pDataAcc->GetAccess() != XFA_ATTRIBUTEENUM_Open) 127 return false; 128 if (!PtInActiveRect(point)) 129 return false; 130 if (!IsFocused()) { 131 m_dwStatus |= XFA_WidgetStatus_Focused; 132 UpdateFWLData(); 133 AddInvalidateRect(); 134 } 135 136 SetButtonDown(true); 137 CFWL_MessageMouse ms(nullptr, nullptr); 138 ms.m_dwCmd = FWL_MouseCommand::RightButtonDown; 139 ms.m_dwFlags = dwFlags; 140 ms.m_pos = FWLToClient(point); 141 TranslateFWLMessage(&ms); 142 return true; 143 } 144 145 bool CXFA_FFTextEdit::OnRButtonUp(uint32_t dwFlags, const CFX_PointF& point) { 146 if (!CXFA_FFField::OnRButtonUp(dwFlags, point)) 147 return false; 148 149 GetDoc()->GetDocEnvironment()->PopupMenu(this, point); 150 return true; 151 } 152 153 bool CXFA_FFTextEdit::OnSetFocus(CXFA_FFWidget* pOldWidget) { 154 m_dwStatus &= ~XFA_WidgetStatus_TextEditValueChanged; 155 if (!IsFocused()) { 156 m_dwStatus |= XFA_WidgetStatus_Focused; 157 UpdateFWLData(); 158 AddInvalidateRect(); 159 } 160 CXFA_FFWidget::OnSetFocus(pOldWidget); 161 CFWL_MessageSetFocus ms(nullptr, m_pNormalWidget); 162 TranslateFWLMessage(&ms); 163 return true; 164 } 165 bool CXFA_FFTextEdit::OnKillFocus(CXFA_FFWidget* pNewWidget) { 166 CFWL_MessageKillFocus ms(nullptr, m_pNormalWidget); 167 TranslateFWLMessage(&ms); 168 m_dwStatus &= ~XFA_WidgetStatus_Focused; 169 SetEditScrollOffset(); 170 ProcessCommittedData(); 171 UpdateFWLData(); 172 AddInvalidateRect(); 173 CXFA_FFWidget::OnKillFocus(pNewWidget); 174 m_dwStatus &= ~XFA_WidgetStatus_TextEditValueChanged; 175 return true; 176 } 177 bool CXFA_FFTextEdit::CommitData() { 178 CFX_WideString wsText = static_cast<CFWL_Edit*>(m_pNormalWidget)->GetText(); 179 if (m_pDataAcc->SetValue(wsText, XFA_VALUEPICTURE_Edit)) { 180 m_pDataAcc->UpdateUIDisplay(this); 181 return true; 182 } 183 ValidateNumberField(wsText); 184 return false; 185 } 186 void CXFA_FFTextEdit::ValidateNumberField(const CFX_WideString& wsText) { 187 CXFA_WidgetAcc* pAcc = GetDataAcc(); 188 if (pAcc && pAcc->GetUIType() == XFA_Element::NumericEdit) { 189 IXFA_AppProvider* pAppProvider = GetApp()->GetAppProvider(); 190 if (pAppProvider) { 191 CFX_WideString wsSomField; 192 pAcc->GetNode()->GetSOMExpression(wsSomField); 193 194 CFX_WideString wsMessage; 195 wsMessage.Format(L"%s can not contain %s", wsText.c_str(), 196 wsSomField.c_str()); 197 pAppProvider->MsgBox(wsMessage, pAppProvider->GetAppTitle(), 198 XFA_MBICON_Error, XFA_MB_OK); 199 } 200 } 201 } 202 bool CXFA_FFTextEdit::IsDataChanged() { 203 return (m_dwStatus & XFA_WidgetStatus_TextEditValueChanged) != 0; 204 } 205 uint32_t CXFA_FFTextEdit::GetAlignment() { 206 uint32_t dwExtendedStyle = 0; 207 if (CXFA_Para para = m_pDataAcc->GetPara()) { 208 int32_t iHorz = para.GetHorizontalAlign(); 209 switch (iHorz) { 210 case XFA_ATTRIBUTEENUM_Center: 211 dwExtendedStyle |= FWL_STYLEEXT_EDT_HCenter; 212 break; 213 case XFA_ATTRIBUTEENUM_Justify: 214 dwExtendedStyle |= FWL_STYLEEXT_EDT_Justified; 215 break; 216 case XFA_ATTRIBUTEENUM_JustifyAll: 217 break; 218 case XFA_ATTRIBUTEENUM_Radix: 219 break; 220 case XFA_ATTRIBUTEENUM_Right: 221 dwExtendedStyle |= FWL_STYLEEXT_EDT_HFar; 222 break; 223 default: 224 dwExtendedStyle |= FWL_STYLEEXT_EDT_HNear; 225 break; 226 } 227 int32_t iVert = para.GetVerticalAlign(); 228 switch (iVert) { 229 case XFA_ATTRIBUTEENUM_Middle: 230 dwExtendedStyle |= FWL_STYLEEXT_EDT_VCenter; 231 break; 232 case XFA_ATTRIBUTEENUM_Bottom: 233 dwExtendedStyle |= FWL_STYLEEXT_EDT_VFar; 234 break; 235 default: 236 dwExtendedStyle |= FWL_STYLEEXT_EDT_VNear; 237 break; 238 } 239 } 240 return dwExtendedStyle; 241 } 242 bool CXFA_FFTextEdit::UpdateFWLData() { 243 if (!m_pNormalWidget) { 244 return false; 245 } 246 XFA_VALUEPICTURE eType = XFA_VALUEPICTURE_Display; 247 if (IsFocused()) { 248 eType = XFA_VALUEPICTURE_Edit; 249 } 250 bool bUpdate = false; 251 if (m_pDataAcc->GetUIType() == XFA_Element::TextEdit && 252 m_pDataAcc->GetNumberOfCells() < 0) { 253 XFA_Element elementType = XFA_Element::Unknown; 254 int32_t iMaxChars = m_pDataAcc->GetMaxChars(elementType); 255 if (elementType == XFA_Element::ExData) { 256 iMaxChars = eType == XFA_VALUEPICTURE_Edit ? iMaxChars : 0; 257 } 258 if (((CFWL_Edit*)m_pNormalWidget)->GetLimit() != iMaxChars) { 259 ((CFWL_Edit*)m_pNormalWidget)->SetLimit(iMaxChars); 260 bUpdate = true; 261 } 262 } 263 if (m_pDataAcc->GetUIType() == XFA_Element::Barcode) { 264 int32_t nDataLen = 0; 265 if (eType == XFA_VALUEPICTURE_Edit) 266 m_pDataAcc->GetBarcodeAttribute_DataLength(nDataLen); 267 static_cast<CFWL_Edit*>(m_pNormalWidget)->SetLimit(nDataLen); 268 bUpdate = true; 269 } 270 CFX_WideString wsText; 271 m_pDataAcc->GetValue(wsText, eType); 272 CFX_WideString wsOldText = 273 static_cast<CFWL_Edit*>(m_pNormalWidget)->GetText(); 274 if (wsText != wsOldText || (eType == XFA_VALUEPICTURE_Edit && bUpdate)) { 275 ((CFWL_Edit*)m_pNormalWidget)->SetText(wsText); 276 bUpdate = true; 277 } 278 if (bUpdate) { 279 m_pNormalWidget->Update(); 280 } 281 return true; 282 } 283 void CXFA_FFTextEdit::OnTextChanged(CFWL_Widget* pWidget, 284 const CFX_WideString& wsChanged, 285 const CFX_WideString& wsPrevText) { 286 m_dwStatus |= XFA_WidgetStatus_TextEditValueChanged; 287 CXFA_EventParam eParam; 288 eParam.m_eType = XFA_EVENT_Change; 289 eParam.m_wsChange = wsChanged; 290 eParam.m_pTarget = m_pDataAcc; 291 eParam.m_wsPrevText = wsPrevText; 292 CFWL_Edit* pEdit = ((CFWL_Edit*)m_pNormalWidget); 293 if (m_pDataAcc->GetUIType() == XFA_Element::DateTimeEdit) { 294 CFWL_DateTimePicker* pDateTime = (CFWL_DateTimePicker*)pEdit; 295 eParam.m_wsNewText = pDateTime->GetEditText(); 296 int32_t iSels = pDateTime->CountSelRanges(); 297 if (iSels) { 298 eParam.m_iSelEnd = pDateTime->GetSelRange(0, &eParam.m_iSelStart); 299 } 300 } else { 301 eParam.m_wsNewText = pEdit->GetText(); 302 int32_t iSels = pEdit->CountSelRanges(); 303 if (iSels) { 304 eParam.m_iSelEnd = pEdit->GetSelRange(0, &eParam.m_iSelStart); 305 } 306 } 307 m_pDataAcc->ProcessEvent(XFA_ATTRIBUTEENUM_Change, &eParam); 308 } 309 void CXFA_FFTextEdit::OnTextFull(CFWL_Widget* pWidget) { 310 CXFA_EventParam eParam; 311 eParam.m_eType = XFA_EVENT_Full; 312 eParam.m_pTarget = m_pDataAcc; 313 m_pDataAcc->ProcessEvent(XFA_ATTRIBUTEENUM_Full, &eParam); 314 } 315 316 bool CXFA_FFTextEdit::CheckWord(const CFX_ByteStringC& sWord) { 317 if (sWord.IsEmpty() || m_pDataAcc->GetUIType() != XFA_Element::TextEdit) 318 return true; 319 return false; 320 } 321 322 void CXFA_FFTextEdit::OnProcessMessage(CFWL_Message* pMessage) { 323 m_pOldDelegate->OnProcessMessage(pMessage); 324 } 325 326 void CXFA_FFTextEdit::OnProcessEvent(CFWL_Event* pEvent) { 327 CXFA_FFField::OnProcessEvent(pEvent); 328 switch (pEvent->GetType()) { 329 case CFWL_Event::Type::TextChanged: { 330 CFWL_EventTextChanged* event = 331 static_cast<CFWL_EventTextChanged*>(pEvent); 332 CFX_WideString wsChange; 333 OnTextChanged(m_pNormalWidget, wsChange, event->wsPrevText); 334 break; 335 } 336 case CFWL_Event::Type::TextFull: { 337 OnTextFull(m_pNormalWidget); 338 break; 339 } 340 case CFWL_Event::Type::CheckWord: { 341 CFX_WideString wstr(L"FWL_EVENT_DTP_SelectChanged"); 342 CFWL_EventCheckWord* event = static_cast<CFWL_EventCheckWord*>(pEvent); 343 event->bCheckWord = CheckWord(event->bsWord.AsStringC()); 344 break; 345 } 346 default: 347 break; 348 } 349 m_pOldDelegate->OnProcessEvent(pEvent); 350 } 351 352 void CXFA_FFTextEdit::OnDrawWidget(CFX_Graphics* pGraphics, 353 const CFX_Matrix* pMatrix) { 354 m_pOldDelegate->OnDrawWidget(pGraphics, pMatrix); 355 } 356 357 CXFA_FFNumericEdit::CXFA_FFNumericEdit(CXFA_WidgetAcc* pDataAcc) 358 : CXFA_FFTextEdit(pDataAcc) {} 359 360 CXFA_FFNumericEdit::~CXFA_FFNumericEdit() {} 361 362 bool CXFA_FFNumericEdit::LoadWidget() { 363 CFWL_Edit* pWidget = new CFWL_Edit( 364 GetFWLApp(), pdfium::MakeUnique<CFWL_WidgetProperties>(), nullptr); 365 m_pNormalWidget = pWidget; 366 367 m_pNormalWidget->SetLayoutItem(this); 368 CFWL_NoteDriver* pNoteDriver = 369 m_pNormalWidget->GetOwnerApp()->GetNoteDriver(); 370 pNoteDriver->RegisterEventTarget(m_pNormalWidget, m_pNormalWidget); 371 372 m_pOldDelegate = m_pNormalWidget->GetDelegate(); 373 m_pNormalWidget->SetDelegate(this); 374 m_pNormalWidget->LockUpdate(); 375 376 CFX_WideString wsText; 377 m_pDataAcc->GetValue(wsText, XFA_VALUEPICTURE_Display); 378 pWidget->SetText(wsText); 379 UpdateWidgetProperty(); 380 m_pNormalWidget->UnlockUpdate(); 381 return CXFA_FFField::LoadWidget(); 382 } 383 void CXFA_FFNumericEdit::UpdateWidgetProperty() { 384 CFWL_Edit* pWidget = (CFWL_Edit*)m_pNormalWidget; 385 if (!pWidget) { 386 return; 387 } 388 uint32_t dwExtendedStyle = 389 FWL_STYLEEXT_EDT_ShowScrollbarFocus | FWL_STYLEEXT_EDT_OuterScrollbar | 390 FWL_STYLEEXT_EDT_Validate | FWL_STYLEEXT_EDT_Number | 391 FWL_STYLEEXT_EDT_LastLineHeight; 392 dwExtendedStyle |= UpdateUIProperty(); 393 if (m_pDataAcc->GetHorizontalScrollPolicy() != XFA_ATTRIBUTEENUM_Off) { 394 dwExtendedStyle |= FWL_STYLEEXT_EDT_AutoHScroll; 395 } 396 int32_t iNumCells = m_pDataAcc->GetNumberOfCells(); 397 if (iNumCells > 0) { 398 dwExtendedStyle |= FWL_STYLEEXT_EDT_CombText; 399 pWidget->SetLimit(iNumCells); 400 } 401 dwExtendedStyle |= GetAlignment(); 402 if (m_pDataAcc->GetAccess() != XFA_ATTRIBUTEENUM_Open || 403 !m_pDataAcc->GetDoc()->GetXFADoc()->IsInteractive()) { 404 dwExtendedStyle |= FWL_STYLEEXT_EDT_ReadOnly; 405 } 406 m_pNormalWidget->ModifyStylesEx(dwExtendedStyle, 0xFFFFFFFF); 407 } 408 409 void CXFA_FFNumericEdit::OnProcessEvent(CFWL_Event* pEvent) { 410 if (pEvent->GetType() == CFWL_Event::Type::Validate) { 411 CFWL_EventValidate* event = static_cast<CFWL_EventValidate*>(pEvent); 412 event->bValidate = OnValidate(m_pNormalWidget, event->wsInsert); 413 return; 414 } 415 CXFA_FFTextEdit::OnProcessEvent(pEvent); 416 } 417 418 bool CXFA_FFNumericEdit::OnValidate(CFWL_Widget* pWidget, 419 CFX_WideString& wsText) { 420 CFX_WideString wsPattern; 421 m_pDataAcc->GetPictureContent(wsPattern, XFA_VALUEPICTURE_Edit); 422 if (!wsPattern.IsEmpty()) { 423 return true; 424 } 425 int32_t iLeads = 0; 426 m_pDataAcc->GetLeadDigits(iLeads); 427 int32_t iFracs = 0; 428 m_pDataAcc->GetFracDigits(iFracs); 429 CFX_WideString wsFormat; 430 CXFA_LocaleValue widgetValue = XFA_GetLocaleValue(m_pDataAcc); 431 widgetValue.GetNumbericFormat(wsFormat, iLeads, iFracs); 432 return widgetValue.ValidateNumericTemp(wsText, wsFormat, 433 m_pDataAcc->GetLocal()); 434 } 435 436 CXFA_FFPasswordEdit::CXFA_FFPasswordEdit(CXFA_WidgetAcc* pDataAcc) 437 : CXFA_FFTextEdit(pDataAcc) {} 438 439 CXFA_FFPasswordEdit::~CXFA_FFPasswordEdit() {} 440 441 bool CXFA_FFPasswordEdit::LoadWidget() { 442 CFWL_Edit* pWidget = new CFWL_Edit( 443 GetFWLApp(), pdfium::MakeUnique<CFWL_WidgetProperties>(), nullptr); 444 m_pNormalWidget = pWidget; 445 m_pNormalWidget->SetLayoutItem(this); 446 447 CFWL_NoteDriver* pNoteDriver = 448 m_pNormalWidget->GetOwnerApp()->GetNoteDriver(); 449 pNoteDriver->RegisterEventTarget(m_pNormalWidget, m_pNormalWidget); 450 451 m_pOldDelegate = m_pNormalWidget->GetDelegate(); 452 m_pNormalWidget->SetDelegate(this); 453 m_pNormalWidget->LockUpdate(); 454 455 CFX_WideString wsText; 456 m_pDataAcc->GetValue(wsText, XFA_VALUEPICTURE_Display); 457 pWidget->SetText(wsText); 458 UpdateWidgetProperty(); 459 m_pNormalWidget->UnlockUpdate(); 460 return CXFA_FFField::LoadWidget(); 461 } 462 void CXFA_FFPasswordEdit::UpdateWidgetProperty() { 463 CFWL_Edit* pWidget = (CFWL_Edit*)m_pNormalWidget; 464 if (!pWidget) { 465 return; 466 } 467 uint32_t dwExtendedStyle = 468 FWL_STYLEEXT_EDT_ShowScrollbarFocus | FWL_STYLEEXT_EDT_OuterScrollbar | 469 FWL_STYLEEXT_EDT_Password | FWL_STYLEEXT_EDT_LastLineHeight; 470 dwExtendedStyle |= UpdateUIProperty(); 471 CFX_WideString wsPassWord; 472 m_pDataAcc->GetPasswordChar(wsPassWord); 473 if (!wsPassWord.IsEmpty()) { 474 pWidget->SetAliasChar(wsPassWord.GetAt(0)); 475 } 476 if (m_pDataAcc->GetHorizontalScrollPolicy() != XFA_ATTRIBUTEENUM_Off) { 477 dwExtendedStyle |= FWL_STYLEEXT_EDT_AutoHScroll; 478 } 479 if (m_pDataAcc->GetAccess() != XFA_ATTRIBUTEENUM_Open || 480 !m_pDataAcc->GetDoc()->GetXFADoc()->IsInteractive()) { 481 dwExtendedStyle |= FWL_STYLEEXT_EDT_ReadOnly; 482 } 483 dwExtendedStyle |= GetAlignment(); 484 m_pNormalWidget->ModifyStylesEx(dwExtendedStyle, 0xFFFFFFFF); 485 } 486 CXFA_FFDateTimeEdit::CXFA_FFDateTimeEdit(CXFA_WidgetAcc* pDataAcc) 487 : CXFA_FFTextEdit(pDataAcc) {} 488 489 CXFA_FFDateTimeEdit::~CXFA_FFDateTimeEdit() {} 490 491 CFX_RectF CXFA_FFDateTimeEdit::GetBBox(uint32_t dwStatus, bool bDrawFocus) { 492 if (bDrawFocus) 493 return CFX_RectF(); 494 return CXFA_FFWidget::GetBBox(dwStatus); 495 } 496 497 bool CXFA_FFDateTimeEdit::PtInActiveRect(const CFX_PointF& point) { 498 return m_pNormalWidget && 499 static_cast<CFWL_DateTimePicker*>(m_pNormalWidget) 500 ->GetBBox() 501 .Contains(point); 502 } 503 504 bool CXFA_FFDateTimeEdit::LoadWidget() { 505 CFWL_DateTimePicker* pWidget = new CFWL_DateTimePicker(GetFWLApp()); 506 m_pNormalWidget = pWidget; 507 m_pNormalWidget->SetLayoutItem(this); 508 CFWL_NoteDriver* pNoteDriver = 509 m_pNormalWidget->GetOwnerApp()->GetNoteDriver(); 510 pNoteDriver->RegisterEventTarget(m_pNormalWidget, m_pNormalWidget); 511 512 m_pOldDelegate = m_pNormalWidget->GetDelegate(); 513 m_pNormalWidget->SetDelegate(this); 514 m_pNormalWidget->LockUpdate(); 515 516 CFX_WideString wsText; 517 m_pDataAcc->GetValue(wsText, XFA_VALUEPICTURE_Display); 518 pWidget->SetEditText(wsText); 519 if (CXFA_Value value = m_pDataAcc->GetFormValue()) { 520 switch (value.GetChildValueClassID()) { 521 case XFA_Element::Date: { 522 if (!wsText.IsEmpty()) { 523 CXFA_LocaleValue lcValue = XFA_GetLocaleValue(m_pDataAcc); 524 CFX_Unitime date = lcValue.GetDate(); 525 if ((FX_UNITIME)date != 0) { 526 pWidget->SetCurSel(date.GetYear(), date.GetMonth(), date.GetDay()); 527 } 528 } 529 } break; 530 default: 531 break; 532 } 533 } 534 UpdateWidgetProperty(); 535 m_pNormalWidget->UnlockUpdate(); 536 return CXFA_FFField::LoadWidget(); 537 } 538 void CXFA_FFDateTimeEdit::UpdateWidgetProperty() { 539 CFWL_DateTimePicker* pWidget = (CFWL_DateTimePicker*)m_pNormalWidget; 540 if (!pWidget) { 541 return; 542 } 543 uint32_t dwExtendedStyle = FWL_STYLEEXT_DTP_ShortDateFormat; 544 dwExtendedStyle |= UpdateUIProperty(); 545 dwExtendedStyle |= GetAlignment(); 546 m_pNormalWidget->ModifyStylesEx(dwExtendedStyle, 0xFFFFFFFF); 547 uint32_t dwEditStyles = FWL_STYLEEXT_EDT_LastLineHeight; 548 int32_t iNumCells = m_pDataAcc->GetNumberOfCells(); 549 if (iNumCells > 0) { 550 dwEditStyles |= FWL_STYLEEXT_EDT_CombText; 551 pWidget->SetEditLimit(iNumCells); 552 } 553 if (m_pDataAcc->GetAccess() != XFA_ATTRIBUTEENUM_Open || 554 !m_pDataAcc->GetDoc()->GetXFADoc()->IsInteractive()) { 555 dwEditStyles |= FWL_STYLEEXT_EDT_ReadOnly; 556 } 557 if (m_pDataAcc->GetHorizontalScrollPolicy() != XFA_ATTRIBUTEENUM_Off) { 558 dwEditStyles |= FWL_STYLEEXT_EDT_AutoHScroll; 559 } 560 pWidget->ModifyEditStylesEx(dwEditStyles, 0xFFFFFFFF); 561 } 562 uint32_t CXFA_FFDateTimeEdit::GetAlignment() { 563 uint32_t dwExtendedStyle = 0; 564 if (CXFA_Para para = m_pDataAcc->GetPara()) { 565 int32_t iHorz = para.GetHorizontalAlign(); 566 switch (iHorz) { 567 case XFA_ATTRIBUTEENUM_Center: 568 dwExtendedStyle |= FWL_STYLEEXT_DTP_EditHCenter; 569 break; 570 case XFA_ATTRIBUTEENUM_Justify: 571 dwExtendedStyle |= FWL_STYLEEXT_DTP_EditJustified; 572 break; 573 case XFA_ATTRIBUTEENUM_JustifyAll: 574 break; 575 case XFA_ATTRIBUTEENUM_Radix: 576 break; 577 case XFA_ATTRIBUTEENUM_Right: 578 dwExtendedStyle |= FWL_STYLEEXT_DTP_EditHFar; 579 break; 580 default: 581 dwExtendedStyle |= FWL_STYLEEXT_DTP_EditHNear; 582 break; 583 } 584 int32_t iVert = para.GetVerticalAlign(); 585 switch (iVert) { 586 case XFA_ATTRIBUTEENUM_Middle: 587 dwExtendedStyle |= FWL_STYLEEXT_DTP_EditVCenter; 588 break; 589 case XFA_ATTRIBUTEENUM_Bottom: 590 dwExtendedStyle |= FWL_STYLEEXT_DTP_EditVFar; 591 break; 592 default: 593 dwExtendedStyle |= FWL_STYLEEXT_DTP_EditVNear; 594 break; 595 } 596 } 597 return dwExtendedStyle; 598 } 599 bool CXFA_FFDateTimeEdit::CommitData() { 600 CFX_WideString wsText = 601 static_cast<CFWL_DateTimePicker*>(m_pNormalWidget)->GetEditText(); 602 if (m_pDataAcc->SetValue(wsText, XFA_VALUEPICTURE_Edit)) { 603 m_pDataAcc->UpdateUIDisplay(this); 604 return true; 605 } 606 return false; 607 } 608 bool CXFA_FFDateTimeEdit::UpdateFWLData() { 609 if (!m_pNormalWidget) { 610 return false; 611 } 612 XFA_VALUEPICTURE eType = XFA_VALUEPICTURE_Display; 613 if (IsFocused()) { 614 eType = XFA_VALUEPICTURE_Edit; 615 } 616 CFX_WideString wsText; 617 m_pDataAcc->GetValue(wsText, eType); 618 ((CFWL_DateTimePicker*)m_pNormalWidget)->SetEditText(wsText); 619 if (IsFocused() && !wsText.IsEmpty()) { 620 CXFA_LocaleValue lcValue = XFA_GetLocaleValue(m_pDataAcc); 621 CFX_Unitime date = lcValue.GetDate(); 622 if (lcValue.IsValid()) { 623 if ((FX_UNITIME)date != 0) { 624 ((CFWL_DateTimePicker*)m_pNormalWidget) 625 ->SetCurSel(date.GetYear(), date.GetMonth(), date.GetDay()); 626 } 627 } 628 } 629 m_pNormalWidget->Update(); 630 return true; 631 } 632 bool CXFA_FFDateTimeEdit::IsDataChanged() { 633 if (m_dwStatus & XFA_WidgetStatus_TextEditValueChanged) { 634 return true; 635 } 636 CFX_WideString wsText = 637 static_cast<CFWL_DateTimePicker*>(m_pNormalWidget)->GetEditText(); 638 CFX_WideString wsOldValue; 639 m_pDataAcc->GetValue(wsOldValue, XFA_VALUEPICTURE_Edit); 640 return wsOldValue != wsText; 641 } 642 643 void CXFA_FFDateTimeEdit::OnSelectChanged(CFWL_Widget* pWidget, 644 int32_t iYear, 645 int32_t iMonth, 646 int32_t iDay) { 647 CFX_WideString wsPicture; 648 m_pDataAcc->GetPictureContent(wsPicture, XFA_VALUEPICTURE_Edit); 649 CXFA_LocaleValue date(XFA_VT_DATE, GetDoc()->GetXFADoc()->GetLocalMgr()); 650 CFX_Unitime dt; 651 dt.Set(iYear, iMonth, iDay); 652 date.SetDate(dt); 653 CFX_WideString wsDate; 654 date.FormatPatterns(wsDate, wsPicture, m_pDataAcc->GetLocal(), 655 XFA_VALUEPICTURE_Edit); 656 CFWL_DateTimePicker* pDateTime = (CFWL_DateTimePicker*)m_pNormalWidget; 657 pDateTime->SetEditText(wsDate); 658 pDateTime->Update(); 659 GetDoc()->GetDocEnvironment()->SetFocusWidget(GetDoc(), nullptr); 660 CXFA_EventParam eParam; 661 eParam.m_eType = XFA_EVENT_Change; 662 eParam.m_pTarget = m_pDataAcc; 663 m_pDataAcc->GetValue(eParam.m_wsNewText, XFA_VALUEPICTURE_Raw); 664 m_pDataAcc->ProcessEvent(XFA_ATTRIBUTEENUM_Change, &eParam); 665 } 666 667 void CXFA_FFDateTimeEdit::OnProcessEvent(CFWL_Event* pEvent) { 668 if (pEvent->GetType() == CFWL_Event::Type::SelectChanged) { 669 CFWL_EventSelectChanged* event = 670 static_cast<CFWL_EventSelectChanged*>(pEvent); 671 OnSelectChanged(m_pNormalWidget, event->iYear, event->iMonth, event->iDay); 672 return; 673 } 674 CXFA_FFTextEdit::OnProcessEvent(pEvent); 675 } 676