EgtMachKernel :
- aggiunta gestione quota di base del tool holder ( se negativa indica spazio libero su testa).
This commit is contained in:
@@ -488,7 +488,7 @@ class MachMgr : public IMachMgr
|
||||
bool ShowRootParts( bool bShow) ;
|
||||
// Tools DataBase
|
||||
bool UpdateAllToolDraws( void) const ;
|
||||
bool UpdateToolDraw( const EgtUUID& UuidTool, double& dTHoldLen, double& dTHoldDiam) const ;
|
||||
bool UpdateToolDraw( const EgtUUID& UuidTool, double& dTHoldBase, double& dTHoldLen, double& dTHoldDiam) const ;
|
||||
int UpdateStandardToolDraw( const ToolData* pTdata, int nGenCtx, int nToolCtx, bool bToSave) const ;
|
||||
int UpdateCustomToolDraw( const ToolData* pTdata, int nGenCtx, int nToolCtx, bool bToSave) const ;
|
||||
std::string GetToolMakerKeyFromType( int nType) const ;
|
||||
|
||||
+6
-4
@@ -528,10 +528,10 @@ MachMgr::UpdateAllToolDraws( void) const
|
||||
bool bNoDraw = ( ! sDraw.empty() && ! ExistsFile( sToolDir + "\\" + sDraw)) ;
|
||||
// se modificato o senza disegno, ne lancio la creazione e aggiorno dati portautensile
|
||||
if ( bModif || bNoDraw) {
|
||||
double dTHoldLen = 0, dTHoldDiam = 0 ;
|
||||
UpdateToolDraw( UuidTool, dTHoldLen, dTHoldDiam) ;
|
||||
double dTHoldBase = 0, dTHoldLen = 0, dTHoldDiam = 0 ;
|
||||
UpdateToolDraw( UuidTool, dTHoldBase, dTHoldLen, dTHoldDiam) ;
|
||||
pTsMgr->SetCurrTool( sName) ;
|
||||
pTsMgr->UpdateCurrToolHolderData( dTHoldLen, dTHoldDiam) ;
|
||||
pTsMgr->UpdateCurrToolHolderData( dTHoldBase, dTHoldLen, dTHoldDiam) ;
|
||||
pTsMgr->SaveCurrTool() ;
|
||||
pTsMgr->SetCurrTool( "") ;
|
||||
}
|
||||
@@ -548,7 +548,7 @@ MachMgr::UpdateAllToolDraws( void) const
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
MachMgr::UpdateToolDraw( const EgtUUID& UuidTool, double& dTHoldLen, double& dTHoldDiam) const
|
||||
MachMgr::UpdateToolDraw( const EgtUUID& UuidTool, double& dTHoldBase, double& dTHoldLen, double& dTHoldDiam) const
|
||||
{
|
||||
// recupero il gestore di utensili della macchina corrente
|
||||
ToolsMgr* pTsMgr = GetCurrToolsMgr() ;
|
||||
@@ -589,6 +589,8 @@ MachMgr::UpdateToolDraw( const EgtUUID& UuidTool, double& dTHoldLen, double& dTH
|
||||
bOk = bOk && ExeSaveFile( sDrawPath, GDB_SV_BIN) ;
|
||||
// Recupero i dati del portautensile
|
||||
int nToolId = ExeGetFirstGroupInGroup( GDB_ID_ROOT) ;
|
||||
if ( ! ExeGetInfo( nToolId, TTH_BASE, dTHoldBase))
|
||||
dTHoldBase = 0 ;
|
||||
if ( ! ExeGetInfo( nToolId, TTH_LEN, dTHoldLen))
|
||||
dTHoldLen = 0 ;
|
||||
if ( ! ExeGetInfo( nToolId, TTH_DIAM, dTHoldDiam))
|
||||
|
||||
@@ -171,6 +171,8 @@ Machine::LoadTool( Exit* pExit, const string& sTool)
|
||||
return false ;
|
||||
// sposto eventuali info relative al porta utensile (ToolHolder) nel gruppo SOLID
|
||||
double dVal ;
|
||||
if ( m_pGeomDB->GetInfo( nTGrpId, TTH_BASE, dVal))
|
||||
m_pGeomDB->SetInfo( nSolidId, TTH_BASE, dVal) ;
|
||||
if ( m_pGeomDB->GetInfo( nTGrpId, TTH_LEN, dVal))
|
||||
m_pGeomDB->SetInfo( nSolidId, TTH_LEN, dVal) ;
|
||||
if ( m_pGeomDB->GetInfo( nTGrpId, TTH_DIAM, dVal))
|
||||
|
||||
+7
-1
@@ -109,6 +109,7 @@ Milling::Clone( void) const
|
||||
pMill->m_nPhase = m_nPhase ;
|
||||
pMill->m_Params = m_Params ;
|
||||
pMill->m_TParams = m_TParams ;
|
||||
pMill->m_dTHoldBase = m_dTHoldBase ;
|
||||
pMill->m_dTHoldLen = m_dTHoldLen ;
|
||||
pMill->m_dTHoldDiam = m_dTHoldDiam ;
|
||||
pMill->m_nStatus = m_nStatus ;
|
||||
@@ -232,6 +233,7 @@ Milling::Milling( void)
|
||||
m_Params.m_sToolName = "*" ;
|
||||
m_TParams.m_sName = "*" ;
|
||||
m_TParams.m_sHead = "*" ;
|
||||
m_dTHoldBase = 0 ;
|
||||
m_dTHoldLen = 0 ;
|
||||
m_dTHoldDiam = 0 ;
|
||||
m_nStatus = MCH_ST_TO_VERIFY ;
|
||||
@@ -652,6 +654,8 @@ Milling::Preview( bool bRecalc)
|
||||
}
|
||||
// recupero i dati del portautensile
|
||||
int nToolId = m_pMchMgr->GetCalcTool() ;
|
||||
m_dTHoldBase = 0 ;
|
||||
m_pGeomDB->GetInfo( nToolId, TTH_BASE, m_dTHoldBase) ;
|
||||
m_dTHoldLen = 0 ;
|
||||
m_pGeomDB->GetInfo( nToolId, TTH_LEN, m_dTHoldLen) ;
|
||||
m_dTHoldDiam = 0 ;
|
||||
@@ -757,6 +761,8 @@ Milling::Apply( bool bRecalc, bool bPostApply)
|
||||
}
|
||||
// recupero i dati del portautensile
|
||||
int nToolId = m_pMchMgr->GetCalcTool() ;
|
||||
m_dTHoldBase = 0 ;
|
||||
m_pGeomDB->GetInfo( nToolId, TTH_BASE, m_dTHoldBase) ;
|
||||
m_dTHoldLen = 0 ;
|
||||
m_pGeomDB->GetInfo( nToolId, TTH_LEN, m_dTHoldLen) ;
|
||||
m_dTHoldDiam = 0 ;
|
||||
@@ -1800,7 +1806,7 @@ Milling::ProcessPath( int nPathId, int nPvId, int nClId)
|
||||
else {
|
||||
// massimo affondamento dell'utensile
|
||||
double dSafe = m_pMchMgr->GetCurrMachiningsMgr()->GetMaxDepthSafe() ;
|
||||
double dMaxDepth = m_TParams.m_dLen - ( m_TParams.m_dDiam > m_dTHoldDiam ? 0 : m_dTHoldLen) - dSafe ;
|
||||
double dMaxDepth = m_TParams.m_dLen - ( m_TParams.m_dDiam > m_dTHoldDiam ? m_dTHoldBase : m_dTHoldLen) - dSafe ;
|
||||
// se c'è oscillazione e l'elevazione complessiva supera la capacità dell'utensile, annullo l'oscillazione
|
||||
if ( bPathOscEnable && dElev + dAddElev > dMaxDepth + EPS_SMALL) {
|
||||
bPathOscEnable = false ;
|
||||
|
||||
@@ -149,6 +149,7 @@ class Milling : public Machining
|
||||
SELVECTOR m_vId ; // identificativi entità geometriche da lavorare
|
||||
MillingData m_Params ; // parametri lavorazione
|
||||
ToolData m_TParams ; // parametri utensile
|
||||
double m_dTHoldBase ; // posizione base del porta-utensile
|
||||
double m_dTHoldLen ; // lunghezza del porta-utensile
|
||||
double m_dTHoldDiam ; // diametro del porta-utensile
|
||||
int m_nStatus ; // stato di aggiornamento della lavorazione
|
||||
|
||||
+9
-1
@@ -110,6 +110,9 @@ Pocketing::Clone( void) const
|
||||
pPock->m_nPhase = m_nPhase ;
|
||||
pPock->m_Params = m_Params ;
|
||||
pPock->m_TParams = m_TParams ;
|
||||
pPock->m_dTHoldBase = m_dTHoldBase ;
|
||||
pPock->m_dTHoldLen = m_dTHoldLen ;
|
||||
pPock->m_dTHoldDiam = m_dTHoldDiam ;
|
||||
pPock->m_nStatus = m_nStatus ;
|
||||
pPock->m_nPockets = m_nPockets ;
|
||||
pPock->m_bTiltingTab = m_bTiltingTab ;
|
||||
@@ -231,6 +234,7 @@ Pocketing::Pocketing( void)
|
||||
m_Params.m_sToolName = "*" ;
|
||||
m_TParams.m_sName = "*" ;
|
||||
m_TParams.m_sHead = "*" ;
|
||||
m_dTHoldBase = 0 ;
|
||||
m_dTHoldLen = 0 ;
|
||||
m_dTHoldDiam = 0 ;
|
||||
m_dMaxHelixRad = INFINITO ;
|
||||
@@ -552,6 +556,8 @@ Pocketing::Preview( bool bRecalc)
|
||||
}
|
||||
// recupero i dati del portautensile
|
||||
int nToolId = m_pMchMgr->GetCalcTool() ;
|
||||
m_dTHoldBase = 0 ;
|
||||
m_pGeomDB->GetInfo( nToolId, TTH_BASE, m_dTHoldBase) ;
|
||||
m_dTHoldLen = 0 ;
|
||||
m_pGeomDB->GetInfo( nToolId, TTH_LEN, m_dTHoldLen) ;
|
||||
m_dTHoldDiam = 0 ;
|
||||
@@ -643,6 +649,8 @@ Pocketing::Apply( bool bRecalc, bool bPostApply)
|
||||
}
|
||||
// recupero i dati del portautensile
|
||||
int nToolId = m_pMchMgr->GetCalcTool() ;
|
||||
m_dTHoldBase = 0 ;
|
||||
m_pGeomDB->GetInfo( nToolId, TTH_BASE, m_dTHoldBase) ;
|
||||
m_dTHoldLen = 0 ;
|
||||
m_pGeomDB->GetInfo( nToolId, TTH_LEN, m_dTHoldLen) ;
|
||||
m_dTHoldDiam = 0 ;
|
||||
@@ -1585,7 +1593,7 @@ Pocketing::ProcessPath( int nPathId, int nPvId, int nClId)
|
||||
else {
|
||||
// se l'elevazione supera il massimo affondamento dell'utensile
|
||||
double dSafe = m_pMchMgr->GetCurrMachiningsMgr()->GetMaxDepthSafe() ;
|
||||
double dMaxDepth = m_TParams.m_dLen - ( m_TParams.m_dDiam > m_dTHoldDiam ? 0 : m_dTHoldLen) - dSafe ;
|
||||
double dMaxDepth = m_TParams.m_dLen - ( m_TParams.m_dDiam > m_dTHoldDiam ? m_dTHoldBase : m_dTHoldLen) - dSafe ;
|
||||
if ( dElev > dMaxDepth + EPS_SMALL) {
|
||||
// segnalo, riduco e continuo
|
||||
string sInfo = "Warning in Pocketing : machining depth (" + ToString( dElev, 1) +
|
||||
|
||||
@@ -171,6 +171,7 @@ class Pocketing : public Machining
|
||||
SELVECTOR m_vId ; // identificativi entità geometriche da lavorare
|
||||
PocketingData m_Params ; // parametri lavorazione
|
||||
ToolData m_TParams ; // parametri utensile
|
||||
double m_dTHoldBase ; // posizione base del porta-utensile
|
||||
double m_dTHoldLen ; // lunghezza del porta-utensile
|
||||
double m_dTHoldDiam ; // diametro del porta-utensile
|
||||
double m_dMaxHelixRad ; // raggio massimo attacco ad elica nel caso di cerchi
|
||||
|
||||
@@ -88,6 +88,9 @@ SurfFinishing::Clone( void) const
|
||||
pSrF->m_nPhase = m_nPhase ;
|
||||
pSrF->m_Params = m_Params ;
|
||||
pSrF->m_TParams = m_TParams ;
|
||||
pSrF->m_dTHoldBase = m_dTHoldBase ;
|
||||
pSrF->m_dTHoldLen = m_dTHoldLen ;
|
||||
pSrF->m_dTHoldDiam = m_dTHoldDiam ;
|
||||
pSrF->m_nStatus = m_nStatus ;
|
||||
pSrF->m_nPaths = m_nPaths ;
|
||||
}
|
||||
@@ -201,6 +204,7 @@ SurfFinishing::SurfFinishing( void)
|
||||
m_Params.m_sToolName = "*" ;
|
||||
m_TParams.m_sName = "*" ;
|
||||
m_TParams.m_sHead = "*" ;
|
||||
m_dTHoldBase = 0 ;
|
||||
m_dTHoldLen = 0 ;
|
||||
m_dTHoldDiam = 0 ;
|
||||
m_nStatus = MCH_ST_TO_VERIFY ;
|
||||
@@ -528,6 +532,8 @@ SurfFinishing::Apply( bool bRecalc, bool bPostApply)
|
||||
}
|
||||
// recupero i dati del portautensile
|
||||
int nToolId = m_pMchMgr->GetCalcTool() ;
|
||||
m_dTHoldBase = 0 ;
|
||||
m_pGeomDB->GetInfo( nToolId, TTH_BASE, m_dTHoldBase) ;
|
||||
m_dTHoldLen = 0 ;
|
||||
m_pGeomDB->GetInfo( nToolId, TTH_LEN, m_dTHoldLen) ;
|
||||
m_dTHoldDiam = 0 ;
|
||||
|
||||
@@ -113,6 +113,7 @@ class SurfFinishing : public Machining
|
||||
SELVECTOR m_vId ; // identificativi entità geometriche da lavorare
|
||||
SurfFinishingData m_Params ; // parametri lavorazione
|
||||
ToolData m_TParams ; // parametri utensile
|
||||
double m_dTHoldBase ; // posizione base del porta-utensile
|
||||
double m_dTHoldLen ; // lunghezza del porta-utensile
|
||||
double m_dTHoldDiam ; // diametro del porta-utensile
|
||||
int m_nStatus ; // stato di aggiornamento della lavorazione
|
||||
|
||||
+17
-7
@@ -561,12 +561,13 @@ ToolsMgr::SaveCurrTool( void)
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
ToolsMgr::UpdateCurrToolHolderData( double dTHoldLen, double dTHoldDiam)
|
||||
ToolsMgr::UpdateCurrToolHolderData( double dTHoldBase, double dTHoldLen, double dTHoldDiam)
|
||||
{
|
||||
// verifico validità utensile corrente
|
||||
if ( ! m_bCurrTool)
|
||||
return false ;
|
||||
// Aggiorno i dati nelle note di sistema
|
||||
SetValInNotes( TSI_THBASE, dTHoldBase, m_tdCurrTool.m_sSysNotes) ;
|
||||
SetValInNotes( TSI_THLEN, dTHoldLen, m_tdCurrTool.m_sSysNotes) ;
|
||||
SetValInNotes( TSI_THDIAM, dTHoldDiam, m_tdCurrTool.m_sSysNotes) ;
|
||||
return true ;
|
||||
@@ -679,21 +680,24 @@ ToolsMgr::GetCurrToolMaxDepth( double dSafe, double& dMaxDepth) const
|
||||
// se fresa
|
||||
else if ( ( m_tdCurrTool.m_nType & TF_MILL) != 0) {
|
||||
// recupero le dimensioni del porta utensili
|
||||
double dTHoldBase = 0 ;
|
||||
double dTHoldLen = 0 ;
|
||||
double dTHoldDiam = 0 ;
|
||||
if ( ! GetValInNotes( m_tdCurrTool.m_sSysNotes, TSI_THLEN, dTHoldLen) ||
|
||||
if ( ! GetValInNotes( m_tdCurrTool.m_sSysNotes, TSI_THBASE, dTHoldBase) ||
|
||||
! GetValInNotes( m_tdCurrTool.m_sSysNotes, TSI_THLEN, dTHoldLen) ||
|
||||
! GetValInNotes( m_tdCurrTool.m_sSysNotes, TSI_THDIAM, dTHoldDiam)) {
|
||||
(const_cast<ToolsMgr*>(this))->SaveCurrTool() ;
|
||||
Save() ;
|
||||
GetValInNotes( m_tdCurrTool.m_sSysNotes, TSI_THBASE, dTHoldBase) ;
|
||||
GetValInNotes( m_tdCurrTool.m_sSysNotes, TSI_THLEN, dTHoldLen) ;
|
||||
GetValInNotes( m_tdCurrTool.m_sSysNotes, TSI_THDIAM, dTHoldDiam) ;
|
||||
}
|
||||
// calcolo il massimo affondamento (lunghezza TH negativa significa che TH è parte della testa)
|
||||
// calcolo il massimo affondamento
|
||||
dMaxDepth = m_tdCurrTool.m_dLen - dSafe ;
|
||||
if ( m_tdCurrTool.m_dDiam > dTHoldDiam)
|
||||
dMaxDepth -= min( 0., dTHoldLen) ;
|
||||
dMaxDepth -= dTHoldBase ;
|
||||
else
|
||||
dMaxDepth -= max( 0., dTHoldLen) ;
|
||||
dMaxDepth -= dTHoldLen ;
|
||||
return true ;
|
||||
}
|
||||
// se mortasatrice o sega a catena
|
||||
@@ -734,12 +738,15 @@ ToolsMgr::GetCurrToolThDiam( double& dThDiam) const
|
||||
( m_tdCurrTool.m_nType & TF_MILL) != 0 ||
|
||||
( m_tdCurrTool.m_nType & TF_CHISEL) != 0) {
|
||||
// recupero le dimensioni del porta utensili
|
||||
double dTHoldBase = 0 ;
|
||||
double dTHoldLen = 0 ;
|
||||
double dTHoldDiam = 0 ;
|
||||
if ( ! GetValInNotes( m_tdCurrTool.m_sSysNotes, TSI_THLEN, dTHoldLen) ||
|
||||
if ( ! GetValInNotes( m_tdCurrTool.m_sSysNotes, TSI_THBASE, dTHoldBase) ||
|
||||
! GetValInNotes( m_tdCurrTool.m_sSysNotes, TSI_THLEN, dTHoldLen) ||
|
||||
! GetValInNotes( m_tdCurrTool.m_sSysNotes, TSI_THDIAM, dTHoldDiam)) {
|
||||
(const_cast<ToolsMgr*>(this))->SaveCurrTool() ;
|
||||
Save() ;
|
||||
GetValInNotes( m_tdCurrTool.m_sSysNotes, TSI_THBASE, dTHoldBase) ;
|
||||
GetValInNotes( m_tdCurrTool.m_sSysNotes, TSI_THLEN, dTHoldLen) ;
|
||||
GetValInNotes( m_tdCurrTool.m_sSysNotes, TSI_THDIAM, dTHoldDiam) ;
|
||||
}
|
||||
@@ -770,12 +777,15 @@ ToolsMgr::GetCurrToolThLength( double& dThLen) const
|
||||
( m_tdCurrTool.m_nType & TF_MILL) != 0 ||
|
||||
( m_tdCurrTool.m_nType & TF_CHISEL) != 0) {
|
||||
// recupero le dimensioni del porta utensili
|
||||
double dTHoldBase = 0 ;
|
||||
double dTHoldLen = 0 ;
|
||||
double dTHoldDiam = 0 ;
|
||||
if ( ! GetValInNotes( m_tdCurrTool.m_sSysNotes, TSI_THLEN, dTHoldLen) ||
|
||||
if ( ! GetValInNotes( m_tdCurrTool.m_sSysNotes, TSI_THBASE, dTHoldBase) ||
|
||||
! GetValInNotes( m_tdCurrTool.m_sSysNotes, TSI_THLEN, dTHoldLen) ||
|
||||
! GetValInNotes( m_tdCurrTool.m_sSysNotes, TSI_THDIAM, dTHoldDiam)) {
|
||||
(const_cast<ToolsMgr*>(this))->SaveCurrTool() ;
|
||||
Save() ;
|
||||
GetValInNotes( m_tdCurrTool.m_sSysNotes, TSI_THBASE, dTHoldBase) ;
|
||||
GetValInNotes( m_tdCurrTool.m_sSysNotes, TSI_THLEN, dTHoldLen) ;
|
||||
GetValInNotes( m_tdCurrTool.m_sSysNotes, TSI_THDIAM, dTHoldDiam) ;
|
||||
}
|
||||
|
||||
+1
-1
@@ -56,7 +56,7 @@ class ToolsMgr
|
||||
bool GetCurrToolParam( int nType, double& dVal) const ;
|
||||
bool GetCurrToolParam( int nType, std::string& sVal) const ;
|
||||
template <class T> bool GetCurrToolValInNotes( int nType, const std::string& sKey, T& Val) const ;
|
||||
bool UpdateCurrToolHolderData( double dTHoldLen, double dTHoldDiam) ;
|
||||
bool UpdateCurrToolHolderData( double dTHoldBase, double dTHoldLen, double dTHoldDiam) ;
|
||||
bool GetCurrToolMaxDepth( double dSafe, double& dMaxDepth) const ;
|
||||
bool GetCurrToolThDiam( double& dThDiam) const ;
|
||||
bool GetCurrToolThLength( double& dThLen) const ;
|
||||
|
||||
@@ -89,6 +89,7 @@ WaterJetting::Clone( void) const
|
||||
pWJ->m_nPhase = m_nPhase ;
|
||||
pWJ->m_Params = m_Params ;
|
||||
pWJ->m_TParams = m_TParams ;
|
||||
pWJ->m_dTHoldBase = m_dTHoldBase ;
|
||||
pWJ->m_dTHoldLen = m_dTHoldLen ;
|
||||
pWJ->m_dTHoldDiam = m_dTHoldDiam ;
|
||||
pWJ->m_dElev = m_dElev ;
|
||||
@@ -207,6 +208,7 @@ WaterJetting::WaterJetting( void)
|
||||
m_Params.m_sToolName = "*" ;
|
||||
m_TParams.m_sName = "*" ;
|
||||
m_TParams.m_sHead = "*" ;
|
||||
m_dTHoldBase = 0 ;
|
||||
m_dTHoldLen = 0 ;
|
||||
m_dTHoldDiam = 0 ;
|
||||
m_dElev = 0 ;
|
||||
@@ -563,6 +565,8 @@ WaterJetting::Preview( bool bRecalc)
|
||||
}
|
||||
// recupero i dati del portautensile
|
||||
int nToolId = m_pMchMgr->GetCalcTool() ;
|
||||
m_dTHoldBase = 0 ;
|
||||
m_pGeomDB->GetInfo( nToolId, TTH_BASE, m_dTHoldBase) ;
|
||||
m_dTHoldLen = 0 ;
|
||||
m_pGeomDB->GetInfo( nToolId, TTH_LEN, m_dTHoldLen) ;
|
||||
m_dTHoldDiam = 0 ;
|
||||
@@ -656,6 +660,8 @@ WaterJetting::Apply( bool bRecalc, bool bPostApply)
|
||||
}
|
||||
// recupero i dati del portautensile
|
||||
int nToolId = m_pMchMgr->GetCalcTool() ;
|
||||
m_dTHoldBase = 0 ;
|
||||
m_pGeomDB->GetInfo( nToolId, TTH_BASE, m_dTHoldBase) ;
|
||||
m_dTHoldLen = 0 ;
|
||||
m_pGeomDB->GetInfo( nToolId, TTH_LEN, m_dTHoldLen) ;
|
||||
m_dTHoldDiam = 0 ;
|
||||
|
||||
@@ -121,6 +121,7 @@ class WaterJetting : public Machining
|
||||
SELVECTOR m_vId ; // identificativi entità geometriche da lavorare
|
||||
WaterJettingData m_Params ; // parametri lavorazione
|
||||
ToolData m_TParams ; // parametri utensile
|
||||
double m_dTHoldBase ; // posizione base del porta-utensile
|
||||
double m_dTHoldLen ; // lunghezza del porta-utensile
|
||||
double m_dTHoldDiam ; // diametro del porta-utensile
|
||||
double m_dElev ; // elevazione del percorso tenendo conto dell'angolo di fianco
|
||||
|
||||
Reference in New Issue
Block a user