From 88008a2be11ccbb5001dc540e96024a9641e4915 Mon Sep 17 00:00:00 2001 From: Dan Sinclair Date: Thu, 20 Apr 2017 16:11:14 -0400 Subject: Cleanup some XFA widget code This CL cleans up the nits in some of the XFA widget files. Change-Id: If72e7855a09a22b2ec8ad3ce297b142ce35f71c9 Reviewed-on: https://pdfium-review.googlesource.com/4395 Commit-Queue: dsinclair Reviewed-by: Tom Sepez --- xfa/fxfa/app/xfa_ffcheckbutton.cpp | 75 ++++++----- xfa/fxfa/app/xfa_ffcheckbutton.h | 2 +- xfa/fxfa/app/xfa_ffchoicelist.cpp | 227 +++++++++++++++++--------------- xfa/fxfa/app/xfa_ffchoicelist.h | 7 +- xfa/fxfa/app/xfa_fffield.cpp | 260 ++++++++++++++++++++----------------- xfa/fxfa/app/xfa_fffield.h | 4 +- 6 files changed, 316 insertions(+), 259 deletions(-) diff --git a/xfa/fxfa/app/xfa_ffcheckbutton.cpp b/xfa/fxfa/app/xfa_ffcheckbutton.cpp index bc4eda0e35..9837e0aa7b 100644 --- a/xfa/fxfa/app/xfa_ffcheckbutton.cpp +++ b/xfa/fxfa/app/xfa_ffcheckbutton.cpp @@ -80,20 +80,22 @@ void CXFA_FFCheckButton::UpdateWidgetProperty() { } } break; } - if (m_pDataAcc->IsAllowNeutral()) { + if (m_pDataAcc->IsAllowNeutral()) dwStyleEx |= FWL_STYLEEXT_CKB_3State; - } + pCheckBox->ModifyStylesEx( dwStyleEx, FWL_STYLEEXT_CKB_SignShapeMask | FWL_STYLEEXT_CKB_3State); } + bool CXFA_FFCheckButton::PerformLayout() { CXFA_FFWidget::PerformLayout(); + float fCheckSize = m_pDataAcc->GetCheckButtonSize(); CXFA_Margin mgWidget = m_pDataAcc->GetMargin(); CFX_RectF rtWidget = GetRectWithoutRotate(); - if (mgWidget) { + if (mgWidget) XFA_RectWidthoutMargin(rtWidget, mgWidget); - } + int32_t iCapPlacement = -1; float fCapReserve = 0; CXFA_Caption caption = m_pDataAcc->GetCaption(); @@ -110,12 +112,14 @@ bool CXFA_FFCheckButton::PerformLayout() { } } } + int32_t iHorzAlign = XFA_ATTRIBUTEENUM_Left; int32_t iVertAlign = XFA_ATTRIBUTEENUM_Top; if (CXFA_Para para = m_pDataAcc->GetPara()) { iHorzAlign = para.GetHorizontalAlign(); iVertAlign = para.GetVerticalAlign(); } + m_rtUI = rtWidget; CXFA_Margin mgCap = caption.GetMargin(); switch (iCapPlacement) { @@ -124,41 +128,46 @@ bool CXFA_FFCheckButton::PerformLayout() { CapLeftRightPlacement(mgCap); m_rtUI.width -= fCapReserve; m_rtUI.left += fCapReserve; - } break; + break; + } case XFA_ATTRIBUTEENUM_Top: { m_rtCaption.height = fCapReserve; XFA_RectWidthoutMargin(m_rtCaption, mgCap); m_rtUI.height -= fCapReserve; m_rtUI.top += fCapReserve; - } break; + break; + } case XFA_ATTRIBUTEENUM_Right: { m_rtCaption.left = m_rtCaption.right() - fCapReserve; m_rtCaption.width = fCapReserve; CapLeftRightPlacement(mgCap); m_rtUI.width -= fCapReserve; - } break; + break; + } case XFA_ATTRIBUTEENUM_Bottom: { m_rtCaption.top = m_rtCaption.bottom() - fCapReserve; m_rtCaption.height = fCapReserve; XFA_RectWidthoutMargin(m_rtCaption, mgCap); m_rtUI.height -= fCapReserve; - } break; + break; + } case XFA_ATTRIBUTEENUM_Inline: break; default: iHorzAlign = XFA_ATTRIBUTEENUM_Right; break; } - if (iHorzAlign == XFA_ATTRIBUTEENUM_Center) { + + if (iHorzAlign == XFA_ATTRIBUTEENUM_Center) m_rtUI.left += (m_rtUI.width - fCheckSize) / 2; - } else if (iHorzAlign == XFA_ATTRIBUTEENUM_Right) { + else if (iHorzAlign == XFA_ATTRIBUTEENUM_Right) m_rtUI.left = m_rtUI.right() - fCheckSize; - } - if (iVertAlign == XFA_ATTRIBUTEENUM_Middle) { + + if (iVertAlign == XFA_ATTRIBUTEENUM_Middle) m_rtUI.top += (m_rtUI.height - fCheckSize) / 2; - } else if (iVertAlign == XFA_ATTRIBUTEENUM_Bottom) { + else if (iVertAlign == XFA_ATTRIBUTEENUM_Bottom) m_rtUI.top = m_rtUI.bottom() - fCheckSize; - } + m_rtUI.width = fCheckSize; m_rtUI.height = fCheckSize; AddUIMargin(iCapPlacement); @@ -166,31 +175,33 @@ bool CXFA_FFCheckButton::PerformLayout() { CXFA_Border borderUI = m_pDataAcc->GetUIBorder(); if (borderUI) { CXFA_Margin margin = borderUI.GetMargin(); - if (margin) { + if (margin) XFA_RectWidthoutMargin(m_rtUI, margin); - } } + m_rtUI.Normalize(); LayoutCaption(); SetFWLRect(); - if (m_pNormalWidget) { + if (m_pNormalWidget) m_pNormalWidget->Update(); - } + return true; } + void CXFA_FFCheckButton::CapLeftRightPlacement(CXFA_Margin mgCap) { XFA_RectWidthoutMargin(m_rtCaption, mgCap); - if (m_rtCaption.height < 0) { + if (m_rtCaption.height < 0) m_rtCaption.top += m_rtCaption.height; - } if (m_rtCaption.width < 0) { m_rtCaption.left += m_rtCaption.width; m_rtCaption.width = -m_rtCaption.width; } } + void CXFA_FFCheckButton::AddUIMargin(int32_t iCapPlacement) { CFX_RectF rtUIMargin = m_pDataAcc->GetUIMargin(); m_rtUI.top -= rtUIMargin.top / 2 - rtUIMargin.height / 2; + float fLeftAddRight = rtUIMargin.left + rtUIMargin.width; float fTopAddBottom = rtUIMargin.top + rtUIMargin.height; if (m_rtUI.width < fLeftAddRight) { @@ -203,13 +214,14 @@ void CXFA_FFCheckButton::AddUIMargin(int32_t iCapPlacement) { m_rtUI.width += 2 * (fLeftAddRight - m_rtUI.width); } if (m_rtUI.height < fTopAddBottom) { - if (iCapPlacement == XFA_ATTRIBUTEENUM_Right) { + if (iCapPlacement == XFA_ATTRIBUTEENUM_Right) m_rtUI.left -= fTopAddBottom - m_rtUI.height; - } + m_rtUI.top -= fTopAddBottom - m_rtUI.height; m_rtUI.height += 2 * (fTopAddBottom - m_rtUI.height); } } + void CXFA_FFCheckButton::RenderWidget(CFX_Graphics* pGS, CFX_Matrix* pMatrix, uint32_t dwStatus) { @@ -268,20 +280,20 @@ bool CXFA_FFCheckButton::IsDataChanged() { XFA_CHECKSTATE eCheckState = FWLState2XFAState(); return m_pDataAcc->GetCheckState() != eCheckState; } + void CXFA_FFCheckButton::SetFWLCheckState(XFA_CHECKSTATE eCheckState) { - if (eCheckState == XFA_CHECKSTATE_Neutral) { + if (eCheckState == XFA_CHECKSTATE_Neutral) m_pNormalWidget->SetStates(FWL_STATE_CKB_Neutral); - } else { - if (eCheckState == XFA_CHECKSTATE_On) - m_pNormalWidget->SetStates(FWL_STATE_CKB_Checked); - else - m_pNormalWidget->RemoveStates(FWL_STATE_CKB_Checked); - } + else if (eCheckState == XFA_CHECKSTATE_On) + m_pNormalWidget->SetStates(FWL_STATE_CKB_Checked); + else + m_pNormalWidget->RemoveStates(FWL_STATE_CKB_Checked); } + bool CXFA_FFCheckButton::UpdateFWLData() { - if (!m_pNormalWidget) { + if (!m_pNormalWidget) return false; - } + XFA_CHECKSTATE eState = m_pDataAcc->GetCheckState(); SetFWLCheckState(eState); m_pNormalWidget->Update(); @@ -299,6 +311,7 @@ void CXFA_FFCheckButton::OnProcessEvent(CFWL_Event* pEvent) { CXFA_EventParam eParam; eParam.m_eType = XFA_EVENT_Change; m_pDataAcc->GetValue(eParam.m_wsNewText, XFA_VALUEPICTURE_Raw); + CXFA_WidgetAcc* pFFExclGroup = m_pDataAcc->GetExclGroup(); if (ProcessCommittedData()) { eParam.m_pTarget = pFFExclGroup; diff --git a/xfa/fxfa/app/xfa_ffcheckbutton.h b/xfa/fxfa/app/xfa_ffcheckbutton.h index 75f884144d..d4de7e8023 100644 --- a/xfa/fxfa/app/xfa_ffcheckbutton.h +++ b/xfa/fxfa/app/xfa_ffcheckbutton.h @@ -35,10 +35,10 @@ class CXFA_FFCheckButton : public CXFA_FFField { private: bool CommitData() override; bool IsDataChanged() override; - void CapLeftRightPlacement(CXFA_Margin mgCap); void AddUIMargin(int32_t iCapPlacement); XFA_CHECKSTATE FWLState2XFAState(); + IFWL_WidgetDelegate* m_pOldDelegate; CFX_RectF m_rtCheckBox; }; diff --git a/xfa/fxfa/app/xfa_ffchoicelist.cpp b/xfa/fxfa/app/xfa_ffchoicelist.cpp index 061e9aa842..b191f838ce 100644 --- a/xfa/fxfa/app/xfa_ffchoicelist.cpp +++ b/xfa/fxfa/app/xfa_ffchoicelist.cpp @@ -27,15 +27,28 @@ #include "xfa/fxfa/cxfa_ffpageview.h" #include "xfa/fxfa/cxfa_ffwidget.h" +namespace { + +CFWL_ListBox* ToListBox(CFWL_Widget* widget) { + return static_cast(widget); +} + +CFWL_ComboBox* ToComboBox(CFWL_Widget* widget) { + return static_cast(widget); +} + +} // namespace + CXFA_FFListBox::CXFA_FFListBox(CXFA_WidgetAcc* pDataAcc) : CXFA_FFField(pDataAcc), m_pOldDelegate(nullptr) {} CXFA_FFListBox::~CXFA_FFListBox() { - if (m_pNormalWidget) { - CFWL_NoteDriver* pNoteDriver = - m_pNormalWidget->GetOwnerApp()->GetNoteDriver(); - pNoteDriver->UnregisterEventTarget(m_pNormalWidget.get()); - } + if (!m_pNormalWidget) + return; + + CFWL_NoteDriver* pNoteDriver = + m_pNormalWidget->GetOwnerApp()->GetNoteDriver(); + pNoteDriver->UnregisterEventTarget(m_pNormalWidget.get()); } bool CXFA_FFListBox::LoadWidget() { @@ -74,16 +87,18 @@ bool CXFA_FFListBox::LoadWidget() { bool CXFA_FFListBox::OnKillFocus(CXFA_FFWidget* pNewFocus) { if (!ProcessCommittedData()) UpdateFWLData(); + CXFA_FFField::OnKillFocus(pNewFocus); return true; } bool CXFA_FFListBox::CommitData() { - auto* pListBox = static_cast(m_pNormalWidget.get()); + auto* pListBox = ToListBox(m_pNormalWidget.get()); std::vector iSelArray; int32_t iSels = pListBox->CountSelItems(); for (int32_t i = 0; i < iSels; ++i) iSelArray.push_back(pListBox->GetSelIndex(i)); + m_pDataAcc->SetSelectedItems(iSelArray, true, false, true); return true; } @@ -91,7 +106,7 @@ bool CXFA_FFListBox::CommitData() { bool CXFA_FFListBox::IsDataChanged() { std::vector iSelArray = m_pDataAcc->GetSelectedItems(); int32_t iOldSels = pdfium::CollectionSize(iSelArray); - auto* pListBox = static_cast(m_pNormalWidget.get()); + auto* pListBox = ToListBox(m_pNormalWidget.get()); int32_t iSels = pListBox->CountSelItems(); if (iOldSels != iSels) return true; @@ -105,34 +120,36 @@ bool CXFA_FFListBox::IsDataChanged() { } uint32_t CXFA_FFListBox::GetAlignment() { + CXFA_Para para = m_pDataAcc->GetPara(); + if (!para) + return 0; + uint32_t dwExtendedStyle = 0; - if (CXFA_Para para = m_pDataAcc->GetPara()) { - int32_t iHorz = para.GetHorizontalAlign(); - switch (iHorz) { - case XFA_ATTRIBUTEENUM_Center: - dwExtendedStyle |= FWL_STYLEEXT_LTB_CenterAlign; - break; - case XFA_ATTRIBUTEENUM_Justify: - break; - case XFA_ATTRIBUTEENUM_JustifyAll: - break; - case XFA_ATTRIBUTEENUM_Radix: - break; - case XFA_ATTRIBUTEENUM_Right: - dwExtendedStyle |= FWL_STYLEEXT_LTB_RightAlign; - break; - default: - dwExtendedStyle |= FWL_STYLEEXT_LTB_LeftAlign; - break; - } + switch (para.GetHorizontalAlign()) { + case XFA_ATTRIBUTEENUM_Center: + dwExtendedStyle |= FWL_STYLEEXT_LTB_CenterAlign; + break; + case XFA_ATTRIBUTEENUM_Justify: + break; + case XFA_ATTRIBUTEENUM_JustifyAll: + break; + case XFA_ATTRIBUTEENUM_Radix: + break; + case XFA_ATTRIBUTEENUM_Right: + dwExtendedStyle |= FWL_STYLEEXT_LTB_RightAlign; + break; + default: + dwExtendedStyle |= FWL_STYLEEXT_LTB_LeftAlign; + break; } return dwExtendedStyle; } + bool CXFA_FFListBox::UpdateFWLData() { if (!m_pNormalWidget) return false; - auto* pListBox = static_cast(m_pNormalWidget.get()); + auto* pListBox = ToListBox(m_pNormalWidget.get()); std::vector iSelArray = m_pDataAcc->GetSelectedItems(); std::vector selItemArray(iSelArray.size()); std::transform(iSelArray.begin(), iSelArray.end(), selItemArray.begin(), @@ -146,13 +163,13 @@ bool CXFA_FFListBox::UpdateFWLData() { return true; } -void CXFA_FFListBox::OnSelectChanged(CFWL_Widget* pWidget, - const std::vector& arrSels) { +void CXFA_FFListBox::OnSelectChanged(CFWL_Widget* pWidget) { CXFA_EventParam eParam; eParam.m_eType = XFA_EVENT_Change; eParam.m_pTarget = m_pDataAcc; m_pDataAcc->GetValue(eParam.m_wsPrevText, XFA_VALUEPICTURE_Raw); - auto* pListBox = static_cast(m_pNormalWidget.get()); + + auto* pListBox = ToListBox(m_pNormalWidget.get()); int32_t iSels = pListBox->CountSelItems(); if (iSels > 0) { CFWL_ListItem* item = pListBox->GetSelItem(0); @@ -162,7 +179,7 @@ void CXFA_FFListBox::OnSelectChanged(CFWL_Widget* pWidget, } void CXFA_FFListBox::SetItemState(int32_t nIndex, bool bSelected) { - auto* pListBox = static_cast(m_pNormalWidget.get()); + auto* pListBox = ToListBox(m_pNormalWidget.get()); pListBox->SetSelItem(pListBox->GetSelItem(nIndex), bSelected); m_pNormalWidget->Update(); AddInvalidateRect(); @@ -171,14 +188,13 @@ void CXFA_FFListBox::SetItemState(int32_t nIndex, bool bSelected) { void CXFA_FFListBox::InsertItem(const CFX_WideStringC& wsLabel, int32_t nIndex) { CFX_WideString wsTemp(wsLabel); - static_cast(m_pNormalWidget.get()) - ->AddString(wsTemp.AsStringC()); + ToListBox(m_pNormalWidget.get())->AddString(wsTemp.AsStringC()); m_pNormalWidget->Update(); AddInvalidateRect(); } void CXFA_FFListBox::DeleteItem(int32_t nIndex) { - auto* pListBox = static_cast(m_pNormalWidget.get()); + auto* pListBox = ToListBox(m_pNormalWidget.get()); if (nIndex < 0) pListBox->DeleteAll(); else @@ -195,16 +211,15 @@ void CXFA_FFListBox::OnProcessMessage(CFWL_Message* pMessage) { void CXFA_FFListBox::OnProcessEvent(CFWL_Event* pEvent) { CXFA_FFField::OnProcessEvent(pEvent); switch (pEvent->GetType()) { - case CFWL_Event::Type::SelectChanged: { - std::vector arrSels; - OnSelectChanged(m_pNormalWidget.get(), arrSels); + case CFWL_Event::Type::SelectChanged: + OnSelectChanged(m_pNormalWidget.get()); break; - } default: break; } m_pOldDelegate->OnProcessEvent(pEvent); } + void CXFA_FFListBox::OnDrawWidget(CFX_Graphics* pGraphics, const CFX_Matrix* pMatrix) { m_pOldDelegate->OnDrawWidget(pGraphics, pMatrix); @@ -216,13 +231,11 @@ CXFA_FFComboBox::CXFA_FFComboBox(CXFA_WidgetAcc* pDataAcc) CXFA_FFComboBox::~CXFA_FFComboBox() {} CFX_RectF CXFA_FFComboBox::GetBBox(uint32_t dwStatus, bool bDrawFocus) { - if (bDrawFocus) - return CFX_RectF(); - return CXFA_FFWidget::GetBBox(dwStatus); + return bDrawFocus ? CFX_RectF() : CXFA_FFWidget::GetBBox(dwStatus); } bool CXFA_FFComboBox::PtInActiveRect(const CFX_PointF& point) { - auto* pComboBox = static_cast(m_pNormalWidget.get()); + auto* pComboBox = ToComboBox(m_pNormalWidget.get()); return pComboBox && pComboBox->GetBBox().Contains(point); } @@ -251,13 +264,14 @@ bool CXFA_FFComboBox::LoadWidget() { m_pDataAcc->GetValue(wsText, XFA_VALUEPICTURE_Raw); pComboBox->SetEditText(wsText); } + UpdateWidgetProperty(); m_pNormalWidget->UnlockUpdate(); return CXFA_FFField::LoadWidget(); } void CXFA_FFComboBox::UpdateWidgetProperty() { - auto* pComboBox = static_cast(m_pNormalWidget.get()); + auto* pComboBox = ToComboBox(m_pNormalWidget.get()); if (!pComboBox) return; @@ -276,9 +290,10 @@ void CXFA_FFComboBox::UpdateWidgetProperty() { } dwExtendedStyle |= GetAlignment(); m_pNormalWidget->ModifyStylesEx(dwExtendedStyle, 0xFFFFFFFF); - if (m_pDataAcc->GetHorizontalScrollPolicy() != XFA_ATTRIBUTEENUM_Off) { + + if (m_pDataAcc->GetHorizontalScrollPolicy() != XFA_ATTRIBUTEENUM_Off) dwEditStyles |= FWL_STYLEEXT_EDT_AutoHScroll; - } + pComboBox->EditModifyStylesEx(dwEditStyles, 0xFFFFFFFF); } @@ -299,7 +314,7 @@ bool CXFA_FFComboBox::OnKillFocus(CXFA_FFWidget* pNewWidget) { } void CXFA_FFComboBox::OpenDropDownList() { - static_cast(m_pNormalWidget.get())->OpenDropDownList(true); + ToComboBox(m_pNormalWidget.get())->OpenDropDownList(true); } bool CXFA_FFComboBox::CommitData() { @@ -307,7 +322,7 @@ bool CXFA_FFComboBox::CommitData() { } bool CXFA_FFComboBox::IsDataChanged() { - auto* pFWLcombobox = static_cast(m_pNormalWidget.get()); + auto* pFWLcombobox = ToComboBox(m_pNormalWidget.get()); CFX_WideString wsText = pFWLcombobox->GetEditText(); int32_t iCursel = pFWLcombobox->GetCurSel(); if (iCursel >= 0) { @@ -315,6 +330,7 @@ bool CXFA_FFComboBox::IsDataChanged() { if (wsSel == wsText) m_pDataAcc->GetChoiceListItem(wsText, iCursel, true); } + CFX_WideString wsOldValue; m_pDataAcc->GetValue(wsOldValue, XFA_VALUEPICTURE_Raw); if (wsOldValue == wsText) @@ -327,51 +343,52 @@ bool CXFA_FFComboBox::IsDataChanged() { void CXFA_FFComboBox::FWLEventSelChange(CXFA_EventParam* pParam) { pParam->m_eType = XFA_EVENT_Change; pParam->m_pTarget = m_pDataAcc; - auto* pFWLcombobox = static_cast(m_pNormalWidget.get()); - pParam->m_wsNewText = pFWLcombobox->GetEditText(); + pParam->m_wsNewText = ToComboBox(m_pNormalWidget.get())->GetEditText(); m_pDataAcc->ProcessEvent(XFA_ATTRIBUTEENUM_Change, pParam); } + uint32_t CXFA_FFComboBox::GetAlignment() { + CXFA_Para para = m_pDataAcc->GetPara(); + if (!para) + return 0; + uint32_t dwExtendedStyle = 0; - if (CXFA_Para para = m_pDataAcc->GetPara()) { - int32_t iHorz = para.GetHorizontalAlign(); - switch (iHorz) { - case XFA_ATTRIBUTEENUM_Center: - dwExtendedStyle |= - FWL_STYLEEXT_CMB_EditHCenter | FWL_STYLEEXT_CMB_ListItemCenterAlign; - break; - case XFA_ATTRIBUTEENUM_Justify: - dwExtendedStyle |= FWL_STYLEEXT_CMB_EditJustified; - break; - case XFA_ATTRIBUTEENUM_JustifyAll: - break; - case XFA_ATTRIBUTEENUM_Radix: - break; - case XFA_ATTRIBUTEENUM_Right: - break; - default: - dwExtendedStyle |= - FWL_STYLEEXT_CMB_EditHNear | FWL_STYLEEXT_CMB_ListItemLeftAlign; - break; - } - int32_t iVert = para.GetVerticalAlign(); - switch (iVert) { - case XFA_ATTRIBUTEENUM_Middle: - dwExtendedStyle |= FWL_STYLEEXT_CMB_EditVCenter; - break; - case XFA_ATTRIBUTEENUM_Bottom: - dwExtendedStyle |= FWL_STYLEEXT_CMB_EditVFar; - break; - default: - dwExtendedStyle |= FWL_STYLEEXT_CMB_EditVNear; - break; - } + switch (para.GetHorizontalAlign()) { + case XFA_ATTRIBUTEENUM_Center: + dwExtendedStyle |= + FWL_STYLEEXT_CMB_EditHCenter | FWL_STYLEEXT_CMB_ListItemCenterAlign; + break; + case XFA_ATTRIBUTEENUM_Justify: + dwExtendedStyle |= FWL_STYLEEXT_CMB_EditJustified; + break; + case XFA_ATTRIBUTEENUM_JustifyAll: + break; + case XFA_ATTRIBUTEENUM_Radix: + break; + case XFA_ATTRIBUTEENUM_Right: + break; + default: + dwExtendedStyle |= + FWL_STYLEEXT_CMB_EditHNear | FWL_STYLEEXT_CMB_ListItemLeftAlign; + break; + } + + switch (para.GetVerticalAlign()) { + case XFA_ATTRIBUTEENUM_Middle: + dwExtendedStyle |= FWL_STYLEEXT_CMB_EditVCenter; + break; + case XFA_ATTRIBUTEENUM_Bottom: + dwExtendedStyle |= FWL_STYLEEXT_CMB_EditVFar; + break; + default: + dwExtendedStyle |= FWL_STYLEEXT_CMB_EditVNear; + break; } return dwExtendedStyle; } bool CXFA_FFComboBox::UpdateFWLData() { - auto* pComboBox = static_cast(m_pNormalWidget.get()); + auto* pComboBox = ToComboBox(m_pNormalWidget.get()); if (!pComboBox) return false; @@ -390,32 +407,32 @@ bool CXFA_FFComboBox::UpdateFWLData() { bool CXFA_FFComboBox::CanUndo() { return m_pDataAcc->IsChoiceListAllowTextEntry() && - static_cast(m_pNormalWidget.get())->EditCanUndo(); + ToComboBox(m_pNormalWidget.get())->EditCanUndo(); } bool CXFA_FFComboBox::CanRedo() { return m_pDataAcc->IsChoiceListAllowTextEntry() && - static_cast(m_pNormalWidget.get())->EditCanRedo(); + ToComboBox(m_pNormalWidget.get())->EditCanRedo(); } bool CXFA_FFComboBox::Undo() { return m_pDataAcc->IsChoiceListAllowTextEntry() && - static_cast(m_pNormalWidget.get())->EditUndo(); + ToComboBox(m_pNormalWidget.get())->EditUndo(); } bool CXFA_FFComboBox::Redo() { return m_pDataAcc->IsChoiceListAllowTextEntry() && - static_cast(m_pNormalWidget.get())->EditRedo(); + ToComboBox(m_pNormalWidget.get())->EditRedo(); } bool CXFA_FFComboBox::CanCopy() { - return static_cast(m_pNormalWidget.get())->EditCanCopy(); + return ToComboBox(m_pNormalWidget.get())->EditCanCopy(); } bool CXFA_FFComboBox::CanCut() { return m_pDataAcc->GetAccess() == XFA_ATTRIBUTEENUM_Open && m_pDataAcc->IsChoiceListAllowTextEntry() && - static_cast(m_pNormalWidget.get())->EditCanCut(); + ToComboBox(m_pNormalWidget.get())->EditCanCut(); } bool CXFA_FFComboBox::CanPaste() { @@ -424,55 +441,54 @@ bool CXFA_FFComboBox::CanPaste() { } bool CXFA_FFComboBox::CanSelectAll() { - return static_cast(m_pNormalWidget.get())->EditCanSelectAll(); + return ToComboBox(m_pNormalWidget.get())->EditCanSelectAll(); } bool CXFA_FFComboBox::Copy(CFX_WideString& wsCopy) { - return static_cast(m_pNormalWidget.get())->EditCopy(wsCopy); + return ToComboBox(m_pNormalWidget.get())->EditCopy(wsCopy); } bool CXFA_FFComboBox::Cut(CFX_WideString& wsCut) { return m_pDataAcc->IsChoiceListAllowTextEntry() && - static_cast(m_pNormalWidget.get())->EditCut(wsCut); + ToComboBox(m_pNormalWidget.get())->EditCut(wsCut); } bool CXFA_FFComboBox::Paste(const CFX_WideString& wsPaste) { return m_pDataAcc->IsChoiceListAllowTextEntry() && - static_cast(m_pNormalWidget.get())->EditPaste(wsPaste); + ToComboBox(m_pNormalWidget.get())->EditPaste(wsPaste); } void CXFA_FFComboBox::SelectAll() { - static_cast(m_pNormalWidget.get())->EditSelectAll(); + ToComboBox(m_pNormalWidget.get())->EditSelectAll(); } void CXFA_FFComboBox::Delete() { - static_cast(m_pNormalWidget.get())->EditDelete(); + ToComboBox(m_pNormalWidget.get())->EditDelete(); } void CXFA_FFComboBox::DeSelect() { - static_cast(m_pNormalWidget.get())->EditDeSelect(); + ToComboBox(m_pNormalWidget.get())->EditDeSelect(); } void CXFA_FFComboBox::SetItemState(int32_t nIndex, bool bSelected) { - static_cast(m_pNormalWidget.get()) - ->SetCurSel(bSelected ? nIndex : -1); + ToComboBox(m_pNormalWidget.get())->SetCurSel(bSelected ? nIndex : -1); m_pNormalWidget->Update(); AddInvalidateRect(); } void CXFA_FFComboBox::InsertItem(const CFX_WideStringC& wsLabel, int32_t nIndex) { - static_cast(m_pNormalWidget.get())->AddString(wsLabel); + ToComboBox(m_pNormalWidget.get())->AddString(wsLabel); m_pNormalWidget->Update(); AddInvalidateRect(); } void CXFA_FFComboBox::DeleteItem(int32_t nIndex) { - if (nIndex < 0) { - static_cast(m_pNormalWidget.get())->RemoveAll(); - } else { - static_cast(m_pNormalWidget.get())->RemoveAt(nIndex); - } + if (nIndex < 0) + ToComboBox(m_pNormalWidget.get())->RemoveAll(); + else + ToComboBox(m_pNormalWidget.get())->RemoveAt(nIndex); + m_pNormalWidget->Update(); AddInvalidateRect(); } @@ -484,6 +500,7 @@ void CXFA_FFComboBox::OnTextChanged(CFWL_Widget* pWidget, eParam.m_wsChange = wsChanged; FWLEventSelChange(&eParam); } + void CXFA_FFComboBox::OnSelectChanged(CFWL_Widget* pWidget, bool bLButtonUp) { CXFA_EventParam eParam; m_pDataAcc->GetValue(eParam.m_wsPrevText, XFA_VALUEPICTURE_Raw); @@ -493,12 +510,14 @@ void CXFA_FFComboBox::OnSelectChanged(CFWL_Widget* pWidget, bool bLButtonUp) { m_pDocView->SetFocusWidgetAcc(nullptr); } } + void CXFA_FFComboBox::OnPreOpen(CFWL_Widget* pWidget) { CXFA_EventParam eParam; eParam.m_eType = XFA_EVENT_PreOpen; eParam.m_pTarget = m_pDataAcc; m_pDataAcc->ProcessEvent(XFA_ATTRIBUTEENUM_PreOpen, &eParam); } + void CXFA_FFComboBox::OnPostOpen(CFWL_Widget* pWidget) { CXFA_EventParam eParam; eParam.m_eType = XFA_EVENT_PostOpen; diff --git a/xfa/fxfa/app/xfa_ffchoicelist.h b/xfa/fxfa/app/xfa_ffchoicelist.h index 8875655901..20f053cc20 100644 --- a/xfa/fxfa/app/xfa_ffchoicelist.h +++ b/xfa/fxfa/app/xfa_ffchoicelist.h @@ -25,10 +25,9 @@ class CXFA_FFListBox : public CXFA_FFField { void OnDrawWidget(CFX_Graphics* pGraphics, const CFX_Matrix* pMatrix = nullptr) override; - void OnSelectChanged(CFWL_Widget* pWidget, - const std::vector& arrSels); + void OnSelectChanged(CFWL_Widget* pWidget); void SetItemState(int32_t nIndex, bool bSelected); - void InsertItem(const CFX_WideStringC& wsLabel, int32_t nIndex = -1); + void InsertItem(const CFX_WideStringC& wsLabel, int32_t nIndex); void DeleteItem(int32_t nIndex); private: @@ -81,7 +80,7 @@ class CXFA_FFComboBox : public CXFA_FFField { void OnPreOpen(CFWL_Widget* pWidget); void OnPostOpen(CFWL_Widget* pWidget); void SetItemState(int32_t nIndex, bool bSelected); - void InsertItem(const CFX_WideStringC& wsLabel, int32_t nIndex = -1); + void InsertItem(const CFX_WideStringC& wsLabel, int32_t nIndex); void DeleteItem(int32_t nIndex); private: diff --git a/xfa/fxfa/app/xfa_fffield.cpp b/xfa/fxfa/app/xfa_fffield.cpp index a480b3991f..186f573182 100644 --- a/xfa/fxfa/app/xfa_fffield.cpp +++ b/xfa/fxfa/app/xfa_fffield.cpp @@ -26,6 +26,14 @@ #include "xfa/fxgraphics/cfx_color.h" #include "xfa/fxgraphics/cfx_path.h" +namespace { + +CXFA_FFField* ToField(CXFA_LayoutItem* widget) { + return static_cast(widget); +} + +} // namespace + CXFA_FFField::CXFA_FFField(CXFA_WidgetAcc* pDataAcc) : CXFA_FFWidget(pDataAcc), m_pNormalWidget(nullptr) {} @@ -71,47 +79,56 @@ void CXFA_FFField::RenderWidget(CFX_Graphics* pGS, GetApp()->GetWidgetMgrDelegate()->OnDrawWidget(m_pNormalWidget.get(), pGS, &mt); } + void CXFA_FFField::DrawHighlight(CFX_Graphics* pGS, CFX_Matrix* pMatrix, uint32_t dwStatus, bool bEllipse) { - if (m_rtUI.IsEmpty() || !m_pDataAcc->GetDoc()->GetXFADoc()->IsInteractive()) { + if (m_rtUI.IsEmpty() || !m_pDataAcc->GetDoc()->GetXFADoc()->IsInteractive()) + return; + + if (!(dwStatus & XFA_WidgetStatus_Highlight) || + m_pDataAcc->GetAccess() != XFA_ATTRIBUTEENUM_Open) { return; } - if ((dwStatus & XFA_WidgetStatus_Highlight) && - m_pDataAcc->GetAccess() == XFA_ATTRIBUTEENUM_Open) { - CXFA_FFDoc* pDoc = GetDoc(); - CFX_Color crHighlight(pDoc->GetDocEnvironment()->GetHighlightColor(pDoc)); - pGS->SetFillColor(&crHighlight); - CFX_Path path; - if (bEllipse) - path.AddEllipse(m_rtUI); - else - path.AddRectangle(m_rtUI.left, m_rtUI.top, m_rtUI.width, m_rtUI.height); - - pGS->FillPath(&path, FXFILL_WINDING, pMatrix); - } + + CXFA_FFDoc* pDoc = GetDoc(); + CFX_Color crHighlight(pDoc->GetDocEnvironment()->GetHighlightColor(pDoc)); + pGS->SetFillColor(&crHighlight); + CFX_Path path; + if (bEllipse) + path.AddEllipse(m_rtUI); + else + path.AddRectangle(m_rtUI.left, m_rtUI.top, m_rtUI.width, m_rtUI.height); + + pGS->FillPath(&path, FXFILL_WINDING, pMatrix); } + void CXFA_FFField::DrawFocus(CFX_Graphics* pGS, CFX_Matrix* pMatrix) { - if (m_dwStatus & XFA_WidgetStatus_Focused) { - CFX_Color cr(0xFF000000); - pGS->SetStrokeColor(&cr); - float DashPattern[2] = {1, 1}; - pGS->SetLineDash(0.0f, DashPattern, 2); - pGS->SetLineWidth(0, false); - - CFX_Path path; - path.AddRectangle(m_rtUI.left, m_rtUI.top, m_rtUI.width, m_rtUI.height); - pGS->StrokePath(&path, pMatrix); - } + if (!(m_dwStatus & XFA_WidgetStatus_Focused)) + return; + + CFX_Color cr(0xFF000000); + pGS->SetStrokeColor(&cr); + + float DashPattern[2] = {1, 1}; + pGS->SetLineDash(0.0f, DashPattern, 2); + pGS->SetLineWidth(0, false); + + CFX_Path path; + path.AddRectangle(m_rtUI.left, m_rtUI.top, m_rtUI.width, m_rtUI.height); + pGS->StrokePath(&path, pMatrix); } + void CXFA_FFField::SetFWLThemeProvider() { if (m_pNormalWidget) m_pNormalWidget->SetThemeProvider(GetApp()->GetFWLTheme()); } + bool CXFA_FFField::IsLoaded() { return m_pNormalWidget && CXFA_FFWidget::IsLoaded(); } + bool CXFA_FFField::LoadWidget() { SetFWLThemeProvider(); m_pDataAcc->LoadCaption(); @@ -125,21 +142,24 @@ void CXFA_FFField::UnloadWidget() { void CXFA_FFField::SetEditScrollOffset() { XFA_Element eType = m_pDataAcc->GetUIType(); - if (eType == XFA_Element::TextEdit || eType == XFA_Element::NumericEdit || - eType == XFA_Element::PasswordEdit) { - float fScrollOffset = 0; - CXFA_FFField* pPrev = static_cast(GetPrev()); - if (pPrev) { - CFX_RectF rtMargin = m_pDataAcc->GetUIMargin(); - fScrollOffset = -rtMargin.top; - } - while (pPrev) { - fScrollOffset += pPrev->m_rtUI.height; - pPrev = static_cast(pPrev->GetPrev()); - } - static_cast(m_pNormalWidget.get()) - ->SetScrollOffset(fScrollOffset); + if (eType != XFA_Element::TextEdit && eType != XFA_Element::NumericEdit && + eType != XFA_Element::PasswordEdit) { + return; + } + + float fScrollOffset = 0; + CXFA_FFField* pPrev = ToField(GetPrev()); + if (pPrev) { + CFX_RectF rtMargin = m_pDataAcc->GetUIMargin(); + fScrollOffset = -rtMargin.top; } + + while (pPrev) { + fScrollOffset += pPrev->m_rtUI.height; + pPrev = ToField(pPrev->GetPrev()); + } + static_cast(m_pNormalWidget.get()) + ->SetScrollOffset(fScrollOffset); } bool CXFA_FFField::PerformLayout() { @@ -199,6 +219,7 @@ void CXFA_FFField::CapPlacement() { } XFA_RectWidthoutMargin(m_rtCaption, mgWidget); } + CXFA_TextLayout* pCapTextLayout = m_pDataAcc->GetCaptionTextLayout(); if (fCapReserve <= 0 && pCapTextLayout) { CFX_SizeF size; @@ -214,6 +235,7 @@ void CXFA_FFField::CapPlacement() { } } } + m_rtUI = rtWidget; switch (iCapPlacement) { case XFA_ATTRIBUTEENUM_Left: { @@ -221,39 +243,44 @@ void CXFA_FFField::CapPlacement() { CapLeftRightPlacement(caption, rtWidget, iCapPlacement); m_rtUI.width -= fCapReserve; m_rtUI.left += fCapReserve; - } break; + break; + } case XFA_ATTRIBUTEENUM_Top: { m_rtCaption.height = fCapReserve; CapTopBottomPlacement(caption, rtWidget, iCapPlacement); m_rtUI.top += fCapReserve; m_rtUI.height -= fCapReserve; - } break; + break; + } case XFA_ATTRIBUTEENUM_Right: { m_rtCaption.left = m_rtCaption.right() - fCapReserve; m_rtCaption.width = fCapReserve; CapLeftRightPlacement(caption, rtWidget, iCapPlacement); m_rtUI.width -= fCapReserve; - } break; + break; + } case XFA_ATTRIBUTEENUM_Bottom: { m_rtCaption.top = m_rtCaption.bottom() - fCapReserve; m_rtCaption.height = fCapReserve; CapTopBottomPlacement(caption, rtWidget, iCapPlacement); m_rtUI.height -= fCapReserve; - } break; + break; + } case XFA_ATTRIBUTEENUM_Inline: break; default: break; } + CXFA_Border borderUI = m_pDataAcc->GetUIBorder(); if (borderUI) { CXFA_Margin margin = borderUI.GetMargin(); - if (margin) { + if (margin) XFA_RectWidthoutMargin(m_rtUI, margin); - } } m_rtUI.Normalize(); } + void CXFA_FFField::CapTopBottomPlacement(CXFA_Caption caption, const CFX_RectF& rtWidget, int32_t iCapPlacement) { @@ -261,25 +288,25 @@ void CXFA_FFField::CapTopBottomPlacement(CXFA_Caption caption, m_rtCaption.left += rtUIMargin.left; if (CXFA_Margin mgCap = caption.GetMargin()) { XFA_RectWidthoutMargin(m_rtCaption, mgCap); - if (m_rtCaption.height < 0) { + if (m_rtCaption.height < 0) m_rtCaption.top += m_rtCaption.height; - } } + float fWidth = rtUIMargin.left + rtUIMargin.width; float fHeight = m_rtCaption.height + rtUIMargin.top + rtUIMargin.height; - if (fWidth > rtWidget.width) { + if (fWidth > rtWidget.width) m_rtUI.width += fWidth - rtWidget.width; - } + if (fHeight == XFA_DEFAULTUI_HEIGHT && m_rtUI.height < XFA_MINUI_HEIGHT) { m_rtUI.height = XFA_MINUI_HEIGHT; m_rtCaption.top += rtUIMargin.top + rtUIMargin.height; } else if (fHeight > rtWidget.height) { m_rtUI.height += fHeight - rtWidget.height; - if (iCapPlacement == XFA_ATTRIBUTEENUM_Bottom) { + if (iCapPlacement == XFA_ATTRIBUTEENUM_Bottom) m_rtCaption.top += fHeight - rtWidget.height; - } } } + void CXFA_FFField::CapLeftRightPlacement(CXFA_Caption caption, const CFX_RectF& rtWidget, int32_t iCapPlacement) { @@ -288,18 +315,18 @@ void CXFA_FFField::CapLeftRightPlacement(CXFA_Caption caption, m_rtCaption.height -= rtUIMargin.top; if (CXFA_Margin mgCap = caption.GetMargin()) { XFA_RectWidthoutMargin(m_rtCaption, mgCap); - if (m_rtCaption.height < 0) { + if (m_rtCaption.height < 0) m_rtCaption.top += m_rtCaption.height; - } } + float fWidth = m_rtCaption.width + rtUIMargin.left + rtUIMargin.width; float fHeight = rtUIMargin.top + rtUIMargin.height; if (fWidth > rtWidget.width) { m_rtUI.width += fWidth - rtWidget.width; - if (iCapPlacement == XFA_ATTRIBUTEENUM_Right) { + if (iCapPlacement == XFA_ATTRIBUTEENUM_Right) m_rtCaption.left += fWidth - rtWidget.width; - } } + if (fHeight == XFA_DEFAULTUI_HEIGHT && m_rtUI.height < XFA_MINUI_HEIGHT) { m_rtUI.height = XFA_MINUI_HEIGHT; m_rtCaption.top += rtUIMargin.top + rtUIMargin.height; @@ -315,11 +342,9 @@ void CXFA_FFField::UpdateFWL() { uint32_t CXFA_FFField::UpdateUIProperty() { CXFA_Node* pUiNode = m_pDataAcc->GetUIChild(); - uint32_t dwStyle = 0; if (pUiNode && pUiNode->GetElementType() == XFA_Element::DefaultUi) - dwStyle = FWL_STYLEEXT_EDT_ReadOnly; - - return dwStyle; + return FWL_STYLEEXT_EDT_ReadOnly; + return 0; } void CXFA_FFField::SetFWLRect() { @@ -620,100 +645,101 @@ bool CXFA_FFField::ProcessCommittedData() { int32_t CXFA_FFField::CalculateOverride() { CXFA_WidgetAcc* pAcc = m_pDataAcc->GetExclGroup(); - if (!pAcc) { + if (!pAcc) return CalculateWidgetAcc(m_pDataAcc); - } - if (CalculateWidgetAcc(pAcc) == 0) { + if (CalculateWidgetAcc(pAcc) == 0) return 0; - } + CXFA_Node* pNode = pAcc->GetExclGroupFirstMember(); - if (!pNode) { + if (!pNode) return 1; - } + CXFA_WidgetAcc* pWidgetAcc = nullptr; while (pNode) { pWidgetAcc = static_cast(pNode->GetWidgetData()); - if (!pWidgetAcc) { + if (!pWidgetAcc) return 1; - } - if (CalculateWidgetAcc(pWidgetAcc) == 0) { + if (CalculateWidgetAcc(pWidgetAcc) == 0) return 0; - } + pNode = pWidgetAcc->GetExclGroupNextMember(pNode); } return 1; } + int32_t CXFA_FFField::CalculateWidgetAcc(CXFA_WidgetAcc* pAcc) { CXFA_Calculate calc = pAcc->GetCalculate(); - if (!calc) { + if (!calc) return 1; - } + XFA_VERSION version = pAcc->GetDoc()->GetXFADoc()->GetCurVersionMode(); - if (calc) { - int32_t iOverride = calc.GetOverride(); - switch (iOverride) { - case XFA_ATTRIBUTEENUM_Error: { - if (version <= XFA_VERSION_204) { - return 1; - } - IXFA_AppProvider* pAppProvider = GetApp()->GetAppProvider(); - if (pAppProvider) { - pAppProvider->MsgBox(L"You are not allowed to modify this field.", - L"Calculate Override", XFA_MBICON_Warning, - XFA_MB_OK); - } + switch (calc.GetOverride()) { + case XFA_ATTRIBUTEENUM_Error: { + if (version <= XFA_VERSION_204) + return 1; + + IXFA_AppProvider* pAppProvider = GetApp()->GetAppProvider(); + if (pAppProvider) { + pAppProvider->MsgBox(L"You are not allowed to modify this field.", + L"Calculate Override", XFA_MBICON_Warning, + XFA_MB_OK); } - return 0; - case XFA_ATTRIBUTEENUM_Warning: { - if (version <= XFA_VERSION_204) { - CXFA_Script script = calc.GetScript(); - if (!script) { - return 1; - } - CFX_WideString wsExpression; - script.GetExpression(wsExpression); - if (wsExpression.IsEmpty()) { - return 1; - } - } - if (pAcc->GetNode()->IsUserInteractive()) + return 0; + } + case XFA_ATTRIBUTEENUM_Warning: { + if (version <= XFA_VERSION_204) { + CXFA_Script script = calc.GetScript(); + if (!script) return 1; - IXFA_AppProvider* pAppProvider = GetApp()->GetAppProvider(); - if (pAppProvider) { - CFX_WideString wsMessage; - calc.GetMessageText(wsMessage); - if (!wsMessage.IsEmpty()) - wsMessage += L"\r\n"; - wsMessage += L"Are you sure you want to modify this field?"; - if (pAppProvider->MsgBox(wsMessage, L"Calculate Override", - XFA_MBICON_Warning, - XFA_MB_YesNo) == XFA_IDYes) { - pAcc->GetNode()->SetFlag(XFA_NodeFlag_UserInteractive, false); - return 1; - } - } - return 0; + CFX_WideString wsExpression; + script.GetExpression(wsExpression); + if (wsExpression.IsEmpty()) + return 1; } - case XFA_ATTRIBUTEENUM_Ignore: + + if (pAcc->GetNode()->IsUserInteractive()) + return 1; + + IXFA_AppProvider* pAppProvider = GetApp()->GetAppProvider(); + if (!pAppProvider) return 0; - case XFA_ATTRIBUTEENUM_Disabled: + + CFX_WideString wsMessage; + calc.GetMessageText(wsMessage); + if (!wsMessage.IsEmpty()) + wsMessage += L"\r\n"; + + wsMessage += L"Are you sure you want to modify this field?"; + if (pAppProvider->MsgBox(wsMessage, L"Calculate Override", + XFA_MBICON_Warning, XFA_MB_YesNo) == XFA_IDYes) { pAcc->GetNode()->SetFlag(XFA_NodeFlag_UserInteractive, false); - default: return 1; + } + return 0; } + case XFA_ATTRIBUTEENUM_Ignore: + return 0; + case XFA_ATTRIBUTEENUM_Disabled: + pAcc->GetNode()->SetFlag(XFA_NodeFlag_UserInteractive, false); + return 1; + default: + return 1; } - return 1; } + bool CXFA_FFField::CommitData() { return false; } + bool CXFA_FFField::IsDataChanged() { return false; } + void CXFA_FFField::TranslateFWLMessage(CFWL_Message* pMessage) { GetApp()->GetWidgetMgrDelegate()->OnProcessMessageToForm(pMessage); } + void CXFA_FFField::OnProcessMessage(CFWL_Message* pMessage) {} void CXFA_FFField::OnProcessEvent(CFWL_Event* pEvent) { diff --git a/xfa/fxfa/app/xfa_fffield.h b/xfa/fxfa/app/xfa_fffield.h index 902a84ba08..eb06caf34a 100644 --- a/xfa/fxfa/app/xfa_fffield.h +++ b/xfa/fxfa/app/xfa_fffield.h @@ -69,7 +69,7 @@ class CXFA_FFField : public CXFA_FFWidget, public IFWL_WidgetDelegate { CFWL_Widget* GetNormalWidget() { return m_pNormalWidget.get(); } CFX_PointF FWLToClient(const CFX_PointF& point); void LayoutCaption(); - void RenderCaption(CFX_Graphics* pGS, CFX_Matrix* pMatrix = nullptr); + void RenderCaption(CFX_Graphics* pGS, CFX_Matrix* pMatrix); int32_t CalculateOverride(); int32_t CalculateWidgetAcc(CXFA_WidgetAcc* pAcc); @@ -79,7 +79,7 @@ class CXFA_FFField : public CXFA_FFWidget, public IFWL_WidgetDelegate { void DrawHighlight(CFX_Graphics* pGS, CFX_Matrix* pMatrix, uint32_t dwStatus, - bool bEllipse = false); + bool bEllipse); void DrawFocus(CFX_Graphics* pGS, CFX_Matrix* pMatrix); void TranslateFWLMessage(CFWL_Message* pMessage); void CapPlacement(); -- cgit v1.2.3