OLD | NEW |
1 // Copyright 2014 PDFium Authors. All rights reserved. | 1 // Copyright 2014 PDFium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com | 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com |
6 | 6 |
7 #include "xfa/fwl/core/ifwl_combobox.h" | 7 #include "xfa/fwl/core/ifwl_combobox.h" |
8 | 8 |
9 #include "xfa/fde/cfde_txtedtengine.h" | 9 #include "xfa/fde/cfde_txtedtengine.h" |
10 #include "xfa/fde/tto/fde_textout.h" | 10 #include "xfa/fde/tto/fde_textout.h" |
11 #include "xfa/fwl/core/cfwl_message.h" | 11 #include "xfa/fwl/core/cfwl_message.h" |
12 #include "xfa/fwl/core/cfwl_themebackground.h" | 12 #include "xfa/fwl/core/cfwl_themebackground.h" |
13 #include "xfa/fwl/core/cfwl_themepart.h" | 13 #include "xfa/fwl/core/cfwl_themepart.h" |
14 #include "xfa/fwl/core/cfwl_themetext.h" | 14 #include "xfa/fwl/core/cfwl_themetext.h" |
15 #include "xfa/fwl/core/cfwl_widgetmgr.h" | 15 #include "xfa/fwl/core/cfwl_widgetmgr.h" |
16 #include "xfa/fwl/core/fwl_noteimp.h" | 16 #include "xfa/fwl/core/fwl_noteimp.h" |
17 #include "xfa/fwl/core/ifwl_app.h" | 17 #include "xfa/fwl/core/ifwl_app.h" |
18 #include "xfa/fwl/core/ifwl_comboedit.h" | 18 #include "xfa/fwl/core/ifwl_comboedit.h" |
19 #include "xfa/fwl/core/ifwl_combolist.h" | 19 #include "xfa/fwl/core/ifwl_combolist.h" |
20 #include "xfa/fwl/core/ifwl_formproxy.h" | 20 #include "xfa/fwl/core/ifwl_formproxy.h" |
21 #include "xfa/fwl/core/ifwl_themeprovider.h" | 21 #include "xfa/fwl/core/ifwl_themeprovider.h" |
22 | 22 |
23 IFWL_ComboBox::IFWL_ComboBox(const CFWL_WidgetImpProperties& properties) | 23 IFWL_ComboBox::IFWL_ComboBox(const IFWL_App* app, |
24 : IFWL_Widget(properties, nullptr), | 24 const CFWL_WidgetImpProperties& properties) |
| 25 : IFWL_Widget(app, properties, nullptr), |
25 m_pForm(nullptr), | 26 m_pForm(nullptr), |
26 m_bLButtonDown(FALSE), | 27 m_bLButtonDown(FALSE), |
27 m_iCurSel(-1), | 28 m_iCurSel(-1), |
28 m_iBtnState(CFWL_PartState_Normal), | 29 m_iBtnState(CFWL_PartState_Normal), |
29 m_fComboFormHandler(0), | 30 m_fComboFormHandler(0), |
30 m_bNeedShowList(FALSE) { | 31 m_bNeedShowList(FALSE) { |
31 m_rtClient.Reset(); | 32 m_rtClient.Reset(); |
32 m_rtBtn.Reset(); | 33 m_rtBtn.Reset(); |
33 m_rtHandler.Reset(); | 34 m_rtHandler.Reset(); |
34 } | 35 } |
35 | 36 |
36 IFWL_ComboBox::~IFWL_ComboBox() {} | 37 IFWL_ComboBox::~IFWL_ComboBox() {} |
37 | 38 |
38 FWL_Type IFWL_ComboBox::GetClassID() const { | 39 void IFWL_ComboBox::Initialize() { |
39 return FWL_Type::ComboBox; | 40 IFWL_Widget::Initialize(); |
40 } | 41 m_pDelegate = new CFWL_ComboBoxImpDelegate(this); |
41 | 42 |
42 FWL_Error IFWL_ComboBox::Initialize() { | 43 if (m_pWidgetMgr->IsFormDisabled()) { |
43 if (m_pWidgetMgr->IsFormDisabled()) | 44 DisForm_InitComboList(); |
44 return DisForm_Initialize(); | 45 DisForm_InitComboEdit(); |
| 46 return; |
| 47 } |
45 | 48 |
46 if (IFWL_Widget::Initialize() != FWL_Error::Succeeded) | |
47 return FWL_Error::Indefinite; | |
48 | |
49 m_pDelegate = new CFWL_ComboBoxImpDelegate(this); | |
50 CFWL_WidgetImpProperties prop; | 49 CFWL_WidgetImpProperties prop; |
51 prop.m_pThemeProvider = m_pProperties->m_pThemeProvider; | 50 prop.m_pThemeProvider = m_pProperties->m_pThemeProvider; |
52 prop.m_dwStyles |= FWL_WGTSTYLE_Border | FWL_WGTSTYLE_VScroll; | 51 prop.m_dwStyles |= FWL_WGTSTYLE_Border | FWL_WGTSTYLE_VScroll; |
53 if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_CMB_ListItemIconText) | 52 if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_CMB_ListItemIconText) |
54 prop.m_dwStyleExes |= FWL_STYLEEXT_LTB_Icon; | 53 prop.m_dwStyleExes |= FWL_STYLEEXT_LTB_Icon; |
55 | 54 |
56 prop.m_pDataProvider = m_pProperties->m_pDataProvider; | 55 prop.m_pDataProvider = m_pProperties->m_pDataProvider; |
57 m_pListBox.reset(new IFWL_ComboList(prop, this)); | 56 m_pListBox.reset(new IFWL_ComboList(m_pOwnerApp, prop, this)); |
58 m_pListBox->Initialize(); | 57 m_pListBox->Initialize(); |
59 if ((m_pProperties->m_dwStyleExes & FWL_STYLEEXT_CMB_DropDown) && !m_pEdit) { | 58 if ((m_pProperties->m_dwStyleExes & FWL_STYLEEXT_CMB_DropDown) && !m_pEdit) { |
60 CFWL_WidgetImpProperties prop2; | 59 CFWL_WidgetImpProperties prop2; |
61 m_pEdit.reset(new IFWL_ComboEdit(prop2, this)); | 60 m_pEdit.reset(new IFWL_ComboEdit(m_pOwnerApp, prop2, this)); |
62 m_pEdit->Initialize(); | 61 m_pEdit->Initialize(); |
63 m_pEdit->SetOuter(this); | 62 m_pEdit->SetOuter(this); |
64 } | 63 } |
65 if (m_pEdit) | 64 if (m_pEdit) |
66 m_pEdit->SetParent(this); | 65 m_pEdit->SetParent(this); |
67 | 66 |
68 SetStates(m_pProperties->m_dwStates); | 67 SetStates(m_pProperties->m_dwStates); |
69 return FWL_Error::Succeeded; | |
70 } | 68 } |
71 | 69 |
72 void IFWL_ComboBox::Finalize() { | 70 void IFWL_ComboBox::Finalize() { |
73 if (m_pEdit) | 71 if (m_pEdit) |
74 m_pEdit->Finalize(); | 72 m_pEdit->Finalize(); |
75 | 73 |
76 m_pListBox->Finalize(); | 74 m_pListBox->Finalize(); |
77 delete m_pDelegate; | 75 delete m_pDelegate; |
78 m_pDelegate = nullptr; | 76 m_pDelegate = nullptr; |
79 IFWL_Widget::Finalize(); | 77 IFWL_Widget::Finalize(); |
80 } | 78 } |
81 | 79 |
| 80 FWL_Type IFWL_ComboBox::GetClassID() const { |
| 81 return FWL_Type::ComboBox; |
| 82 } |
| 83 |
82 FWL_Error IFWL_ComboBox::GetWidgetRect(CFX_RectF& rect, FX_BOOL bAutoSize) { | 84 FWL_Error IFWL_ComboBox::GetWidgetRect(CFX_RectF& rect, FX_BOOL bAutoSize) { |
83 if (bAutoSize) { | 85 if (bAutoSize) { |
84 rect.Reset(); | 86 rect.Reset(); |
85 FX_BOOL bIsDropDown = IsDropDownStyle(); | 87 FX_BOOL bIsDropDown = IsDropDownStyle(); |
86 if (bIsDropDown && m_pEdit) { | 88 if (bIsDropDown && m_pEdit) { |
87 m_pEdit->GetWidgetRect(rect, TRUE); | 89 m_pEdit->GetWidgetRect(rect, TRUE); |
88 } else { | 90 } else { |
89 rect.width = 100; | 91 rect.width = 100; |
90 rect.height = 16; | 92 rect.height = 16; |
91 } | 93 } |
(...skipping 14 matching lines...) Expand all Loading... |
106 | 108 |
107 FWL_Error IFWL_ComboBox::ModifyStylesEx(uint32_t dwStylesExAdded, | 109 FWL_Error IFWL_ComboBox::ModifyStylesEx(uint32_t dwStylesExAdded, |
108 uint32_t dwStylesExRemoved) { | 110 uint32_t dwStylesExRemoved) { |
109 if (m_pWidgetMgr->IsFormDisabled()) { | 111 if (m_pWidgetMgr->IsFormDisabled()) { |
110 return DisForm_ModifyStylesEx(dwStylesExAdded, dwStylesExRemoved); | 112 return DisForm_ModifyStylesEx(dwStylesExAdded, dwStylesExRemoved); |
111 } | 113 } |
112 bool bAddDropDown = !!(dwStylesExAdded & FWL_STYLEEXT_CMB_DropDown); | 114 bool bAddDropDown = !!(dwStylesExAdded & FWL_STYLEEXT_CMB_DropDown); |
113 bool bRemoveDropDown = !!(dwStylesExRemoved & FWL_STYLEEXT_CMB_DropDown); | 115 bool bRemoveDropDown = !!(dwStylesExRemoved & FWL_STYLEEXT_CMB_DropDown); |
114 if (bAddDropDown && !m_pEdit) { | 116 if (bAddDropDown && !m_pEdit) { |
115 CFWL_WidgetImpProperties prop; | 117 CFWL_WidgetImpProperties prop; |
116 m_pEdit.reset(new IFWL_ComboEdit(prop, nullptr)); | 118 m_pEdit.reset(new IFWL_ComboEdit(m_pOwnerApp, prop, nullptr)); |
117 m_pEdit->Initialize(); | 119 m_pEdit->Initialize(); |
118 m_pEdit->SetOuter(this); | 120 m_pEdit->SetOuter(this); |
119 m_pEdit->SetParent(this); | 121 m_pEdit->SetParent(this); |
120 } else if (bRemoveDropDown && m_pEdit) { | 122 } else if (bRemoveDropDown && m_pEdit) { |
121 m_pEdit->SetStates(FWL_WGTSTATE_Invisible, TRUE); | 123 m_pEdit->SetStates(FWL_WGTSTATE_Invisible, TRUE); |
122 } | 124 } |
123 return IFWL_Widget::ModifyStylesEx(dwStylesExAdded, dwStylesExRemoved); | 125 return IFWL_Widget::ModifyStylesEx(dwStylesExAdded, dwStylesExRemoved); |
124 } | 126 } |
125 | 127 |
126 FWL_Error IFWL_ComboBox::Update() { | 128 FWL_Error IFWL_ComboBox::Update() { |
(...skipping 578 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
705 if (m_pForm) | 707 if (m_pForm) |
706 return; | 708 return; |
707 if (!m_pListBox) | 709 if (!m_pListBox) |
708 return; | 710 return; |
709 | 711 |
710 CFWL_WidgetImpProperties propForm; | 712 CFWL_WidgetImpProperties propForm; |
711 propForm.m_pOwner = this; | 713 propForm.m_pOwner = this; |
712 propForm.m_dwStyles = FWL_WGTSTYLE_Popup; | 714 propForm.m_dwStyles = FWL_WGTSTYLE_Popup; |
713 propForm.m_dwStates = FWL_WGTSTATE_Invisible; | 715 propForm.m_dwStates = FWL_WGTSTATE_Invisible; |
714 | 716 |
715 m_pForm = new IFWL_FormProxy(propForm, m_pListBox.get()); | 717 m_pForm = new IFWL_FormProxy(m_pOwnerApp, propForm, m_pListBox.get()); |
716 m_pForm->Initialize(); | 718 m_pForm->Initialize(); |
717 m_pListBox->SetParent(m_pForm); | 719 m_pListBox->SetParent(m_pForm); |
718 m_pListProxyDelegate = new CFWL_ComboProxyImpDelegate(m_pForm, this); | 720 m_pListProxyDelegate = new CFWL_ComboProxyImpDelegate(m_pForm, this); |
719 m_pForm->SetDelegate(m_pListProxyDelegate); | 721 m_pForm->SetDelegate(m_pListProxyDelegate); |
720 } | 722 } |
721 | 723 |
722 FWL_Error IFWL_ComboBox::DisForm_Initialize() { | |
723 if (IFWL_Widget::Initialize() != FWL_Error::Succeeded) | |
724 return FWL_Error::Indefinite; | |
725 | |
726 m_pDelegate = new CFWL_ComboBoxImpDelegate(this); | |
727 DisForm_InitComboList(); | |
728 DisForm_InitComboEdit(); | |
729 return FWL_Error::Succeeded; | |
730 } | |
731 | |
732 void IFWL_ComboBox::DisForm_InitComboList() { | 724 void IFWL_ComboBox::DisForm_InitComboList() { |
733 if (m_pListBox) | 725 if (m_pListBox) |
734 return; | 726 return; |
735 | 727 |
736 CFWL_WidgetImpProperties prop; | 728 CFWL_WidgetImpProperties prop; |
737 prop.m_pParent = this; | 729 prop.m_pParent = this; |
738 prop.m_dwStyles = FWL_WGTSTYLE_Border | FWL_WGTSTYLE_VScroll; | 730 prop.m_dwStyles = FWL_WGTSTYLE_Border | FWL_WGTSTYLE_VScroll; |
739 prop.m_dwStates = FWL_WGTSTATE_Invisible; | 731 prop.m_dwStates = FWL_WGTSTATE_Invisible; |
740 prop.m_pDataProvider = m_pProperties->m_pDataProvider; | 732 prop.m_pDataProvider = m_pProperties->m_pDataProvider; |
741 prop.m_pThemeProvider = m_pProperties->m_pThemeProvider; | 733 prop.m_pThemeProvider = m_pProperties->m_pThemeProvider; |
742 m_pListBox.reset(new IFWL_ComboList(prop, this)); | 734 m_pListBox.reset(new IFWL_ComboList(m_pOwnerApp, prop, this)); |
743 m_pListBox->Initialize(); | 735 m_pListBox->Initialize(); |
744 } | 736 } |
745 | 737 |
746 void IFWL_ComboBox::DisForm_InitComboEdit() { | 738 void IFWL_ComboBox::DisForm_InitComboEdit() { |
747 if (m_pEdit) { | 739 if (m_pEdit) |
748 return; | 740 return; |
749 } | 741 |
750 CFWL_WidgetImpProperties prop; | 742 CFWL_WidgetImpProperties prop; |
751 prop.m_pParent = this; | 743 prop.m_pParent = this; |
752 prop.m_pThemeProvider = m_pProperties->m_pThemeProvider; | 744 prop.m_pThemeProvider = m_pProperties->m_pThemeProvider; |
753 m_pEdit.reset(new IFWL_ComboEdit(prop, this)); | 745 m_pEdit.reset(new IFWL_ComboEdit(m_pOwnerApp, prop, this)); |
754 m_pEdit->Initialize(); | 746 m_pEdit->Initialize(); |
755 m_pEdit->SetOuter(this); | 747 m_pEdit->SetOuter(this); |
756 } | 748 } |
757 | 749 |
758 void IFWL_ComboBox::DisForm_ShowDropList(FX_BOOL bActivate) { | 750 void IFWL_ComboBox::DisForm_ShowDropList(FX_BOOL bActivate) { |
759 FX_BOOL bDropList = DisForm_IsDropListShowed(); | 751 FX_BOOL bDropList = DisForm_IsDropListShowed(); |
760 if (bDropList == bActivate) { | 752 if (bDropList == bActivate) { |
761 return; | 753 return; |
762 } | 754 } |
763 if (bActivate) { | 755 if (bActivate) { |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
800 rect.Inflate(2, 2); | 792 rect.Inflate(2, 2); |
801 Repaint(&rect); | 793 Repaint(&rect); |
802 } | 794 } |
803 | 795 |
804 FX_BOOL IFWL_ComboBox::DisForm_IsDropListShowed() { | 796 FX_BOOL IFWL_ComboBox::DisForm_IsDropListShowed() { |
805 return !(m_pListBox->GetStates() & FWL_WGTSTATE_Invisible); | 797 return !(m_pListBox->GetStates() & FWL_WGTSTATE_Invisible); |
806 } | 798 } |
807 | 799 |
808 FWL_Error IFWL_ComboBox::DisForm_ModifyStylesEx(uint32_t dwStylesExAdded, | 800 FWL_Error IFWL_ComboBox::DisForm_ModifyStylesEx(uint32_t dwStylesExAdded, |
809 uint32_t dwStylesExRemoved) { | 801 uint32_t dwStylesExRemoved) { |
810 if (!m_pEdit) { | 802 if (!m_pEdit) |
811 DisForm_InitComboEdit(); | 803 DisForm_InitComboEdit(); |
812 } | 804 |
813 bool bAddDropDown = !!(dwStylesExAdded & FWL_STYLEEXT_CMB_DropDown); | 805 bool bAddDropDown = !!(dwStylesExAdded & FWL_STYLEEXT_CMB_DropDown); |
814 bool bDelDropDown = !!(dwStylesExRemoved & FWL_STYLEEXT_CMB_DropDown); | 806 bool bDelDropDown = !!(dwStylesExRemoved & FWL_STYLEEXT_CMB_DropDown); |
815 dwStylesExRemoved &= ~FWL_STYLEEXT_CMB_DropDown; | 807 dwStylesExRemoved &= ~FWL_STYLEEXT_CMB_DropDown; |
816 m_pProperties->m_dwStyleExes |= FWL_STYLEEXT_CMB_DropDown; | 808 m_pProperties->m_dwStyleExes |= FWL_STYLEEXT_CMB_DropDown; |
817 if (bAddDropDown) { | 809 if (bAddDropDown) { |
818 m_pEdit->ModifyStylesEx(0, FWL_STYLEEXT_EDT_ReadOnly); | 810 m_pEdit->ModifyStylesEx(0, FWL_STYLEEXT_EDT_ReadOnly); |
819 } else if (bDelDropDown) { | 811 } else if (bDelDropDown) { |
820 m_pEdit->ModifyStylesEx(FWL_STYLEEXT_EDT_ReadOnly, 0); | 812 m_pEdit->ModifyStylesEx(FWL_STYLEEXT_EDT_ReadOnly, 0); |
821 } | 813 } |
822 return IFWL_Widget::ModifyStylesEx(dwStylesExAdded, dwStylesExRemoved); | 814 return IFWL_Widget::ModifyStylesEx(dwStylesExAdded, dwStylesExRemoved); |
(...skipping 546 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1369 } | 1361 } |
1370 CFWL_WidgetImpDelegate::OnProcessMessage(pMessage); | 1362 CFWL_WidgetImpDelegate::OnProcessMessage(pMessage); |
1371 } | 1363 } |
1372 | 1364 |
1373 void CFWL_ComboProxyImpDelegate::OnDrawWidget(CFX_Graphics* pGraphics, | 1365 void CFWL_ComboProxyImpDelegate::OnDrawWidget(CFX_Graphics* pGraphics, |
1374 const CFX_Matrix* pMatrix) { | 1366 const CFX_Matrix* pMatrix) { |
1375 m_pComboBox->DrawStretchHandler(pGraphics, pMatrix); | 1367 m_pComboBox->DrawStretchHandler(pGraphics, pMatrix); |
1376 } | 1368 } |
1377 | 1369 |
1378 void CFWL_ComboProxyImpDelegate::OnLButtonDown(CFWL_MsgMouse* pMsg) { | 1370 void CFWL_ComboProxyImpDelegate::OnLButtonDown(CFWL_MsgMouse* pMsg) { |
1379 IFWL_App* pApp = m_pForm->GetOwnerApp(); | 1371 const IFWL_App* pApp = m_pForm->GetOwnerApp(); |
1380 if (!pApp) | 1372 if (!pApp) |
1381 return; | 1373 return; |
1382 | 1374 |
1383 CFWL_NoteDriver* pDriver = | 1375 CFWL_NoteDriver* pDriver = |
1384 static_cast<CFWL_NoteDriver*>(pApp->GetNoteDriver()); | 1376 static_cast<CFWL_NoteDriver*>(pApp->GetNoteDriver()); |
1385 CFX_RectF rtWidget; | 1377 CFX_RectF rtWidget; |
1386 m_pForm->GetWidgetRect(rtWidget); | 1378 m_pForm->GetWidgetRect(rtWidget); |
1387 rtWidget.left = rtWidget.top = 0; | 1379 rtWidget.left = rtWidget.top = 0; |
1388 if (rtWidget.Contains(pMsg->m_fx, pMsg->m_fy)) { | 1380 if (rtWidget.Contains(pMsg->m_fx, pMsg->m_fy)) { |
1389 m_bLButtonDown = TRUE; | 1381 m_bLButtonDown = TRUE; |
1390 pDriver->SetGrab(m_pForm, TRUE); | 1382 pDriver->SetGrab(m_pForm, TRUE); |
1391 } else { | 1383 } else { |
1392 m_bLButtonDown = FALSE; | 1384 m_bLButtonDown = FALSE; |
1393 pDriver->SetGrab(m_pForm, FALSE); | 1385 pDriver->SetGrab(m_pForm, FALSE); |
1394 m_pComboBox->ShowDropList(FALSE); | 1386 m_pComboBox->ShowDropList(FALSE); |
1395 } | 1387 } |
1396 } | 1388 } |
1397 | 1389 |
1398 void CFWL_ComboProxyImpDelegate::OnLButtonUp(CFWL_MsgMouse* pMsg) { | 1390 void CFWL_ComboProxyImpDelegate::OnLButtonUp(CFWL_MsgMouse* pMsg) { |
1399 m_bLButtonDown = FALSE; | 1391 m_bLButtonDown = FALSE; |
1400 IFWL_App* pApp = m_pForm->GetOwnerApp(); | 1392 const IFWL_App* pApp = m_pForm->GetOwnerApp(); |
1401 if (!pApp) | 1393 if (!pApp) |
1402 return; | 1394 return; |
1403 | 1395 |
1404 CFWL_NoteDriver* pDriver = | 1396 CFWL_NoteDriver* pDriver = |
1405 static_cast<CFWL_NoteDriver*>(pApp->GetNoteDriver()); | 1397 static_cast<CFWL_NoteDriver*>(pApp->GetNoteDriver()); |
1406 pDriver->SetGrab(m_pForm, FALSE); | 1398 pDriver->SetGrab(m_pForm, FALSE); |
1407 if (m_bLButtonUpSelf) { | 1399 if (m_bLButtonUpSelf) { |
1408 CFX_RectF rect; | 1400 CFX_RectF rect; |
1409 m_pForm->GetWidgetRect(rect); | 1401 m_pForm->GetWidgetRect(rect); |
1410 rect.left = rect.top = 0; | 1402 rect.left = rect.top = 0; |
(...skipping 13 matching lines...) Expand all Loading... |
1424 } | 1416 } |
1425 | 1417 |
1426 void CFWL_ComboProxyImpDelegate::OnFocusChanged(CFWL_MsgKillFocus* pMsg, | 1418 void CFWL_ComboProxyImpDelegate::OnFocusChanged(CFWL_MsgKillFocus* pMsg, |
1427 FX_BOOL bSet) { | 1419 FX_BOOL bSet) { |
1428 if (!bSet) { | 1420 if (!bSet) { |
1429 if (!pMsg->m_pSetFocus) { | 1421 if (!pMsg->m_pSetFocus) { |
1430 m_pComboBox->ShowDropList(FALSE); | 1422 m_pComboBox->ShowDropList(FALSE); |
1431 } | 1423 } |
1432 } | 1424 } |
1433 } | 1425 } |
OLD | NEW |