mirror of
https://gitlab.com/kicad/code/kicad.git
synced 2025-09-13 17:53:11 +02:00
Auto-convert numeric values in fields when referencing them in expressions.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/21723
This commit is contained in:
parent
aa4de22ef4
commit
2c102a62e0
@ -708,6 +708,104 @@ double EDA_UNIT_UTILS::UI::DoubleValueFromString( const EDA_IU_SCALE& aIuScale,
|
||||
}
|
||||
|
||||
|
||||
bool EDA_UNIT_UTILS::UI::DoubleValueFromString( const EDA_IU_SCALE& aIuScale, const wxString& aTextValue,
|
||||
double& aDoubleValue )
|
||||
{
|
||||
double dtmp = 0;
|
||||
|
||||
// Acquire the 'right' decimal point separator
|
||||
const struct lconv* lc = localeconv();
|
||||
|
||||
wxChar decimal_point = lc->decimal_point[0];
|
||||
wxString buf( aTextValue.Strip( wxString::both ) );
|
||||
|
||||
// Convert any entered decimal point separators to the 'right' one
|
||||
buf.Replace( wxT( "." ), wxString( decimal_point, 1 ) );
|
||||
buf.Replace( wxT( "," ), wxString( decimal_point, 1 ) );
|
||||
|
||||
// Find the end of the numeric part
|
||||
unsigned brk_point = 0;
|
||||
|
||||
while( brk_point < buf.Len() )
|
||||
{
|
||||
wxChar ch = buf[brk_point];
|
||||
|
||||
if( !( (ch >= '0' && ch <= '9') || (ch == decimal_point) || (ch == '-') || (ch == '+') ) )
|
||||
break;
|
||||
|
||||
++brk_point;
|
||||
}
|
||||
|
||||
if( brk_point == 0 )
|
||||
return false;
|
||||
|
||||
// Extract the numeric part
|
||||
buf.Left( brk_point ).ToDouble( &dtmp );
|
||||
|
||||
// Check the unit designator
|
||||
wxString unit( buf.Mid( brk_point ).Strip( wxString::both ).Lower() );
|
||||
EDA_UNITS units;
|
||||
|
||||
//check for um, μm (µ is MICRO SIGN) and µm (µ is GREEK SMALL LETTER MU) for micrometre
|
||||
if( unit == wxT( "um" ) || unit == wxT( "\u00B5m" ) || unit == wxT( "\u03BCm" ) )
|
||||
{
|
||||
units = EDA_UNITS::UM;
|
||||
}
|
||||
else if( unit == wxT( "mm" ) )
|
||||
{
|
||||
units = EDA_UNITS::MM;
|
||||
}
|
||||
else if( unit == wxT( "cm" ) )
|
||||
{
|
||||
units = EDA_UNITS::CM;
|
||||
}
|
||||
else if( unit == wxT( "mil" ) || unit == wxT( "mils" ) || unit == wxT( "thou" ) )
|
||||
{
|
||||
units = EDA_UNITS::MILS;
|
||||
}
|
||||
else if( unit == wxT( "in" ) || unit == wxT( "\"" ) )
|
||||
{
|
||||
units = EDA_UNITS::INCH;
|
||||
}
|
||||
else if( unit == wxT( "oz" ) ) // 1 oz = 1.37 mils
|
||||
{
|
||||
units = EDA_UNITS::MILS;
|
||||
dtmp *= 1.37;
|
||||
}
|
||||
else if( unit == wxT( "ra" ) ) // Radians
|
||||
{
|
||||
dtmp *= 180.0f / M_PI;
|
||||
}
|
||||
else if( unit == wxT( "fs" ) )
|
||||
{
|
||||
units = EDA_UNITS::FS;
|
||||
}
|
||||
else if( unit == wxT( "ps" ) )
|
||||
{
|
||||
units = EDA_UNITS::PS;
|
||||
}
|
||||
else if( unit == wxT( "ps/in" ) )
|
||||
{
|
||||
units = EDA_UNITS::PS_PER_INCH;
|
||||
}
|
||||
else if( unit == wxT( "ps/cm" ) )
|
||||
{
|
||||
units = EDA_UNITS::PS_PER_CM;
|
||||
}
|
||||
else if( unit == wxT( "ps/mm" ) )
|
||||
{
|
||||
units = EDA_UNITS::PS_PER_MM;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
aDoubleValue = FromUserUnit( aIuScale, units, dtmp );
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
long long int EDA_UNIT_UTILS::UI::ValueFromString( const EDA_IU_SCALE& aIuScale, EDA_UNITS aUnits,
|
||||
const wxString& aTextValue, EDA_DATA_TYPE aType )
|
||||
{
|
||||
|
@ -256,6 +256,9 @@ namespace EDA_UNIT_UTILS
|
||||
|
||||
KICOMMON_API double DoubleValueFromString( const wxString& aTextValue );
|
||||
|
||||
KICOMMON_API bool DoubleValueFromString( const EDA_IU_SCALE& aIuScale, const wxString& aTextValue,
|
||||
double& aDoubleValue );
|
||||
|
||||
/**
|
||||
* Convert \a aTextValue in \a aUnits to internal units used by the application.
|
||||
*
|
||||
|
@ -447,28 +447,33 @@ LIBEVAL::VALUE* PCBEXPR_VAR_REF::GetValue( LIBEVAL::CONTEXT* aCtx )
|
||||
|
||||
if( it->second->Name() == wxT( "Pin Type" ) )
|
||||
return new PCBEXPR_PINTYPE_VALUE( str );
|
||||
else
|
||||
return new LIBEVAL::VALUE( str );
|
||||
|
||||
// If it quacks like a duck, it is a duck
|
||||
double doubleVal;
|
||||
|
||||
if( EDA_UNIT_UTILS::UI::DoubleValueFromString( pcbIUScale, str, doubleVal ) )
|
||||
return new LIBEVAL::VALUE( doubleVal );
|
||||
|
||||
return new LIBEVAL::VALUE( str );
|
||||
}
|
||||
else
|
||||
else if( it->second->Name() == wxT( "Layer" )
|
||||
|| it->second->Name() == wxT( "Layer Top" )
|
||||
|| it->second->Name() == wxT( "Layer Bottom" ) )
|
||||
{
|
||||
const wxAny& any = item->Get( it->second );
|
||||
PCB_LAYER_ID layer;
|
||||
|
||||
if( it->second->Name() == wxT( "Layer" )
|
||||
|| it->second->Name() == wxT( "Layer Top" )
|
||||
|| it->second->Name() == wxT( "Layer Bottom" ) )
|
||||
{
|
||||
if( any.GetAs<PCB_LAYER_ID>( &layer ) )
|
||||
return new PCBEXPR_LAYER_VALUE( layer );
|
||||
else if( any.GetAs<wxString>( &str ) )
|
||||
return new PCBEXPR_LAYER_VALUE( context->GetBoard()->GetLayerID( str ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
if( any.GetAs<wxString>( &str ) )
|
||||
return new LIBEVAL::VALUE( str );
|
||||
}
|
||||
if( any.GetAs<PCB_LAYER_ID>( &layer ) )
|
||||
return new PCBEXPR_LAYER_VALUE( layer );
|
||||
else if( any.GetAs<wxString>( &str ) )
|
||||
return new PCBEXPR_LAYER_VALUE( context->GetBoard()->GetLayerID( str ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
const wxAny& any = item->Get( it->second );
|
||||
|
||||
if( any.GetAs<wxString>( &str ) )
|
||||
return new LIBEVAL::VALUE( str );
|
||||
}
|
||||
|
||||
return new LIBEVAL::VALUE();
|
||||
|
Loading…
x
Reference in New Issue
Block a user