From e03a27e715212be21bb0348d984cdcfb0c9a0aa6 Mon Sep 17 00:00:00 2001 From: NicolaP Date: Mon, 14 Jun 2021 19:11:48 +0200 Subject: [PATCH] Correzione modifica inizio fine tagli pagina SPLIT --- CadCuts/EditValueWD.xaml | 2 +- CadCuts/EditValueWD.xaml.vb | 9 +- CadCuts/SplitPageUC.xaml.vb | 296 +++++++++++++++++++++++------------- 3 files changed, 199 insertions(+), 108 deletions(-) diff --git a/CadCuts/EditValueWD.xaml b/CadCuts/EditValueWD.xaml index 51e9495..c7ff142 100644 --- a/CadCuts/EditValueWD.xaml +++ b/CadCuts/EditValueWD.xaml @@ -25,7 +25,7 @@ + Style="{StaticResource OmagCut_CalculatorTextBox}"/> diff --git a/CadCuts/EditValueWD.xaml.vb b/CadCuts/EditValueWD.xaml.vb index 406b93e..cc436d6 100644 --- a/CadCuts/EditValueWD.xaml.vb +++ b/CadCuts/EditValueWD.xaml.vb @@ -34,10 +34,15 @@ Public Class EditValueWD End Sub Private Sub EditValueWD_Rendered(sender As Object, e As EventArgs) Handles Me.ContentRendered - ValueTxBx.Focus() - ValueTxBx.OpenKeyboard(ValueTxBx, ValueTxBx) + ' ValueTxBx.Focus() + ' ValueTxBx.OpenKeyboard(ValueTxBx, ValueTxBx) End Sub + 'Private Sub ValueTxBx_Closed(Sender As Object, e As EventArgs) Handles ValueTxBx.EgtClosed + ' m_sValue = ValueTxBx.Text + ' DialogResult = True + 'End Sub + Private Sub OkBtn_Click(sender As Object, e As RoutedEventArgs) Handles OkBtn.Click m_sValue = ValueTxBx.Text DialogResult = True diff --git a/CadCuts/SplitPageUC.xaml.vb b/CadCuts/SplitPageUC.xaml.vb index b88499c..b8d8197 100644 --- a/CadCuts/SplitPageUC.xaml.vb +++ b/CadCuts/SplitPageUC.xaml.vb @@ -728,6 +728,18 @@ Public Class SplitPageUC End Sub Private Sub ModifStartBtn_Click(sender As Object, e As RoutedEventArgs) Handles ModifStartBtn.Click + ' abilito la finestra per inserire i valori solo per il primo elemento della lista (di default tutti gli altri oggetti assumono lo stesso valore) + Dim bFirstInd As Boolean = True + ' elenco delle variabili : MCH_MY.SAWING/MCH_MY.MILLING + Dim dUsal As Double = 0 + + ' elenco delle variabili : MCH_MY.WATERJETTING + Dim dWJAddLen As Double = 0 + Dim bWJLiHole As Boolean = True + Dim nWJTangDist As Double = 0 + Dim nWJPerpDist As Double = 0 + Dim nWJLeadInType As Integer = 0 + ' Recupero la lavorazione corrente If m_CurrFirstInd = -1 Then Return Dim bGenModif As Boolean = False @@ -737,24 +749,34 @@ Public Class SplitPageUC Dim nMachiningType As Integer = EgtGetOperationType(nOperId) ' Se taglio con lama If nMachiningType = MCH_MY.SAWING And - ( m_MachiningList(nI).m_bIsLine Or m_MachiningList(nI).m_dPrevAng > FL_ARC_ANG_MIN Or m_MachiningList(nI).m_sLay = NAME_ONPATH) Then + (m_MachiningList(nI).m_bIsLine Or m_MachiningList(nI).m_dPrevAng > FL_ARC_ANG_MIN Or m_MachiningList(nI).m_sLay = NAME_ONPATH) Then + ' leggo il valore salvato nella geometria Dim dOrigUsal As Double = 0 EgtGetInfo(nOperId, INFO_MCH_USER_SAL, dOrigUsal) - ' Dialogo richiesta valore - Dim ValWnd As New EditValueWD(m_MainWindow, EgtMsg(MSG_SPLITPAGEUC + 35)) ' Allungamento - ValWnd.SetVal(dOrigUsal) - If Not ValWnd.ShowDialog() Then Return - Dim dUsal As Double = ValWnd.GetVal() + + ' ------------------ INIZIO PREPARAZIONE TASTIERINO VIRTUALE ------------------ + If bFirstInd Then + ' Dialogo richiesta valore + Dim ValWnd As New EditValueWD(m_MainWindow, EgtMsg(MSG_SPLITPAGEUC + 35)) ' Allungamento + ValWnd.SetVal(dOrigUsal) + If Not ValWnd.ShowDialog() Then Return + ' carico il valore letto dal testierino virtuale + dUsal = ValWnd.GetVal() + ' comunico che ho letto il primo dato + bFirstInd = False + End If + ' ------------------ FINE PREPARAZIONE TASTIERINO VIRTUALE ------------------ + ' Se c'è limite alla lunghezza libera If m_MachiningList(nI).m_dStartFreeLen < FREELEN_INF Then ' Recupero sicurezza in corner interno Dim dCornerSafety As Double = Math.Max(GetPrivateProfileDouble(S_MACH_NEST, K_MACH_SAFE_LEN_INTCORNER, 1, m_MainWindow.GetMachIniFile()), 10 * EPS_SMALL) ' Recupero lunghezza baffo del taglio Dim nPvId As Integer = GDB_ID.NULL - EgtGetInfo( EgtGetFirstNameInGroup( nOperId, NAME_PREVIEW), INFO_PV_ONPART_ID, nPvId) + EgtGetInfo(EgtGetFirstNameInGroup(nOperId, NAME_PREVIEW), INFO_PV_ONPART_ID, nPvId) Dim dDT As Double = 0 - EgtGetInfo( EgtGetFirstGroupInGroup( nPvId), "DT", dDT) - dUsal = Math.Min( dUsal, m_MachiningList(nI).m_dStartFreeLen - dDT - dCornerSafety) + EgtGetInfo(EgtGetFirstGroupInGroup(nPvId), "DT", dDT) + dUsal = Math.Min(dUsal, m_MachiningList(nI).m_dStartFreeLen - dDT - dCornerSafety) End If ' Modifica della lavorazione EgtSetCurrMachining(nOperId) @@ -769,15 +791,26 @@ Public Class SplitPageUC ColorMachining(m_MachiningList(nI)) ColorNumberArrow(nI) bGenModif = True - ' se altrimenti fresatura sopra + + ' se altrimenti fresatura sopra ElseIf nMachiningType = MCH_MY.MILLING And m_MachiningList(nI).m_sLay = NAME_ONPATH Then + + ' leggo il valore salvato nella geometria Dim dOrigUsal As Double = 0 EgtGetInfo(nOperId, INFO_MCH_USER_SAL, dOrigUsal) - ' Dialogo richiesta valore - Dim ValWnd As New EditValueWD(m_MainWindow, EgtMsg(MSG_SPLITPAGEUC + 35)) ' Allungamento - ValWnd.SetVal(dOrigUsal) - If Not ValWnd.ShowDialog() Then Return - Dim dUsal As Double = ValWnd.GetVal() + If bFirstInd Then + ' ------------------ INIZIO PREPARAZIONE TASTIERINO VIRTUALE ------------------ + ' Dialogo richiesta valore + Dim ValWnd As New EditValueWD(m_MainWindow, EgtMsg(MSG_SPLITPAGEUC + 35)) ' Allungamento + ValWnd.SetVal(dOrigUsal) + If Not ValWnd.ShowDialog() Then Return + ' carico il valore letto dal testierino virtuale + dUsal = ValWnd.GetVal() + ' comunico che ho letto il primo dato + bFirstInd = False + End If + ' ------------------ FINE PREPARAZIONE TASTIERINO VIRTUALE ------------------ + ' Modifica della lavorazione EgtSetCurrMachining(nOperId) Dim dAddLen As Double = 0 @@ -786,43 +819,61 @@ Public Class SplitPageUC EgtSetInfo(nOperId, INFO_MCH_USER_SAL, dUsal) UpdateMachiningPreview(m_MachiningList(nI).m_nId, True) bGenModif = True - ' se altrimenti getto d'acqua + + ' se altrimenti getto d'acqua ElseIf nMachiningType = MCH_MY.WATERJETTING Then - ' Recupero i valori attuali della lavorazione - Dim bIsLeadIn As Boolean = True - Dim dAddLen As Double = 0 - Dim bLiHole As Boolean = true - Dim nTangDist As Double = 0 - Dim nPerpDist As Double = 0 - Dim LeadInType As Integer = 0 - EgtSetCurrMachining( nOperId) - EgtGetMachiningParam( MCH_MP.STARTADDLEN, dAddLen) - EgtGetMachiningParam( MCH_MP.LIHOLE, bLiHole) - EgtGetMachiningParam( MCH_MP.LITANG, nTangDist) - EgtGetMachiningParam( MCH_MP.LIPERP, nPerpDist) - EgtGetMachiningParam( MCH_MP.LEADINTYPE, LeadInType) - ' Dialogo richiesta valori - Dim ModifStartWnd As New ModifStartEndWD( m_MainWindow, EgtMsg(MSG_SPLITPAGEUC + 33), bIsLeadIn, nOperId) ' Inizio Modif. - ModifStartWnd.SetElongation( dAddLen) - ModifStartWnd.SetHole( bLiHole) - ModifStartWnd.SetLeadInType( LeadInType) - ModifStartWnd.SetLiTangDist( nTangDist) - ModifStartWnd.SetLiPerpDist( nPerpDist) - If Not ModifStartWnd.ShowDialog() Then return + + ' ------------------ INIZIO PREPARAZIONE TASTIERINO VIRTUALE ------------------ + If bFirstInd Then + ' Recupero i valori attuali della lavorazione + Dim bOriginalIsLeadIn As Boolean = True + Dim dOriginalAddLen As Double = 0 + Dim bOriginalLiHole As Boolean = True + Dim nOriginalTangDist As Double = 0 + Dim nOriginalPerpDist As Double = 0 + Dim nOriginalLeadInType As Integer = 0 + EgtSetCurrMachining(nOperId) + EgtGetMachiningParam(MCH_MP.STARTADDLEN, dOriginalAddLen) + EgtGetMachiningParam(MCH_MP.LIHOLE, bOriginalLiHole) + EgtGetMachiningParam(MCH_MP.LITANG, nOriginalTangDist) + EgtGetMachiningParam(MCH_MP.LIPERP, nOriginalPerpDist) + EgtGetMachiningParam(MCH_MP.LEADINTYPE, nOriginalLeadInType) + ' Dialogo richiesta valori + Dim ModifStartWnd As New ModifStartEndWD(m_MainWindow, EgtMsg(MSG_SPLITPAGEUC + 33), bOriginalIsLeadIn, nOperId) ' Inizio Modif. + ModifStartWnd.SetElongation(dOriginalAddLen) + ModifStartWnd.SetHole(bOriginalLiHole) + ModifStartWnd.SetLiTangDist(nOriginalTangDist) + ModifStartWnd.SetLiPerpDist(nOriginalPerpDist) + ModifStartWnd.SetLeadInType(nOriginalLeadInType) + If Not ModifStartWnd.ShowDialog() Then Return + + ' carico il valore letto dal testierino virtuale + dWJAddLen = ModifStartWnd.GetElongation() + bWJLiHole = ModifStartWnd.GetHole() + nWJTangDist = ModifStartWnd.GetLiTangDist() + nWJPerpDist = ModifStartWnd.GetLiPerpDist() + nWJLeadInType = ModifStartWnd.GetLeadInType().Id + ' comunico che ho letto il primo dato + bFirstInd = False + End If + ' ------------------ INIZIO PREPARAZIONE TASTIERINO VIRTUALE ------------------ + ' Modifica della lavorazione - EgtSetCurrMachining( nOperId) - EgtSetMachiningParam( MCH_MP.LIHOLE, ModifStartWnd.GetHole()) - EgtSetMachiningParam( MCH_MP.STARTADDLEN, ModifStartWnd.GetElongation()) - EgtSetMachiningParam( MCH_MP.LEADINTYPE, ModifStartWnd.GetLeadInType().Id) - EgtSetMachiningParam( MCH_MP.LITANG, ModifStartWnd.GetLiTangDist()) - EgtSetMachiningParam( MCH_MP.LIPERP, ModifStartWnd.GetLiPerpDist()) - UpdateMachiningPreview( m_MachiningList(nI).m_nId, True) - ' verifico interferenza - EgtVerifyMachining( m_MachiningList(nI).m_nId, m_MachiningList(nI).m_nInterf) - ColorMachining( m_MachiningList(nI)) - ColorNumberArrow( nI) - bGenModif = True - End If + EgtSetCurrMachining(nOperId) + EgtSetMachiningParam(MCH_MP.LIHOLE, bWJLiHole) + EgtSetMachiningParam(MCH_MP.STARTADDLEN, dWJAddLen) + EgtSetMachiningParam(MCH_MP.LEADINTYPE, nWJLeadInType) + EgtSetMachiningParam(MCH_MP.LITANG, nWJTangDist) + EgtSetMachiningParam(MCH_MP.LIPERP, nWJPerpDist) + + UpdateMachiningPreview(m_MachiningList(nI).m_nId, True) + + ' verifico interferenza + EgtVerifyMachining(m_MachiningList(nI).m_nId, m_MachiningList(nI).m_nInterf) + ColorMachining(m_MachiningList(nI)) + ColorNumberArrow(nI) + bGenModif = True + End If Next ' Se modificato qualcosa If bGenModif Then @@ -832,56 +883,81 @@ Public Class SplitPageUC End Sub Private Sub ModifEndBtn_Click(sender As Object, e As RoutedEventArgs) Handles ModifEndBtn.Click + ' abilito la finestra per inserire i valori solo per il primo elemento della lista (di default tutti gli altri oggetti assumono lo stesso valore) + Dim bFirstInd As Boolean = True + ' elenco delle variabili : MCH_MY.SAWING/MCH_MY.MILLING + Dim dUeal As Double = 0 + + ' Recupero i valori attuali della lavorazione + Dim dWJAddLen As Double = 0 + Dim WJLeadOutType As Integer = 0 + Dim nWJTangDist As Double = 0 + Dim nWJPerpDist As Double = 0 + ' Recupero la lavorazione corrente If m_CurrFirstInd = -1 Then Return Dim bGenModif As Boolean = False For Index = m_CurrFirstInd To m_CurrLastInd - Dim nI As Integer = m_ItemList( Index).Ind - Dim nOperId As Integer = m_MachiningList( nI).m_nId - Dim nMachiningType As Integer = EgtGetOperationType( nOperId) + Dim nI As Integer = m_ItemList(Index).Ind + Dim nOperId As Integer = m_MachiningList(nI).m_nId + Dim nMachiningType As Integer = EgtGetOperationType(nOperId) ' Se taglio con lama If nMachiningType = MCH_MY.SAWING And - ( m_MachiningList( nI).m_bIsLine Or m_MachiningList( nI).m_dNextAng > FL_ARC_ANG_MIN Or m_MachiningList(nI).m_sLay = NAME_ONPATH) Then + (m_MachiningList(nI).m_bIsLine Or m_MachiningList(nI).m_dNextAng > FL_ARC_ANG_MIN Or m_MachiningList(nI).m_sLay = NAME_ONPATH) Then + Dim dOrigUeal As Double = 0 EgtGetInfo(nOperId, INFO_MCH_USER_EAL, dOrigUeal) - ' Dialogo richiesta valore - Dim ValWnd As New EditValueWD( m_MainWindow, EgtMsg(MSG_SPLITPAGEUC + 35)) ' Allungamento - ValWnd.SetVal(dOrigUeal) - If Not ValWnd.ShowDialog() Then Return - Dim dUeal As Double = ValWnd.GetVal() + + ' ------------------ INIZIO PREPARAZIONE TASTIERINO VIRTUALE ------------------ + If bFirstInd Then + ' Dialogo richiesta valore + Dim ValWnd As New EditValueWD(m_MainWindow, EgtMsg(MSG_SPLITPAGEUC + 35)) ' Allungamento + ValWnd.SetVal(dOrigUeal) + If Not ValWnd.ShowDialog() Then Return + dUeal = ValWnd.GetVal() + bFirstInd = False + End If + ' ------------------ FINE PREPARAZIONE TASTIERINO VIRTUALE ------------------ + ' Se c'è limite alla lunghezza libera If m_MachiningList(nI).m_dEndFreeLen < FREELEN_INF Then ' Recupero sicurezza in corner interno Dim dCornerSafety As Double = Math.Max(GetPrivateProfileDouble(S_MACH_NEST, K_MACH_SAFE_LEN_INTCORNER, 1, m_MainWindow.GetMachIniFile()), 10 * EPS_SMALL) ' Recupero lunghezza baffo del taglio Dim nPvId As Integer = GDB_ID.NULL - EgtGetInfo( EgtGetFirstNameInGroup( nOperId, NAME_PREVIEW), INFO_PV_ONPART_ID, nPvId) + EgtGetInfo(EgtGetFirstNameInGroup(nOperId, NAME_PREVIEW), INFO_PV_ONPART_ID, nPvId) Dim dDT As Double = 0 - EgtGetInfo( EgtGetFirstGroupInGroup( nPvId), "DT", dDT) - dUeal = Math.Min( dUeal, m_MachiningList(nI).m_dEndFreeLen - dDT - dCornerSafety) + EgtGetInfo(EgtGetFirstGroupInGroup(nPvId), "DT", dDT) + dUeal = Math.Min(dUeal, m_MachiningList(nI).m_dEndFreeLen - dDT - dCornerSafety) End If ' Modifica della lavorazione - EgtSetCurrMachining( nOperId) + EgtSetCurrMachining(nOperId) Dim dAddLen As Double = 0 - EgtGetMachiningParam( MCH_MP.ENDADDLEN, dAddLen) + EgtGetMachiningParam(MCH_MP.ENDADDLEN, dAddLen) If dAddLen - dOrigUeal < -10 * EPS_SMALL Then Return - EgtSetMachiningParam( MCH_MP.ENDADDLEN, dAddLen + dUeal - dOrigUeal) - EgtSetInfo( nOperId, INFO_MCH_USER_EAL, dUeal) - UpdateMachiningPreview( m_MachiningList(nI).m_nId, True) + EgtSetMachiningParam(MCH_MP.ENDADDLEN, dAddLen + dUeal - dOrigUeal) + EgtSetInfo(nOperId, INFO_MCH_USER_EAL, dUeal) + UpdateMachiningPreview(m_MachiningList(nI).m_nId, True) ' verifico interferenza - EgtVerifyMachining( m_MachiningList(nI).m_nId, m_MachiningList(nI).m_nInterf) - ColorMachining( m_MachiningList(nI)) - ColorNumberArrow( nI) + EgtVerifyMachining(m_MachiningList(nI).m_nId, m_MachiningList(nI).m_nInterf) + ColorMachining(m_MachiningList(nI)) + ColorNumberArrow(nI) bGenModif = True - ' se altrimenti fresatura sopra + ' se altrimenti fresatura sopra ElseIf nMachiningType = MCH_MY.MILLING And m_MachiningList(nI).m_sLay = NAME_ONPATH Then + Dim dOrigUeal As Double = 0 EgtGetInfo(nOperId, INFO_MCH_USER_EAL, dOrigUeal) - ' Dialogo richiesta valore - Dim ValWnd As New EditValueWD(m_MainWindow, EgtMsg(MSG_SPLITPAGEUC + 35)) ' Allungamento - ValWnd.SetVal(dOrigUeal) - If Not ValWnd.ShowDialog() Then Return - Dim dUeal As Double = ValWnd.GetVal() + ' ------------------ INIZIO PREPARAZIONE TASTIERINO VIRTUALE ------------------ + If bFirstInd Then + ' Dialogo richiesta valore + Dim ValWnd As New EditValueWD(m_MainWindow, EgtMsg(MSG_SPLITPAGEUC + 35)) ' Allungamento + ValWnd.SetVal(dOrigUeal) + If Not ValWnd.ShowDialog() Then Return + dUeal = ValWnd.GetVal() + bFirstInd = False + End If + ' ------------------ FINE PREPARAZIONE TASTIERINO VIRTUALE ------------------ ' Modifica della lavorazione EgtSetCurrMachining(nOperId) Dim dAddLen As Double = 0 @@ -890,38 +966,48 @@ Public Class SplitPageUC EgtSetInfo(nOperId, INFO_MCH_USER_EAL, dUeal) UpdateMachiningPreview(m_MachiningList(nI).m_nId, True) bGenModif = True - ' se altrimenti getto d'acqua + ' se altrimenti getto d'acqua ElseIf nMachiningType = MCH_MY.WATERJETTING Then - ' Recupero i valori attuali della lavorazione - Dim dAddLen As Double = 0 - Dim LeadOutType As Integer = 0 - Dim nTangDist As Double = 0 - Dim nPerpDist As Double = 0 - EgtSetCurrMachining(nOperId) - EgtGetMachiningParam( MCH_MP.ENDADDLEN, dAddLen) - EgtGetMachiningParam( MCH_MP.LEADOUTTYPE, LeadOutType) - EgtGetMachiningParam( MCH_MP.LOTANG, nTangDist) - EgtGetMachiningParam( MCH_MP.LOPERP, nPerpDist) - ' Dialogo richiesta valore - Dim ModifStartWnd As New ModifStartEndWD( m_MainWindow, EgtMsg(MSG_SPLITPAGEUC + 34), False, nOperId) ' Fine Modif. - ModifStartWnd.SetElongation( dAddLen) - ModifStartWnd.SetLeadOutType( LeadOutType) - ModifStartWnd.SetLoTangDist( nTangDist) - ModifStartWnd.SetLoPerpDist( nPerpDist) - If Not ModifStartWnd.ShowDialog() Then Return + + If bFirstInd Then + ' Recupero i valori attuali della lavorazione + Dim dAddLen As Double = 0 + Dim LeadOutType As Integer = 0 + Dim nTangDist As Double = 0 + Dim nPerpDist As Double = 0 + EgtSetCurrMachining(nOperId) + EgtGetMachiningParam(MCH_MP.ENDADDLEN, dAddLen) + EgtGetMachiningParam(MCH_MP.LEADOUTTYPE, LeadOutType) + EgtGetMachiningParam(MCH_MP.LOTANG, nTangDist) + EgtGetMachiningParam(MCH_MP.LOPERP, nPerpDist) + ' Dialogo richiesta valore + Dim ModifStartWnd As New ModifStartEndWD(m_MainWindow, EgtMsg(MSG_SPLITPAGEUC + 34), False, nOperId) ' Fine Modif. + ModifStartWnd.SetElongation(dAddLen) + ModifStartWnd.SetLeadOutType(LeadOutType) + ModifStartWnd.SetLoTangDist(nTangDist) + ModifStartWnd.SetLoPerpDist(nPerpDist) + If Not ModifStartWnd.ShowDialog() Then Return + dWJAddLen = ModifStartWnd.GetElongation() + WJLeadOutType = ModifStartWnd.GetLeadOutType().Id + nWJTangDist = ModifStartWnd.GetLoTangDist() + nWJPerpDist = ModifStartWnd.GetLoPerpDist() + bFirstInd = False + End If + ' Modifica della lavorazione EgtSetCurrMachining(nOperId) - EgtSetMachiningParam( MCH_MP.ENDADDLEN, ModifStartWnd.GetElongation()) - EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, ModifStartWnd.GetLeadOutType().Id) - EgtSetMachiningParam( MCH_MP.LOTANG, ModifStartWnd.GetLoTangDist()) - EgtSetMachiningParam( MCH_MP.LOPERP, ModifStartWnd.GetLoPerpDist()) - UpdateMachiningPreview(m_MachiningList(nI).m_nId, True) - ' verifico interferenza - EgtVerifyMachining( m_MachiningList(nI).m_nId, m_MachiningList(nI).m_nInterf) - ColorMachining( m_MachiningList(nI)) - ColorNumberArrow( nI) - bGenModif = True - End If + EgtSetMachiningParam(MCH_MP.ENDADDLEN, dWJAddLen) + EgtSetMachiningParam(MCH_MP.LEADOUTTYPE, WJLeadOutType) + EgtSetMachiningParam(MCH_MP.LOTANG, nWJTangDist) + EgtSetMachiningParam(MCH_MP.LOPERP, nWJPerpDist) + UpdateMachiningPreview(m_MachiningList(nI).m_nId, True) + + ' verifico interferenza + EgtVerifyMachining(m_MachiningList(nI).m_nId, m_MachiningList(nI).m_nInterf) + ColorMachining(m_MachiningList(nI)) + ColorNumberArrow(nI) + bGenModif = True + End If Next ' Se modificato qualcosa If bGenModif Then