diff --git a/api/proto/common/types/project_settings.proto b/api/proto/common/types/project_settings.proto
index 5af1320464..7e8b03e87a 100644
--- a/api/proto/common/types/project_settings.proto
+++ b/api/proto/common/types/project_settings.proto
@@ -49,6 +49,9 @@ message NetClassBoardSettings
optional kiapi.board.types.PadStack microvia_stack = 7;
optional kiapi.common.types.Color color = 8;
+
+ // Since 10.0.0
+ optional string tuning_profile = 9;
}
message NetClassSchematicSettings
diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt
index 8cf87308e6..3c7440e2d1 100644
--- a/common/CMakeLists.txt
+++ b/common/CMakeLists.txt
@@ -153,7 +153,7 @@ set( KICOMMON_SRCS
project/project_archiver.cpp
project/project_file.cpp
project/project_local_settings.cpp
- project/time_domain_parameters.cpp
+ project/tuning_profiles.cpp
text_eval/text_eval_wrapper.cpp
text_eval/text_eval_parser.cpp
@@ -959,7 +959,7 @@ set( PCB_COMMON_SRCS
${CMAKE_SOURCE_DIR}/pcbnew/length_delay_calculation/length_delay_calculation.cpp
${CMAKE_SOURCE_DIR}/pcbnew/length_delay_calculation/length_delay_calculation_item.cpp
- ${CMAKE_SOURCE_DIR}/pcbnew/length_delay_calculation/time_domain_parameters_user_defined.cpp
+ ${CMAKE_SOURCE_DIR}/pcbnew/length_delay_calculation/tuning_profile_parameters_user_defined.cpp
widgets/net_selector.cpp
)
diff --git a/common/dialogs/panel_setup_netclasses.cpp b/common/dialogs/panel_setup_netclasses.cpp
index a1c6dbba18..91a62a0aa9 100644
--- a/common/dialogs/panel_setup_netclasses.cpp
+++ b/common/dialogs/panel_setup_netclasses.cpp
@@ -287,7 +287,7 @@ void PANEL_SETUP_NETCLASSES::loadNetclasses()
[&]( int aRow, const NETCLASS* nc )
{
m_netclassGrid->SetCellValue( aRow, GRID_NAME, nc->GetName() );
- m_netclassGrid->SetCellValue( aRow, GRID_DELAY_PROFILE, nc->GetDelayProfile() );
+ m_netclassGrid->SetCellValue( aRow, GRID_DELAY_PROFILE, nc->GetTuningProfile() );
m_netclassGrid->SetOptionalUnitValue( aRow, GRID_WIREWIDTH, nc->GetWireWidthOpt() );
m_netclassGrid->SetOptionalUnitValue( aRow, GRID_BUSWIDTH, nc->GetBusWidthOpt() );
@@ -486,7 +486,7 @@ bool PANEL_SETUP_NETCLASSES::TransferDataFromWindow()
nc->SetPriority( aRow );
nc->SetName( m_netclassGrid->GetCellValue( aRow, GRID_NAME ) );
- nc->SetDelayProfile( m_netclassGrid->GetCellValue( aRow, GRID_DELAY_PROFILE ) );
+ nc->SetTuningProfile( m_netclassGrid->GetCellValue( aRow, GRID_DELAY_PROFILE ) );
nc->SetWireWidth( m_netclassGrid->GetOptionalUnitValue( aRow, GRID_WIREWIDTH ) );
nc->SetBusWidth( m_netclassGrid->GetOptionalUnitValue( aRow, GRID_BUSWIDTH ) );
diff --git a/common/dialogs/panel_setup_netclasses_base.cpp b/common/dialogs/panel_setup_netclasses_base.cpp
index 127a5f60e1..a7a8c3355f 100644
--- a/common/dialogs/panel_setup_netclasses_base.cpp
+++ b/common/dialogs/panel_setup_netclasses_base.cpp
@@ -57,7 +57,7 @@ PANEL_SETUP_NETCLASSES_BASE::PANEL_SETUP_NETCLASSES_BASE( wxWindow* parent, wxWi
m_netclassGrid->SetColLabelValue( 6, _("uVia Hole") );
m_netclassGrid->SetColLabelValue( 7, _("DP Width") );
m_netclassGrid->SetColLabelValue( 8, _("DP Gap") );
- m_netclassGrid->SetColLabelValue( 9, _("Delay Profile") );
+ m_netclassGrid->SetColLabelValue( 9, _("Tuning Profile") );
m_netclassGrid->SetColLabelValue( 10, _("PCB Color") );
m_netclassGrid->SetColLabelValue( 11, _("Wire Thickness") );
m_netclassGrid->SetColLabelValue( 12, _("Bus Thickness") );
diff --git a/common/dialogs/panel_setup_netclasses_base.fbp b/common/dialogs/panel_setup_netclasses_base.fbp
index 24fde54d1f..f30477045e 100644
--- a/common/dialogs/panel_setup_netclasses_base.fbp
+++ b/common/dialogs/panel_setup_netclasses_base.fbp
@@ -290,7 +290,7 @@
1
wxALIGN_CENTER
wxGRID_AUTOSIZE
- "Name" "Clearance" "Track Width" "Via Size" "Via Hole" "uVia Size" "uVia Hole" "DP Width" "DP Gap" "Delay Profile" "PCB Color" "Wire Thickness" "Bus Thickness" "Color" "Line Style"
+ "Name" "Clearance" "Track Width" "Via Size" "Via Hole" "uVia Size" "uVia Hole" "DP Width" "DP Gap" "Tuning Profile" "PCB Color" "Wire Thickness" "Bus Thickness" "Color" "Line Style"
wxALIGN_CENTER
15
diff --git a/common/netclass.cpp b/common/netclass.cpp
index 3d4027ede5..bd42cca791 100644
--- a/common/netclass.cpp
+++ b/common/netclass.cpp
@@ -59,7 +59,7 @@ NETCLASS::NETCLASS( const wxString& aName, bool aInitWithDefaults ) : m_isDefaul
SetName( aName );
SetPriority( -1 );
- SetDelayProfile( wxEmptyString );
+ SetTuningProfile( wxEmptyString );
// Colors are a special optional case - always set, but UNSPECIFIED used in place of optional
SetPcbColor( COLOR4D::UNSPECIFIED );
@@ -102,7 +102,7 @@ void NETCLASS::ResetParents()
SetBusWidthParent( this );
SetSchematicColorParent( this );
SetLineStyleParent( this );
- SetDelayProfileParent( this );
+ SetTuningProfileParent( this );
}
@@ -180,6 +180,9 @@ void NETCLASS::Serialize( google::protobuf::Any &aContainer ) const
if( m_pcbColor != COLOR4D::UNSPECIFIED )
PackColor( *board->mutable_color(), m_pcbColor );
+ if( m_tuningProfile != wxEmptyString )
+ board->set_tuning_profile( m_tuningProfile.ToUTF8() );
+
project::NetClassSchematicSettings* schematic = nc.mutable_schematic();
if( m_wireWidth )
@@ -246,6 +249,9 @@ bool NETCLASS::Deserialize( const google::protobuf::Any &aContainer )
if( nc.board().has_color() )
m_pcbColor = UnpackColor( nc.board().color() );
+ if( nc.board().has_tuning_profile() )
+ m_tuningProfile = wxString::FromUTF8( nc.board().tuning_profile() );
+
if( nc.schematic().has_wire_width() )
m_wireWidth = nc.schematic().wire_width().value_nm();
diff --git a/common/project/net_settings.cpp b/common/project/net_settings.cpp
index 4ad03ffb31..32d56e3004 100644
--- a/common/project/net_settings.cpp
+++ b/common/project/net_settings.cpp
@@ -76,7 +76,7 @@ NET_SETTINGS::NET_SETTINGS( JSON_SETTINGS* aParent, const std::string& aPath ) :
{ "priority", nc->GetPriority() },
{ "schematic_color", nc->GetSchematicColor( true ) },
{ "pcb_color", nc->GetPcbColor( true ) },
- { "tuning_profile", nc->GetDelayProfile() } };
+ { "tuning_profile", nc->GetTuningProfile() } };
auto saveInPcbUnits =
[]( nlohmann::json& json, const std::string& aKey, int aValue )
@@ -134,7 +134,7 @@ NET_SETTINGS::NET_SETTINGS( JSON_SETTINGS* aParent, const std::string& aPath ) :
int priority = entry["priority"];
nc->SetPriority( priority );
- nc->SetDelayProfile( entry["tuning_profile"] );
+ nc->SetTuningProfile( entry["tuning_profile"] );
if( auto value = getInPcbUnits( entry, "clearance" ) )
nc->SetClearance( *value );
@@ -925,10 +925,10 @@ void NET_SETTINGS::makeEffectiveNetclass( std::shared_ptr& effectiveNe
effectiveNetclass->SetSchematicColorParent( nc );
}
- if( nc->HasDelayProfile() )
+ if( nc->HasTuningProfile() )
{
- effectiveNetclass->SetDelayProfile( nc->GetDelayProfile() );
- effectiveNetclass->SetDelayProfileParent( nc );
+ effectiveNetclass->SetTuningProfile( nc->GetTuningProfile() );
+ effectiveNetclass->SetTuningProfileParent( nc );
}
}
@@ -1021,11 +1021,11 @@ bool NET_SETTINGS::addMissingDefaults( NETCLASS* nc ) const
}
// The tuning profile can be empty - only fill if a default tuning profile is set
- if( !nc->HasDelayProfile() && m_defaultNetClass->HasDelayProfile() )
+ if( !nc->HasTuningProfile() && m_defaultNetClass->HasTuningProfile() )
{
addedDefault = true;
- nc->SetDelayProfile( m_defaultNetClass->GetDelayProfile() );
- nc->SetDelayProfileParent( m_defaultNetClass.get() );
+ nc->SetTuningProfile( m_defaultNetClass->GetTuningProfile() );
+ nc->SetTuningProfileParent( m_defaultNetClass.get() );
}
return addedDefault;
diff --git a/common/project/project_file.cpp b/common/project/project_file.cpp
index 623bb9e566..67b7e5c826 100644
--- a/common/project/project_file.cpp
+++ b/common/project/project_file.cpp
@@ -22,7 +22,7 @@
#include
#include
#include
-#include
+#include
#include
#include
#include
@@ -160,8 +160,7 @@ PROJECT_FILE::PROJECT_FILE( const wxString& aFullPath ) :
m_ComponentClassSettings =
std::make_shared( this, "component_class_settings" );
- m_timeDomainParameters =
- std::make_shared( this, "time_domain_parameters" );
+ m_tuningProfileParameters = std::make_shared( this, "tuning_profiles" );
m_params.emplace_back( new PARAM_LAYER_PRESET( "board.layer_presets", &m_LayerPresets ) );
diff --git a/common/project/time_domain_parameters.cpp b/common/project/tuning_profiles.cpp
similarity index 50%
rename from common/project/time_domain_parameters.cpp
rename to common/project/tuning_profiles.cpp
index 3b7bdf14bf..361e3dd7ba 100644
--- a/common/project/time_domain_parameters.cpp
+++ b/common/project/tuning_profiles.cpp
@@ -21,18 +21,15 @@
#include
#include
-
-#include
-#include
+#include
#include
#include
-constexpr int timeDomainParametersSchemaVersion = 0;
+constexpr int tuningParametersSchemaVersion = 0;
-TIME_DOMAIN_PARAMETERS::TIME_DOMAIN_PARAMETERS( JSON_SETTINGS* aParent, const std::string& aPath ) :
- NESTED_SETTINGS( "time_domain_parameters", timeDomainParametersSchemaVersion, aParent,
- aPath, false )
+TUNING_PROFILES::TUNING_PROFILES( JSON_SETTINGS* aParent, const std::string& aPath ) :
+ NESTED_SETTINGS( "tuning_profiles", tuningParametersSchemaVersion, aParent, aPath, false )
{
auto saveViaOverrideConfigurationLine =
[]( nlohmann::json& json_array, const DELAY_PROFILE_VIA_OVERRIDE_ENTRY& item )
@@ -71,14 +68,22 @@ TIME_DOMAIN_PARAMETERS::TIME_DOMAIN_PARAMETERS( JSON_SETTINGS* aParent, const st
};
auto saveUserDefinedProfileConfigurationLine =
- [&saveViaOverrideConfigurationLine]( nlohmann::json& json_array, const DELAY_PROFILE& item )
+ [&saveViaOverrideConfigurationLine]( nlohmann::json& json_array, const TUNING_PROFILE& item )
{
- nlohmann::json layer_velocities = nlohmann::json::array();
+ nlohmann::json layer_entries = nlohmann::json::array();
- for( const auto& [layerId, velocity] : item.m_LayerPropagationDelays )
+ for( const DELAY_PROFILE_TRACK_PROPAGATION_ENTRY& trackEntry : item.m_TrackPropagationEntries )
{
- nlohmann::json layer_json = { { "layer", LSET::Name( layerId ) }, { "delay", velocity } };
- layer_velocities.push_back( layer_json );
+ nlohmann::json layer_json;
+
+ layer_json["signal_layer"] = LSET::Name( trackEntry.m_signalLayer );
+ layer_json["top_reference_layer"] = LSET::Name( trackEntry.m_topReferenceLayer );
+ layer_json["bottom_reference_layer"] = LSET::Name( trackEntry.m_bottomReferenceLayer );
+ layer_json["width"] = trackEntry.m_width;
+ layer_json["diff_pair_gap"] = trackEntry.m_diffPairGap;
+ layer_json["delay"] = trackEntry.m_delay;
+
+ layer_entries.push_back( layer_json );
}
nlohmann::json via_overrides = nlohmann::json::array();
@@ -89,8 +94,12 @@ TIME_DOMAIN_PARAMETERS::TIME_DOMAIN_PARAMETERS( JSON_SETTINGS* aParent, const st
}
const nlohmann::json item_json = { { "profile_name", item.m_ProfileName.ToUTF8() },
+ { "type", static_cast( item.m_Type ) },
+ { "target_impedance", item.m_TargetImpedance },
+ { "generate_drc_rules", item.m_GenerateNetClassDRCRules },
+ { "enable_time_domain_tuning", item.m_EnableTimeDomainTuning },
+ { "layer_entries", layer_entries },
{ "via_prop_delay", item.m_ViaPropagationDelay },
- { "layer_delays", layer_velocities },
{ "via_overrides", via_overrides } };
json_array.push_back( item_json );
@@ -98,19 +107,38 @@ TIME_DOMAIN_PARAMETERS::TIME_DOMAIN_PARAMETERS( JSON_SETTINGS* aParent, const st
auto readUserDefinedProfileConfigurationLine = [&readViaOverrideConfigurationLine]( const nlohmann::json& entry )
{
- const wxString profileName = entry["profile_name"];
- const int viaPropDelay = entry["via_prop_delay"];
- std::map traceDelays;
+ const wxString profileName = entry["profile_name"];
+ const TUNING_PROFILE::PROFILE_TYPE profileType = static_cast( entry["type"] );
+ const double targetImpedance = entry["target_impedance"];
+ const bool generateDrcRules = entry["generate_drc_rules"];
+ const bool enableTimeDomainTuning = entry["enable_time_domain_tuning"];
+ const int viaPropDelay = entry["via_prop_delay"];
+ std::vector trackEntries;
+ std::map trackEntriesMap;
- for( const nlohmann::json& layerEntry : entry["layer_delays"] )
+ for( const nlohmann::json& layerEntry : entry["layer_entries"] )
{
- if( !layerEntry.is_object() || !layerEntry.contains( "layer" ) )
+ if( !layerEntry.is_object() )
continue;
- wxString layerName = layerEntry["layer"];
- int layerId = LSET::NameToLayer( layerName );
- const int velocity = layerEntry["delay"];
- traceDelays[static_cast( layerId )] = velocity;
+ wxString signalLayer = layerEntry["signal_layer"];
+ wxString topRefLayer = layerEntry["top_reference_layer"];
+ wxString bottomRefLayer = layerEntry["bottom_reference_layer"];
+ int signalLayerId = LSET::NameToLayer( signalLayer );
+ int topRefLayerId = LSET::NameToLayer( topRefLayer );
+ int bottomRefLayerId = LSET::NameToLayer( bottomRefLayer );
+
+ DELAY_PROFILE_TRACK_PROPAGATION_ENTRY trackEntry;
+ trackEntry.m_signalLayer = static_cast( signalLayerId );
+ trackEntry.m_topReferenceLayer = static_cast( topRefLayerId );
+ trackEntry.m_bottomReferenceLayer = static_cast( bottomRefLayerId );
+ trackEntry.m_width = layerEntry["width"];
+ trackEntry.m_diffPairGap = layerEntry["diff_pair_gap"];
+ trackEntry.m_delay = layerEntry["delay"];
+ trackEntry.m_enableTimeDomainTuning = enableTimeDomainTuning;
+
+ trackEntries.push_back( trackEntry );
+ trackEntriesMap[static_cast( signalLayerId )] = trackEntry;
}
std::vector viaOverrides;
@@ -123,18 +151,26 @@ TIME_DOMAIN_PARAMETERS::TIME_DOMAIN_PARAMETERS( JSON_SETTINGS* aParent, const st
viaOverrides.push_back( readViaOverrideConfigurationLine( viaEntry ) );
}
- DELAY_PROFILE item{ profileName, viaPropDelay, std::move( traceDelays ), std::move( viaOverrides ) };
+ TUNING_PROFILE item{ profileName,
+ profileType,
+ targetImpedance,
+ generateDrcRules,
+ enableTimeDomainTuning,
+ std::move( trackEntries ),
+ viaPropDelay,
+ std::move( viaOverrides ),
+ std::move( trackEntriesMap ) };
return item;
};
m_params.emplace_back( new PARAM_LAMBDA(
- "delay_profiles_user_defined",
+ "tuning_profiles_impedance_geometric",
[&]() -> nlohmann::json
{
nlohmann::json ret = nlohmann::json::array();
- for( const auto& entry : m_delayProfiles )
+ for( const auto& entry : m_tuningProfiles )
saveUserDefinedProfileConfigurationLine( ret, entry );
return ret;
@@ -144,21 +180,21 @@ TIME_DOMAIN_PARAMETERS::TIME_DOMAIN_PARAMETERS( JSON_SETTINGS* aParent, const st
if( !aJson.is_array() )
return;
- ClearDelayProfiles();
+ ClearTuningProfiles();
for( const nlohmann::json& entry : aJson )
{
if( !entry.is_object() || !entry.contains( "profile_name" ) )
continue;
- m_delayProfiles.emplace_back( readUserDefinedProfileConfigurationLine( entry ) );
+ m_tuningProfiles.emplace_back( readUserDefinedProfileConfigurationLine( entry ) );
}
},
{} ) );
}
-TIME_DOMAIN_PARAMETERS::~TIME_DOMAIN_PARAMETERS()
+TUNING_PROFILES::~TUNING_PROFILES()
{
// Release early before destroying members
if( m_parent )
@@ -169,28 +205,22 @@ TIME_DOMAIN_PARAMETERS::~TIME_DOMAIN_PARAMETERS()
}
-bool TIME_DOMAIN_PARAMETERS::operator==( const TIME_DOMAIN_PARAMETERS& aOther ) const
+TUNING_PROFILE& TUNING_PROFILES::GetTuningProfile( wxString aProfileName )
{
- /*
- if( !std::equal( std::begin( m_netClasses ), std::end( m_netClasses ),
- std::begin( aOther.m_netClasses ) ) )
- return false;
+ auto itr = std::find_if( m_tuningProfiles.begin(), m_tuningProfiles.end(),
+ [&aProfileName]( const TUNING_PROFILE& aProfile )
+ {
+ return aProfile.m_ProfileName == aProfileName;
+ } );
- if( !std::equal( std::begin( m_netClassPatternAssignments ),
- std::end( m_netClassPatternAssignments ),
- std::begin( aOther.m_netClassPatternAssignments ) ) )
- return false;
+ if( itr == m_tuningProfiles.end() )
+ return m_nullDelayProfile;
- if( !std::equal( std::begin( m_netClassLabelAssignments ),
- std::end( m_netClassLabelAssignments ),
- std::begin( aOther.m_netClassLabelAssignments ) ) )
- return false;
-
-
- if( !std::equal( std::begin( m_netColorAssignments ), std::end( m_netColorAssignments ),
- std::begin( aOther.m_netColorAssignments ) ) )
- return false;
- */
-
- return true;
+ return *itr;
+}
+
+
+bool TUNING_PROFILES::operator==( const TUNING_PROFILES& aOther ) const
+{
+ return m_tuningProfiles == aOther.m_tuningProfiles;
}
diff --git a/common/transline_calculations/coupled_microstrip.cpp b/common/transline_calculations/coupled_microstrip.cpp
index 66f86685d5..90b48877e7 100644
--- a/common/transline_calculations/coupled_microstrip.cpp
+++ b/common/transline_calculations/coupled_microstrip.cpp
@@ -60,10 +60,10 @@ void COUPLED_MICROSTRIP::Analyse()
bool COUPLED_MICROSTRIP::Synthesize( const SYNTHESIZE_OPTS aOpts )
{
if( aOpts == SYNTHESIZE_OPTS::FIX_WIDTH )
- return MinimiseZ0Error1D( TCP::PHYS_S, TCP::Z0_O );
+ return MinimiseZ0Error1D( TCP::PHYS_S, TCP::Z0_O, false );
if( aOpts == SYNTHESIZE_OPTS::FIX_SPACING )
- return MinimiseZ0Error1D( TCP::PHYS_WIDTH, TCP::Z0_O );
+ return MinimiseZ0Error1D( TCP::PHYS_WIDTH, TCP::Z0_O, false );
double Z0_e, Z0_o, ang_l_dest;
double f1, f2, ft1, ft2, j11, j12, j21, j22, d_s_h, d_w_h, err;
@@ -173,16 +173,16 @@ void COUPLED_MICROSTRIP::SetAnalysisResults()
void COUPLED_MICROSTRIP::SetSynthesisResults()
{
- SetAnalysisResult( TCP::EPSILON_EFF_EVEN, er_eff_e );
- SetAnalysisResult( TCP::EPSILON_EFF_ODD, er_eff_o );
- SetAnalysisResult( TCP::UNIT_PROP_DELAY_EVEN, prop_delay_e );
- SetAnalysisResult( TCP::UNIT_PROP_DELAY_ODD, prop_delay_o );
- SetAnalysisResult( TCP::ATTEN_COND_EVEN, atten_cond_e );
- SetAnalysisResult( TCP::ATTEN_COND_ODD, atten_cond_o );
- SetAnalysisResult( TCP::ATTEN_DILECTRIC_EVEN, atten_dielectric_e );
- SetAnalysisResult( TCP::ATTEN_DILECTRIC_ODD, atten_dielectric_o );
- SetAnalysisResult( TCP::SKIN_DEPTH, GetParameter( TCP::SKIN_DEPTH ) );
- SetAnalysisResult( TCP::Z_DIFF, Zdiff );
+ SetSynthesisResult( TCP::EPSILON_EFF_EVEN, er_eff_e );
+ SetSynthesisResult( TCP::EPSILON_EFF_ODD, er_eff_o );
+ SetSynthesisResult( TCP::UNIT_PROP_DELAY_EVEN, prop_delay_e );
+ SetSynthesisResult( TCP::UNIT_PROP_DELAY_ODD, prop_delay_o );
+ SetSynthesisResult( TCP::ATTEN_COND_EVEN, atten_cond_e );
+ SetSynthesisResult( TCP::ATTEN_COND_ODD, atten_cond_o );
+ SetSynthesisResult( TCP::ATTEN_DILECTRIC_EVEN, atten_dielectric_e );
+ SetSynthesisResult( TCP::ATTEN_DILECTRIC_ODD, atten_dielectric_o );
+ SetSynthesisResult( TCP::SKIN_DEPTH, GetParameter( TCP::SKIN_DEPTH ) );
+ SetSynthesisResult( TCP::Z_DIFF, Zdiff );
const double Z0_E = GetParameter( TCP::Z0_E );
const double Z0_O = GetParameter( TCP::Z0_O );
@@ -198,12 +198,12 @@ void COUPLED_MICROSTRIP::SetSynthesisResults()
const bool L_invalid = !std::isfinite( L ) || L < 0;
const bool S_invalid = !std::isfinite( S ) || S <= 0;
- SetAnalysisResult( TCP::Z0_E, Z0_E, Z0_E_invalid ? TRANSLINE_STATUS::WARNING : TRANSLINE_STATUS::OK );
- SetAnalysisResult( TCP::Z0_O, Z0_O, Z0_O_invalid ? TRANSLINE_STATUS::WARNING : TRANSLINE_STATUS::OK );
- SetAnalysisResult( TCP::ANG_L, ANG_L, ANG_L_invalid ? TRANSLINE_STATUS::WARNING : TRANSLINE_STATUS::OK );
- SetAnalysisResult( TCP::PHYS_WIDTH, W, W_invalid ? TRANSLINE_STATUS::TS_ERROR : TRANSLINE_STATUS::OK );
- SetAnalysisResult( TCP::PHYS_LEN, L, L_invalid ? TRANSLINE_STATUS::TS_ERROR : TRANSLINE_STATUS::OK );
- SetAnalysisResult( TCP::PHYS_S, S, S_invalid ? TRANSLINE_STATUS::TS_ERROR : TRANSLINE_STATUS::OK );
+ SetSynthesisResult( TCP::Z0_E, Z0_E, Z0_E_invalid ? TRANSLINE_STATUS::WARNING : TRANSLINE_STATUS::OK );
+ SetSynthesisResult( TCP::Z0_O, Z0_O, Z0_O_invalid ? TRANSLINE_STATUS::WARNING : TRANSLINE_STATUS::OK );
+ SetSynthesisResult( TCP::ANG_L, ANG_L, ANG_L_invalid ? TRANSLINE_STATUS::WARNING : TRANSLINE_STATUS::OK );
+ SetSynthesisResult( TCP::PHYS_WIDTH, W, W_invalid ? TRANSLINE_STATUS::TS_ERROR : TRANSLINE_STATUS::OK );
+ SetSynthesisResult( TCP::PHYS_LEN, L, L_invalid ? TRANSLINE_STATUS::TS_ERROR : TRANSLINE_STATUS::OK );
+ SetSynthesisResult( TCP::PHYS_S, S, S_invalid ? TRANSLINE_STATUS::TS_ERROR : TRANSLINE_STATUS::OK );
}
diff --git a/common/transline_calculations/coupled_stripline.cpp b/common/transline_calculations/coupled_stripline.cpp
index a4626962ae..80f3916f0a 100644
--- a/common/transline_calculations/coupled_stripline.cpp
+++ b/common/transline_calculations/coupled_stripline.cpp
@@ -71,10 +71,10 @@ void COUPLED_STRIPLINE::Analyse()
bool COUPLED_STRIPLINE::Synthesize( const SYNTHESIZE_OPTS aOpts )
{
if( aOpts == SYNTHESIZE_OPTS::FIX_WIDTH )
- return MinimiseZ0Error1D( TCP::PHYS_S, TCP::Z0_O );
+ return MinimiseZ0Error1D( TCP::PHYS_S, TCP::Z0_O, false );
if( aOpts == SYNTHESIZE_OPTS::FIX_SPACING )
- return MinimiseZ0Error1D( TCP::PHYS_WIDTH, TCP::Z0_O );
+ return MinimiseZ0Error1D( TCP::PHYS_WIDTH, TCP::Z0_O, false );
// This synthesis approach is modified from wcalc, which is released under GPL version 2
// Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2006 Dan McMahill
diff --git a/common/transline_calculations/transline_calculation_base.cpp b/common/transline_calculations/transline_calculation_base.cpp
index 38f1538453..0084dfde4a 100644
--- a/common/transline_calculations/transline_calculation_base.cpp
+++ b/common/transline_calculations/transline_calculation_base.cpp
@@ -63,7 +63,7 @@ void TRANSLINE_CALCULATION_BASE::SetSynthesisResult( const TRANSLINE_PARAMETERS
bool TRANSLINE_CALCULATION_BASE::MinimiseZ0Error1D( const TRANSLINE_PARAMETERS aOptimise,
- const TRANSLINE_PARAMETERS aMeasure )
+ const TRANSLINE_PARAMETERS aMeasure, bool aRecalculateLength )
{
double& var = GetParameterRef( aOptimise );
double& Z0_param = GetParameterRef( aMeasure );
@@ -125,17 +125,20 @@ bool TRANSLINE_CALCULATION_BASE::MinimiseZ0Error1D( const TRANSLINE_PARAMETERS a
}
/* Compute one last time, but with correct length */
- Z0_param = Z0_dest;
- ANG_L_param = angl_l_dest;
- SetParameter( TCP::PHYS_LEN, TC::C0 / GetParameter( TCP::FREQUENCY ) / sqrt( GetParameter( TCP::EPSILON_EFF ) )
- * ANG_L_param / 2.0 / M_PI ); /* in m */
- Analyse();
+ if( aRecalculateLength )
+ {
+ Z0_param = Z0_dest;
+ ANG_L_param = angl_l_dest;
+ SetParameter( TCP::PHYS_LEN, TC::C0 / GetParameter( TCP::FREQUENCY ) / sqrt( GetParameter( TCP::EPSILON_EFF ) )
+ * ANG_L_param / 2.0 / M_PI ); /* in m */
+ Analyse();
- /* Restore parameters */
- Z0_param = Z0_dest;
- ANG_L_param = angl_l_dest;
- SetParameter( TCP::PHYS_LEN, TC::C0 / GetParameter( TCP::FREQUENCY ) / sqrt( GetParameter( TCP::EPSILON_EFF ) )
- * ANG_L_param / 2.0 / M_PI ); /* in m */
+ /* Restore parameters */
+ Z0_param = Z0_dest;
+ ANG_L_param = angl_l_dest;
+ SetParameter( TCP::PHYS_LEN, TC::C0 / GetParameter( TCP::FREQUENCY ) / sqrt( GetParameter( TCP::EPSILON_EFF ) )
+ * ANG_L_param / 2.0 / M_PI ); /* in m */
+ }
return error <= m_maxError;
}
diff --git a/common/transline_calculations/transline_calculation_base.h b/common/transline_calculations/transline_calculation_base.h
index e55c750a67..9e5449523e 100644
--- a/common/transline_calculations/transline_calculation_base.h
+++ b/common/transline_calculations/transline_calculation_base.h
@@ -165,9 +165,11 @@ protected:
*
* @param aOptimise Parameter to optimise
* @param aMeasure The parameter to measure / optimise against
+ * @param aRecalculateLength True if the angular length should be recalculated (not for differential pair usage)
* @returns true if error < MAX_ERROR, otherwise false
*/
- bool MinimiseZ0Error1D( TRANSLINE_PARAMETERS aOptimise, TRANSLINE_PARAMETERS aMeasure );
+ bool MinimiseZ0Error1D( TRANSLINE_PARAMETERS aOptimise, TRANSLINE_PARAMETERS aMeasure,
+ bool aRecalculateLength = false );
/**
* minimizeZ0Error2D
diff --git a/common/widgets/grid_text_button_helpers.cpp b/common/widgets/grid_text_button_helpers.cpp
index 159a390e73..237a287ee6 100644
--- a/common/widgets/grid_text_button_helpers.cpp
+++ b/common/widgets/grid_text_button_helpers.cpp
@@ -621,3 +621,58 @@ void GRID_CELL_PATH_EDITOR::Create( wxWindow* aParent, wxWindowID aId,
wxGridCellEditor::Create( aParent, aId, aEventHandler );
}
+
+class TEXT_BUTTON_RUN_FUNCTION final : public wxComboCtrl
+{
+public:
+ TEXT_BUTTON_RUN_FUNCTION( wxWindow* aParent, DIALOG_SHIM* aParentDlg, std::function& aFunction,
+ int& aRow, int& aCol ) :
+ wxComboCtrl( aParent, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( 0, 0 ),
+ wxTE_PROCESS_ENTER | wxBORDER_NONE ),
+ m_dlg( aParentDlg ),
+ m_function( aFunction ),
+ m_row( aRow ),
+ m_col( aCol )
+ {
+ SetButtonBitmaps( KiBitmapBundle( BITMAPS::small_refresh ) );
+
+ // win32 fix, avoids drawing the "native dropdown caret"
+ Customize( wxCC_IFLAG_HAS_NONSTANDARD_BUTTON );
+ }
+
+protected:
+ void DoSetPopupControl( wxComboPopup* popup ) override { m_popup = nullptr; }
+
+ void OnButtonClick() override { m_function( m_row, m_col ); }
+
+ DIALOG_SHIM* m_dlg;
+ std::function& m_function;
+ int& m_row;
+ int& m_col;
+};
+
+
+void GRID_CELL_RUN_FUNCTION_EDITOR::Create( wxWindow* aParent, wxWindowID aId, wxEvtHandler* aEventHandler )
+{
+ m_control = new TEXT_BUTTON_RUN_FUNCTION( aParent, m_dlg, m_function, m_row, m_col );
+ WX_GRID::CellEditorSetMargins( Combo() );
+
+#if wxUSE_VALIDATORS
+ // validate text in textctrl, if validator is set
+ if( m_validator )
+ {
+ Combo()->SetValidator( *m_validator );
+ }
+#endif
+
+ wxGridCellEditor::Create( aParent, aId, aEventHandler );
+}
+
+
+void GRID_CELL_RUN_FUNCTION_EDITOR::BeginEdit( int aRow, int aCol, wxGrid* aGrid )
+{
+ m_row = aRow;
+ m_col = aCol;
+
+ GRID_CELL_TEXT_BUTTON::BeginEdit( aRow, aCol, aGrid );
+}
diff --git a/common/widgets/wx_grid.cpp b/common/widgets/wx_grid.cpp
index a505911a51..eea3f18634 100644
--- a/common/widgets/wx_grid.cpp
+++ b/common/widgets/wx_grid.cpp
@@ -386,7 +386,8 @@ void WX_GRID::onCellEditorHidden( wxGridEvent& aEvent )
if( cellEditor )
{
- if( GRID_CELL_MARK_AS_NULLABLE* nullable = dynamic_cast( cellEditor ) )
+ if( const GRID_CELL_NULLABLE_INTERFACE* nullable =
+ dynamic_cast( cellEditor ) )
isNullable = nullable->IsNullable();
cellEditor->DecRef();
@@ -897,7 +898,14 @@ void WX_GRID::SetUnitValue( int aRow, int aCol, int aValue )
void WX_GRID::SetOptionalUnitValue( int aRow, int aCol, std::optional aValue )
{
- SetCellValue( aRow, aCol, getUnitsProvider( aCol )->StringFromOptionalValue( aValue, true ) );
+ EDA_DATA_TYPE cellDataType;
+
+ if( m_autoEvalColsUnits.contains( aCol ) )
+ cellDataType = m_autoEvalColsUnits[aCol].second;
+ else
+ cellDataType = EDA_DATA_TYPE::DISTANCE;
+
+ SetCellValue( aRow, aCol, getUnitsProvider( aCol )->StringFromOptionalValue( aValue, true, cellDataType ) );
}
diff --git a/include/netclass.h b/include/netclass.h
index 466a3f5350..0e167f03ce 100644
--- a/include/netclass.h
+++ b/include/netclass.h
@@ -241,11 +241,11 @@ public:
void SetPriority( int aPriority ) { m_Priority = aPriority; }
int GetPriority() const { return m_Priority; }
- bool HasDelayProfile() const { return !m_DelayProfile.empty(); }
- void SetDelayProfile( const wxString& aDelayProfile ) { m_DelayProfile = aDelayProfile; }
- wxString GetDelayProfile() const { return m_DelayProfile; }
- void SetDelayProfileParent( NETCLASS* aParent ) { m_delayProfileParent = aParent; }
- NETCLASS* GetDelayProfileParent() const { return m_delayProfileParent; }
+ bool HasTuningProfile() const { return !m_tuningProfile.empty(); }
+ void SetTuningProfile( const wxString& aTuningProfile ) { m_tuningProfile = aTuningProfile; }
+ wxString GetTuningProfile() const { return m_tuningProfile; }
+ void SetTuningProfileParent( NETCLASS* aParent ) { m_tuningProfileParent = aParent; }
+ NETCLASS* GetTuningProfileParent() const { return m_tuningProfileParent; }
protected:
bool m_isDefault; ///< Mark if this instance is the default netclass
@@ -276,7 +276,7 @@ protected:
COLOR4D m_pcbColor; ///< Optional PCB color override for this netclass
- wxString m_DelayProfile; ///< The tuning profile name being used by this netclass
+ wxString m_tuningProfile; ///< The tuning profile name being used by this netclass
// The NETCLASS providing each parameter
NETCLASS* m_clearanceParent;
@@ -293,7 +293,7 @@ protected:
NETCLASS* m_busWidthParent;
NETCLASS* m_schematicColorParent;
NETCLASS* m_lineStyleParent;
- NETCLASS* m_delayProfileParent;
+ NETCLASS* m_tuningProfileParent;
};
#endif // CLASS_NETCLASS_H
diff --git a/include/project/project_file.h b/include/project/project_file.h
index bb403dc4ca..a1022763c1 100644
--- a/include/project/project_file.h
+++ b/include/project/project_file.h
@@ -32,7 +32,7 @@ class BOARD_DESIGN_SETTINGS;
class ERC_SETTINGS;
class NET_SETTINGS;
class COMPONENT_CLASS_SETTINGS;
-class TIME_DOMAIN_PARAMETERS;
+class TUNING_PROFILES;
class LAYER_PAIR_SETTINGS;
class SCHEMATIC_SETTINGS;
class TEMPLATES;
@@ -144,10 +144,7 @@ public:
return m_ComponentClassSettings;
}
- std::shared_ptr& TimeDomainParameters()
- {
- return m_timeDomainParameters;
- }
+ std::shared_ptr& TuningProfileParameters() { return m_tuningProfileParameters; }
/**
* @return true if it should be safe to auto-save this file without user action
@@ -237,9 +234,9 @@ public:
std::shared_ptr m_ComponentClassSettings;
/**
- * Time domain parameters for this project
+ * Tuning profile parameters for this project
*/
- std::shared_ptr m_timeDomainParameters;
+ std::shared_ptr m_tuningProfileParameters;
std::vector m_LayerPresets; /// List of stored layer presets
std::vector m_Viewports; /// List of stored viewports (pos + zoom)
diff --git a/include/project/time_domain_parameters.h b/include/project/time_domain_parameters.h
deleted file mode 100644
index 9bb2db9e7f..0000000000
--- a/include/project/time_domain_parameters.h
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * This program source code file is part of KiCad, a free EDA CAD application.
- *
- * Copyright (C) 2020 CERN
- * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
- * @author Jon Evans
- *
- * This program is free software: you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation, either version 3 of the License, or (at your
- * option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program. If not, see .
- */
-
-#ifndef KICAD_TIME_DOMAIN_PARAMETERS_H
-#define KICAD_TIME_DOMAIN_PARAMETERS_H
-
-#include
-#include
-
-/**
- * Represents a single line in the time domain configuration via overrides configuration grid
- */
-struct DELAY_PROFILE_VIA_OVERRIDE_ENTRY
-{
- PCB_LAYER_ID m_SignalLayerFrom;
- PCB_LAYER_ID m_SignalLayerTo;
- PCB_LAYER_ID m_ViaLayerFrom;
- PCB_LAYER_ID m_ViaLayerTo;
- int m_Delay;
-
- bool operator<( const DELAY_PROFILE_VIA_OVERRIDE_ENTRY& other ) const
- {
- if( m_SignalLayerFrom != other.m_SignalLayerFrom )
- return IsCopperLayerLowerThan( m_SignalLayerFrom, other.m_SignalLayerFrom );
-
- if( m_SignalLayerTo != other.m_SignalLayerTo )
- return IsCopperLayerLowerThan( m_SignalLayerTo, other.m_SignalLayerTo );
-
- if( m_ViaLayerFrom != other.m_ViaLayerFrom )
- return IsCopperLayerLowerThan( m_ViaLayerFrom, other.m_ViaLayerFrom );
-
- if( m_ViaLayerTo != other.m_ViaLayerTo )
- return IsCopperLayerLowerThan( m_ViaLayerTo, other.m_ViaLayerTo );
-
- return m_Delay < other.m_Delay;
- }
-};
-
-
-/**
- * Represents a single line in the time domain configuration net class configuration grid
- */
-struct DELAY_PROFILE
-{
- wxString m_ProfileName;
- int m_ViaPropagationDelay;
- std::map m_LayerPropagationDelays;
- std::vector m_ViaOverrides;
-};
-
-
-/**
- * TIME_DOMAIN_PARAMETERS stores the configuration for time-domain tuning
- */
-class KICOMMON_API TIME_DOMAIN_PARAMETERS final : public NESTED_SETTINGS
-{
-public:
- TIME_DOMAIN_PARAMETERS( JSON_SETTINGS* aParent, const std::string& aPath );
-
- virtual ~TIME_DOMAIN_PARAMETERS();
-
- bool operator==( const TIME_DOMAIN_PARAMETERS& aOther ) const;
-
- bool operator!=( const TIME_DOMAIN_PARAMETERS& aOther ) const { return !operator==( aOther ); }
-
- void ClearDelayProfiles() { m_delayProfiles.clear(); }
-
- void AddDelayProfile( DELAY_PROFILE&& aTraceEntry ) { m_delayProfiles.emplace_back( std::move( aTraceEntry ) ); }
-
- const std::vector& GetDelayProfiles() const { return m_delayProfiles; }
-
-private:
- std::vector m_delayProfiles;
-};
-
-#endif // KICAD_NET_SETTINGS_H
diff --git a/include/project/tuning_profiles.h b/include/project/tuning_profiles.h
new file mode 100644
index 0000000000..31ced6a6f8
--- /dev/null
+++ b/include/project/tuning_profiles.h
@@ -0,0 +1,225 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2020 CERN
+ * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
+ * @author Jon Evans
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see .
+ */
+
+#ifndef KICAD_TUNING_PROFILES_H
+#define KICAD_TUNING_PROFILES_H
+
+#include
+#include
+
+/**
+ * Represents a single line in the time domain configuration via overrides configuration grid
+ */
+struct DELAY_PROFILE_VIA_OVERRIDE_ENTRY
+{
+ PCB_LAYER_ID m_SignalLayerFrom;
+ PCB_LAYER_ID m_SignalLayerTo;
+ PCB_LAYER_ID m_ViaLayerFrom;
+ PCB_LAYER_ID m_ViaLayerTo;
+ int m_Delay;
+
+ bool operator<( const DELAY_PROFILE_VIA_OVERRIDE_ENTRY& other ) const
+ {
+ if( m_SignalLayerFrom != other.m_SignalLayerFrom )
+ return IsCopperLayerLowerThan( m_SignalLayerFrom, other.m_SignalLayerFrom );
+
+ if( m_SignalLayerTo != other.m_SignalLayerTo )
+ return IsCopperLayerLowerThan( m_SignalLayerTo, other.m_SignalLayerTo );
+
+ if( m_ViaLayerFrom != other.m_ViaLayerFrom )
+ return IsCopperLayerLowerThan( m_ViaLayerFrom, other.m_ViaLayerFrom );
+
+ if( m_ViaLayerTo != other.m_ViaLayerTo )
+ return IsCopperLayerLowerThan( m_ViaLayerTo, other.m_ViaLayerTo );
+
+ return m_Delay < other.m_Delay;
+ }
+
+ bool operator==( const DELAY_PROFILE_VIA_OVERRIDE_ENTRY& other ) const
+ {
+ if( m_SignalLayerFrom != other.m_SignalLayerFrom )
+ return false;
+
+ if( m_SignalLayerTo != other.m_SignalLayerTo )
+ return false;
+
+ if( m_ViaLayerFrom != other.m_ViaLayerFrom )
+ return false;
+
+ if( m_ViaLayerTo != other.m_ViaLayerTo )
+ return false;
+
+ if( m_Delay != other.m_Delay )
+ return false;
+
+ return true;
+ }
+};
+
+class TUNING_PROFILES;
+
+/**
+* Represents a single line in a time domain profile track propagation setup
+*/
+class DELAY_PROFILE_TRACK_PROPAGATION_ENTRY
+{
+public:
+ friend class TUNING_PROFILES;
+
+ void SetSignalLayer( const PCB_LAYER_ID aLayer ) { m_signalLayer = aLayer; }
+ void SetTopReferenceLayer( const PCB_LAYER_ID aLayer ) { m_topReferenceLayer = aLayer; }
+ void SetBottomReferenceLayer( const PCB_LAYER_ID aLayer ) { m_bottomReferenceLayer = aLayer; }
+
+ void SetWidth( const int aWidth ) { m_width = aWidth; }
+ void SetDiffPairGap( const int aDiffPairGap ) { m_diffPairGap = aDiffPairGap; }
+ void SetDelay( const int aDelay ) { m_delay = aDelay; }
+ void SetEnableTimeDomainTuning( bool aEnable ) { m_enableTimeDomainTuning = aEnable; }
+
+ PCB_LAYER_ID GetSignalLayer() const { return m_signalLayer; }
+ PCB_LAYER_ID GetTopReferenceLayer() const { return m_topReferenceLayer; }
+ PCB_LAYER_ID GetBottomReferenceLayer() const { return m_bottomReferenceLayer; }
+
+ int GetWidth() const { return m_width; }
+ int GetDiffPairGap() const { return m_diffPairGap; }
+ int GetDelay() const { return m_enableTimeDomainTuning ? m_delay : 0; }
+
+ bool operator==( const DELAY_PROFILE_TRACK_PROPAGATION_ENTRY& other ) const
+ {
+ if( m_signalLayer != other.m_signalLayer )
+ return false;
+
+ if( m_topReferenceLayer != other.m_topReferenceLayer )
+ return false;
+
+ if( m_bottomReferenceLayer != other.m_bottomReferenceLayer )
+ return false;
+
+ if( m_width != other.m_width )
+ return false;
+
+ if( m_diffPairGap != other.m_diffPairGap )
+ return false;
+
+ if( m_delay != other.m_delay )
+ return false;
+
+ if( m_enableTimeDomainTuning != other.m_enableTimeDomainTuning )
+ return false;
+
+ return true;
+ }
+
+private:
+ PCB_LAYER_ID m_signalLayer{ UNDEFINED_LAYER };
+ PCB_LAYER_ID m_topReferenceLayer{ UNDEFINED_LAYER };
+ PCB_LAYER_ID m_bottomReferenceLayer{ UNDEFINED_LAYER };
+
+ int m_width{ 0 };
+ int m_diffPairGap{ 0 };
+ int m_delay{ 0 };
+
+ bool m_enableTimeDomainTuning{ false };
+};
+
+
+/**
+ * Represents a single line in the tuning profile configuration grid
+ */
+struct TUNING_PROFILE
+{
+ enum class PROFILE_TYPE
+ {
+ SINGLE,
+ DIFFERENTIAL
+ };
+
+ wxString m_ProfileName;
+ PROFILE_TYPE m_Type;
+ double m_TargetImpedance;
+ bool m_GenerateNetClassDRCRules;
+ bool m_EnableTimeDomainTuning;
+ std::vector m_TrackPropagationEntries;
+ int m_ViaPropagationDelay;
+ std::vector m_ViaOverrides;
+
+ // This is not persisted - but is used for quick lookup for track statistics calculations
+ std::map m_TrackPropagationEntriesMap;
+
+ bool operator==( const TUNING_PROFILE& aOther ) const
+ {
+ if( m_ProfileName != aOther.m_ProfileName )
+ return false;
+
+ if( m_Type != aOther.m_Type )
+ return false;
+
+ if( m_TargetImpedance != aOther.m_TargetImpedance )
+ return false;
+
+ if( m_GenerateNetClassDRCRules != aOther.m_GenerateNetClassDRCRules )
+ return false;
+
+ if( m_EnableTimeDomainTuning != aOther.m_EnableTimeDomainTuning )
+ return false;
+
+ if( m_TrackPropagationEntries != aOther.m_TrackPropagationEntries )
+ return false;
+
+ if( m_ViaPropagationDelay != aOther.m_ViaPropagationDelay )
+ return false;
+
+ if( m_ViaOverrides != aOther.m_ViaOverrides )
+ return false;
+
+ return true;
+ }
+};
+
+
+/**
+ * TUNING_PROFILES stores the configuration for impedance / delay tuning profiles
+ */
+class KICOMMON_API TUNING_PROFILES final : public NESTED_SETTINGS
+{
+public:
+ TUNING_PROFILES( JSON_SETTINGS* aParent, const std::string& aPath );
+
+ virtual ~TUNING_PROFILES();
+
+ bool operator==( const TUNING_PROFILES& aOther ) const;
+
+ bool operator!=( const TUNING_PROFILES& aOther ) const { return !operator==( aOther ); }
+
+ void ClearTuningProfiles() { m_tuningProfiles.clear(); }
+
+ void AddTuningProfile( TUNING_PROFILE&& aTraceEntry ) { m_tuningProfiles.emplace_back( std::move( aTraceEntry ) ); }
+
+ const std::vector& GetTuningProfiles() const { return m_tuningProfiles; }
+
+ TUNING_PROFILE& GetTuningProfile( wxString aProfileName );
+
+private:
+ std::vector m_tuningProfiles;
+
+ TUNING_PROFILE m_nullDelayProfile;
+};
+
+#endif // KICAD_TUNING_PROFILES_H
diff --git a/include/widgets/grid_icon_text_helpers.h b/include/widgets/grid_icon_text_helpers.h
index cabd082b4a..5459158a1b 100644
--- a/include/widgets/grid_icon_text_helpers.h
+++ b/include/widgets/grid_icon_text_helpers.h
@@ -140,26 +140,45 @@ protected:
};
+class GRID_CELL_NULLABLE_INTERFACE
+{
+public:
+ GRID_CELL_NULLABLE_INTERFACE() :
+ m_isNullable( true )
+ {
+ }
+ GRID_CELL_NULLABLE_INTERFACE( bool aIsNullable ) :
+ m_isNullable( aIsNullable )
+ {
+ }
+ virtual ~GRID_CELL_NULLABLE_INTERFACE() = default;
+
+ virtual bool IsNullable() const { return m_isNullable; }
+
+protected:
+ bool m_isNullable{ false };
+};
+
+
//---- Grid helpers: custom wxGridCellTextEditor ------------------------------------------
//
// Note: This is used to mark WX_GRID cell as nullable
-class GRID_CELL_MARK_AS_NULLABLE : public wxGridCellTextEditor
+class GRID_CELL_MARK_AS_NULLABLE : public wxGridCellTextEditor, public GRID_CELL_NULLABLE_INTERFACE
{
public:
- GRID_CELL_MARK_AS_NULLABLE() : m_isNullable( true ) {}
- GRID_CELL_MARK_AS_NULLABLE( bool aIsNullable ) : m_isNullable( aIsNullable ) {}
-
- wxGridCellEditor* Clone() const override
+ GRID_CELL_MARK_AS_NULLABLE() :
+ GRID_CELL_NULLABLE_INTERFACE( true )
{
- return new GRID_CELL_MARK_AS_NULLABLE( m_isNullable );
}
+ GRID_CELL_MARK_AS_NULLABLE( const bool aIsNullable ) :
+ GRID_CELL_NULLABLE_INTERFACE( aIsNullable )
+ {
+ }
+
+ wxGridCellEditor* Clone() const override { return new GRID_CELL_MARK_AS_NULLABLE( IsNullable() ); }
void Reset() override {}
- bool IsNullable() { return m_isNullable; }
-
-protected:
- bool m_isNullable;
wxDECLARE_NO_COPY_CLASS( GRID_CELL_MARK_AS_NULLABLE );
};
diff --git a/include/widgets/grid_text_button_helpers.h b/include/widgets/grid_text_button_helpers.h
index 7a1c4259fd..4117cc71e9 100644
--- a/include/widgets/grid_text_button_helpers.h
+++ b/include/widgets/grid_text_button_helpers.h
@@ -25,6 +25,8 @@
#ifndef GRID_TEXT_BUTTON_HELPERS_H
#define GRID_TEXT_BUTTON_HELPERS_H
+#include
+
#include
#include
@@ -222,4 +224,39 @@ protected:
};
+/**
+* A cell editor which runs a provided function when the grid cell button is clicked.
+*
+* The function has the signature (int, int) -> void. The passed parameters are the (row, col) of the
+* clicked grid cell
+*/
+class GRID_CELL_RUN_FUNCTION_EDITOR : public GRID_CELL_TEXT_BUTTON, public GRID_CELL_NULLABLE_INTERFACE
+{
+public:
+ GRID_CELL_RUN_FUNCTION_EDITOR( DIALOG_SHIM* aParent, const std::function aFunction,
+ const bool aIsNullable = false ) :
+ GRID_CELL_NULLABLE_INTERFACE( aIsNullable ),
+ m_dlg( aParent ),
+ m_row( -1 ),
+ m_col( -1 ),
+ m_function( aFunction )
+ {
+ }
+
+ wxGridCellEditor* Clone() const override
+ {
+ return new GRID_CELL_RUN_FUNCTION_EDITOR( m_dlg, m_function, IsNullable() );
+ }
+
+ void Create( wxWindow* aParent, wxWindowID aId, wxEvtHandler* aEventHandler ) override;
+ void BeginEdit( int aRow, int aCol, wxGrid* aGrid ) override;
+
+
+protected:
+ DIALOG_SHIM* m_dlg;
+ int m_row;
+ int m_col;
+ std::function m_function;
+};
+
#endif // GRID_TEXT_BUTTON_HELPERS_H
diff --git a/pcbnew/CMakeLists.txt b/pcbnew/CMakeLists.txt
index 3c95dd28e6..26d408088a 100644
--- a/pcbnew/CMakeLists.txt
+++ b/pcbnew/CMakeLists.txt
@@ -206,8 +206,10 @@ set( PCBNEW_DIALOGS
dialogs/panel_setup_tracks_and_vias_base.cpp
dialogs/panel_setup_tuning_patterns.cpp
dialogs/panel_setup_tuning_patterns_base.cpp
- dialogs/panel_setup_time_domain_parameters.cpp
- dialogs/panel_setup_time_domain_parameters_base.cpp
+ dialogs/panel_setup_tuning_profiles_base.cpp
+ dialogs/panel_setup_tuning_profiles.cpp
+ dialogs/panel_setup_tuning_profile_info_base.cpp
+ dialogs/panel_setup_tuning_profile_info.cpp
footprint_wizard.cpp
footprint_wizard_frame.cpp
footprint_wizard_frame_functions.cpp
diff --git a/pcbnew/board.cpp b/pcbnew/board.cpp
index 10e3890a8d..bf957cf58f 100644
--- a/pcbnew/board.cpp
+++ b/pcbnew/board.cpp
@@ -2408,9 +2408,9 @@ void BOARD::SynchronizeProperties()
}
-void BOARD::SynchronizeTimeDomainProperties()
+void BOARD::SynchronizeTuningProfileProperties()
{
- m_lengthDelayCalc->SynchronizeTimeDomainProperties();
+ m_lengthDelayCalc->SynchronizeTuningProfileProperties();
}
diff --git a/pcbnew/board.h b/pcbnew/board.h
index 0ffe8455f6..4e06e3c44b 100644
--- a/pcbnew/board.h
+++ b/pcbnew/board.h
@@ -1084,7 +1084,7 @@ public:
/**
* Ensure that all time domain properties providers are in sync with current settings
*/
- void SynchronizeTimeDomainProperties();
+ void SynchronizeTuningProfileProperties();
/**
* Return the Similarity. Because we compare board to board, we just return 1.0 here
diff --git a/pcbnew/board_design_settings.cpp b/pcbnew/board_design_settings.cpp
index 3c3e3d2495..e0818f482b 100644
--- a/pcbnew/board_design_settings.cpp
+++ b/pcbnew/board_design_settings.cpp
@@ -204,6 +204,8 @@ BOARD_DESIGN_SETTINGS::BOARD_DESIGN_SETTINGS( JSON_SETTINGS* aParent, const std:
m_DRCSeverities[DRCE_MIRRORED_TEXT_ON_FRONT_LAYER] = RPT_SEVERITY_WARNING;
m_DRCSeverities[DRCE_NONMIRRORED_TEXT_ON_BACK_LAYER] = RPT_SEVERITY_WARNING;
+ m_DRCSeverities[DRCE_MISSING_TUNING_PROFILE] = RPT_SEVERITY_WARNING;
+
m_MaxError = ARC_HIGH_DEF;
m_ZoneKeepExternalFillets = false;
m_UseHeightForLengthCalcs = true;
diff --git a/pcbnew/dialogs/dialog_board_setup.cpp b/pcbnew/dialogs/dialog_board_setup.cpp
index e640b9ac3f..dfd72cd6c4 100644
--- a/pcbnew/dialogs/dialog_board_setup.cpp
+++ b/pcbnew/dialogs/dialog_board_setup.cpp
@@ -38,7 +38,7 @@
#include
#include
#include
-#include
+#include
#include
#include
#include
@@ -50,6 +50,7 @@
#include "dialog_board_setup.h"
#include
+#include
#include
@@ -62,7 +63,7 @@ DIALOG_BOARD_SETUP::DIALOG_BOARD_SETUP( PCB_EDIT_FRAME* aFrame, wxWindow* aParen
m_layers( nullptr ),
m_boardFinish( nullptr ),
m_physicalStackup( nullptr ),
- m_timeDomainParameters( nullptr ),
+ m_tuningProfiles( nullptr ),
m_netClasses( nullptr ),
m_currentPage( 0 ),
m_layersPage( 0 ),
@@ -78,7 +79,7 @@ DIALOG_BOARD_SETUP::DIALOG_BOARD_SETUP( PCB_EDIT_FRAME* aFrame, wxWindow* aParen
m_netclassesPage( 0 ),
m_customRulesPage( 0 ),
m_severitiesPage( 0 ),
- m_timeDomainParametersPage( 0 )
+ m_tuningProfilesPage( 0 )
{
SetEvtHandlerEnabled( false );
@@ -181,6 +182,16 @@ DIALOG_BOARD_SETUP::DIALOG_BOARD_SETUP( PCB_EDIT_FRAME* aFrame, wxWindow* aParen
bds.m_SkewMeanderSettings );
}, _( "Length-tuning Patterns" ) );
+ m_tuningProfilesPage = m_treebook->GetPageCount();
+ m_treebook->AddLazySubPage(
+ [this]( wxWindow* aParent ) -> wxWindow*
+ {
+ BOARD* board = m_frame->GetBoard();
+ return new PANEL_SETUP_TUNING_PROFILES( aParent, m_frame, board,
+ m_frame->Prj().GetProjectFile().TuningProfileParameters() );
+ },
+ _( "Tuning Profiles" ) );
+
m_netclassesPage = m_treebook->GetPageCount();
m_treebook->AddLazySubPage(
[this]( wxWindow* aParent ) -> wxWindow*
@@ -203,56 +214,46 @@ DIALOG_BOARD_SETUP::DIALOG_BOARD_SETUP( PCB_EDIT_FRAME* aFrame, wxWindow* aParen
},
_( "Component Classes" ) );
- m_timeDomainParametersPage = m_treebook->GetPageCount();
- m_treebook->AddLazySubPage(
- [this]( wxWindow* aParent ) -> wxWindow*
- {
- BOARD* board = m_frame->GetBoard();
- return new PANEL_SETUP_TIME_DOMAIN_PARAMETERS(
- aParent, m_frame, board, m_frame->Prj().GetProjectFile().TimeDomainParameters() );
- },
- _( "Time Domain Parameters" ) );
+ m_customRulesPage = m_treebook->GetPageCount();
+ m_treebook->AddLazySubPage(
+ [this]( wxWindow* aParent ) -> wxWindow*
+ {
+ return new PANEL_SETUP_RULES( aParent, m_frame );
+ },
+ _( "Custom Rules" ) );
- m_customRulesPage = m_treebook->GetPageCount();
- m_treebook->AddLazySubPage(
- [this]( wxWindow* aParent ) -> wxWindow*
- {
- return new PANEL_SETUP_RULES( aParent, m_frame );
- },
- _( "Custom Rules" ) );
+ m_severitiesPage = m_treebook->GetPageCount();
+ m_treebook->AddLazySubPage(
+ [this]( wxWindow* aParent ) -> wxWindow*
+ {
+ BOARD* board = m_frame->GetBoard();
+ return new PANEL_SETUP_SEVERITIES( aParent, DRC_ITEM::GetItemsWithSeverities(),
+ board->GetDesignSettings().m_DRCSeverities );
+ },
+ _( "Violation Severity" ) );
- m_severitiesPage = m_treebook->GetPageCount();
- m_treebook->AddLazySubPage(
- [this]( wxWindow* aParent ) -> wxWindow*
- {
- BOARD* board = m_frame->GetBoard();
- return new PANEL_SETUP_SEVERITIES( aParent, DRC_ITEM::GetItemsWithSeverities(),
- board->GetDesignSettings().m_DRCSeverities );
- },
- _( "Violation Severity" ) );
+ m_treebook->AddPage( new wxPanel( GetTreebook() ), _( "Board Data" ) );
+ m_embeddedFilesPage = m_treebook->GetPageCount();
+ m_treebook->AddLazySubPage(
+ [this]( wxWindow* aParent ) -> wxWindow*
+ {
+ return new PANEL_EMBEDDED_FILES( aParent, m_frame->GetBoard(), NO_MARGINS );
+ },
+ _( "Embedded Files" ) );
- m_treebook->AddPage( new wxPanel( GetTreebook() ), _( "Board Data" ) );
- m_embeddedFilesPage = m_treebook->GetPageCount();
- m_treebook->AddLazySubPage(
- [this]( wxWindow* aParent ) -> wxWindow*
- {
- return new PANEL_EMBEDDED_FILES( aParent, m_frame->GetBoard(), NO_MARGINS );
- },
- _( "Embedded Files" ) );
+ for( size_t i = 0; i < m_treebook->GetPageCount(); ++i )
+ m_treebook->ExpandNode( i );
- for( size_t i = 0; i < m_treebook->GetPageCount(); ++i )
- m_treebook->ExpandNode( i );
+ SetEvtHandlerEnabled( true );
- SetEvtHandlerEnabled( true );
+ finishDialogSettings();
- finishDialogSettings();
-
- if( Prj().IsReadOnly() )
- {
- m_infoBar->ShowMessage( _( "Project is missing or read-only. Some settings will not "
- "be editable." ),
- wxICON_WARNING );
- }
+ if( Prj().IsReadOnly() )
+ {
+ m_infoBar->ShowMessage( _( "Project is missing or read-only. Some settings will not "
+ "be editable." ),
+ wxICON_WARNING );
+ }
wxBookCtrlEvent evt( wxEVT_TREEBOOK_PAGE_CHANGED, wxID_ANY, 0 );
@@ -273,12 +274,12 @@ void DIALOG_BOARD_SETUP::onPageChanged( wxBookCtrlEvent& aEvent )
if( m_physicalStackupPage > 0 ) // Don't run this during initialization
{
- if( m_currentPage == m_physicalStackupPage || m_currentPage == m_timeDomainParametersPage
- || page == m_physicalStackupPage || page == m_timeDomainParametersPage || page == m_netclassesPage )
+ if( m_currentPage == m_physicalStackupPage || page == m_physicalStackupPage || page == m_netclassesPage
+ || page == m_tuningProfilesPage )
{
m_layers = RESOLVE_PAGE( PANEL_SETUP_LAYERS, m_layersPage );
m_physicalStackup = RESOLVE_PAGE( PANEL_SETUP_BOARD_STACKUP, m_physicalStackupPage );
- m_timeDomainParameters = RESOLVE_PAGE( PANEL_SETUP_TIME_DOMAIN_PARAMETERS, m_timeDomainParametersPage );
+ m_tuningProfiles = RESOLVE_PAGE( PANEL_SETUP_TUNING_PROFILES, m_tuningProfilesPage );
m_netClasses = RESOLVE_PAGE( PANEL_SETUP_NETCLASSES, m_netclassesPage );
}
@@ -287,21 +288,21 @@ void DIALOG_BOARD_SETUP::onPageChanged( wxBookCtrlEvent& aEvent )
{
m_layers->SyncCopperLayers( m_physicalStackup->GetCopperLayerCount() );
- // Avoid calling SyncCopperLayers twice if moving from stackup to time domain directly
- m_timeDomainParameters->SyncCopperLayers( m_physicalStackup->GetCopperLayerCount() );
+ // Avoid calling SyncCopperLayers twice if moving from stackup to tuning profiles directly
+ m_tuningProfiles->SyncCopperLayers( m_physicalStackup->GetCopperLayerCount() );
}
if( page == m_physicalStackupPage )
{
m_physicalStackup->OnLayersOptionsChanged( m_layers->GetUILayerMask() );
}
- else if( page == m_netclassesPage || m_currentPage == m_timeDomainParametersPage )
+ else if( page == m_netclassesPage || m_currentPage == m_tuningProfilesPage )
{
- m_netClasses->UpdateDelayProfileNames( m_timeDomainParameters->GetDelayProfileNames() );
+ m_netClasses->UpdateDelayProfileNames( m_tuningProfiles->GetDelayProfileNames() );
}
- else if( page == m_timeDomainParametersPage )
+ else if( page == m_tuningProfilesPage )
{
- m_timeDomainParameters->SyncCopperLayers( m_physicalStackup->GetCopperLayerCount() );
+ m_tuningProfiles->SyncCopperLayers( m_physicalStackup->GetCopperLayerCount() );
}
if( Prj().IsReadOnly() )
@@ -475,13 +476,12 @@ void DIALOG_BOARD_SETUP::onAuxiliaryAction( wxCommandEvent& aEvent )
RESOLVE_PAGE( PANEL_SETUP_SEVERITIES,
m_severitiesPage )->ImportSettingsFrom( otherSettings.m_DRCSeverities );
}
-
- if( importDlg.m_TimeDomainParametersOpt->GetValue() )
+ if( importDlg.m_TuningProfilesOpt->GetValue() )
{
PROJECT_FILE& otherProjectFile = otherPrj->GetProjectFile();
- RESOLVE_PAGE( PANEL_SETUP_TIME_DOMAIN_PARAMETERS, m_timeDomainParametersPage )
- ->ImportSettingsFrom( otherProjectFile.TimeDomainParameters() );
+ RESOLVE_PAGE( PANEL_SETUP_TUNING_PROFILES, m_tuningProfilesPage )
+ ->ImportSettingsFrom( otherProjectFile.TuningProfileParameters() );
}
if( otherPrj != &m_frame->Prj() )
diff --git a/pcbnew/dialogs/dialog_board_setup.h b/pcbnew/dialogs/dialog_board_setup.h
index 52c8b1fc00..d70a9116fb 100644
--- a/pcbnew/dialogs/dialog_board_setup.h
+++ b/pcbnew/dialogs/dialog_board_setup.h
@@ -29,7 +29,6 @@ class PANEL_SETUP_CONSTRAINTS;
class PANEL_SETUP_LAYERS;
class PANEL_SETUP_TEXT_AND_GRAPHICS;
class PANEL_SETUP_NETCLASSES;
-class PANEL_SETUP_TIME_DOMAIN_PARAMETERS;
class PANEL_SETUP_RULES;
class PANEL_SETUP_TRACKS_AND_VIAS;
class PANEL_SETUP_MASK_AND_PASTE;
@@ -37,6 +36,7 @@ class PANEL_SETUP_BOARD_STACKUP;
class PANEL_SETUP_BOARD_FINISH;
class PANEL_SETUP_SEVERITIES;
class PANEL_TEXT_VARIABLES;
+class PANEL_SETUP_TUNING_PROFILES;
class DIALOG_BOARD_SETUP : public PAGED_DIALOG
@@ -54,7 +54,7 @@ protected:
PANEL_SETUP_LAYERS* m_layers;
PANEL_SETUP_BOARD_FINISH* m_boardFinish;
PANEL_SETUP_BOARD_STACKUP* m_physicalStackup;
- PANEL_SETUP_TIME_DOMAIN_PARAMETERS* m_timeDomainParameters;
+ PANEL_SETUP_TUNING_PROFILES* m_tuningProfiles;
PANEL_SETUP_NETCLASSES* m_netClasses;
private:
@@ -74,7 +74,7 @@ private:
size_t m_customRulesPage;
size_t m_severitiesPage;
size_t m_embeddedFilesPage;
- size_t m_timeDomainParametersPage;
+ size_t m_tuningProfilesPage;
};
diff --git a/pcbnew/dialogs/dialog_import_settings.cpp b/pcbnew/dialogs/dialog_import_settings.cpp
index e7e2a9ced6..f531c5e65c 100644
--- a/pcbnew/dialogs/dialog_import_settings.cpp
+++ b/pcbnew/dialogs/dialog_import_settings.cpp
@@ -83,8 +83,8 @@ bool DIALOG_IMPORT_SETTINGS::UpdateImportSettingsButton()
( m_LayersOpt->IsChecked() || m_MaskAndPasteOpt->IsChecked() || m_ConstraintsOpt->IsChecked()
|| m_NetclassesOpt->IsChecked() || m_SeveritiesOpt->IsChecked() || m_TextAndGraphicsOpt->IsChecked()
|| m_FormattingOpt->IsChecked() || m_TracksAndViasOpt->IsChecked() || m_TuningPatternsOpt->IsChecked()
- || m_CustomRulesOpt->IsChecked() || m_ComponentClassesOpt->IsChecked()
- || m_TimeDomainParametersOpt->IsChecked() || m_TeardropsOpt->IsChecked() );
+ || m_CustomRulesOpt->IsChecked() || m_ComponentClassesOpt->IsChecked() || m_TuningProfilesOpt->IsChecked()
+ || m_TeardropsOpt->IsChecked() );
m_sdbSizer1OK->Enable( buttonEnableState );
@@ -150,7 +150,7 @@ void DIALOG_IMPORT_SETTINGS::OnSelectAll( wxCommandEvent& event )
m_TeardropsOpt->SetValue( m_showSelectAllOnBtn );
m_TuningPatternsOpt->SetValue( m_showSelectAllOnBtn );
m_CustomRulesOpt->SetValue( m_showSelectAllOnBtn );
- m_TimeDomainParametersOpt->SetValue( m_showSelectAllOnBtn );
+ m_TuningProfilesOpt->SetValue( m_showSelectAllOnBtn );
m_ComponentClassesOpt->SetValue( m_showSelectAllOnBtn );
// Ensure "Import Settings" button state is enabled as appropriate
diff --git a/pcbnew/dialogs/dialog_import_settings_base.cpp b/pcbnew/dialogs/dialog_import_settings_base.cpp
index 747e7a1515..dfcf7d14c5 100644
--- a/pcbnew/dialogs/dialog_import_settings_base.cpp
+++ b/pcbnew/dialogs/dialog_import_settings_base.cpp
@@ -78,8 +78,8 @@ DIALOG_IMPORT_SETTINGS_BASE::DIALOG_IMPORT_SETTINGS_BASE( wxWindow* parent, wxWi
m_ComponentClassesOpt = new wxCheckBox( this, wxID_ANY, _("Component classes"), wxDefaultPosition, wxDefaultSize, 0 );
bLeftCol->Add( m_ComponentClassesOpt, 0, wxBOTTOM|wxLEFT|wxRIGHT, 5 );
- m_TimeDomainParametersOpt = new wxCheckBox( this, wxID_ANY, _("Time domain parameters"), wxDefaultPosition, wxDefaultSize, 0 );
- bLeftCol->Add( m_TimeDomainParametersOpt, 0, wxBOTTOM|wxLEFT|wxRIGHT, 5 );
+ m_TuningProfilesOpt = new wxCheckBox( this, wxID_ANY, _("Tuning Profiles"), wxDefaultPosition, wxDefaultSize, 0 );
+ bLeftCol->Add( m_TuningProfilesOpt, 0, wxBOTTOM|wxLEFT|wxRIGHT, 5 );
m_CustomRulesOpt = new wxCheckBox( this, wxID_ANY, _("Custom rules"), wxDefaultPosition, wxDefaultSize, 0 );
bLeftCol->Add( m_CustomRulesOpt, 0, wxBOTTOM|wxRIGHT|wxLEFT, 5 );
@@ -128,7 +128,7 @@ DIALOG_IMPORT_SETTINGS_BASE::DIALOG_IMPORT_SETTINGS_BASE( wxWindow* parent, wxWi
m_TuningPatternsOpt->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_IMPORT_SETTINGS_BASE::OnCheckboxClicked ), NULL, this );
m_NetclassesOpt->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_IMPORT_SETTINGS_BASE::OnCheckboxClicked ), NULL, this );
m_ComponentClassesOpt->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_IMPORT_SETTINGS_BASE::OnCheckboxClicked ), NULL, this );
- m_TimeDomainParametersOpt->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_IMPORT_SETTINGS_BASE::OnCheckboxClicked ), NULL, this );
+ m_TuningProfilesOpt->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_IMPORT_SETTINGS_BASE::OnCheckboxClicked ), NULL, this );
m_CustomRulesOpt->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_IMPORT_SETTINGS_BASE::OnCheckboxClicked ), NULL, this );
m_SeveritiesOpt->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_IMPORT_SETTINGS_BASE::OnCheckboxClicked ), NULL, this );
m_selectAllButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_IMPORT_SETTINGS_BASE::OnSelectAll ), NULL, this );
@@ -147,7 +147,7 @@ DIALOG_IMPORT_SETTINGS_BASE::~DIALOG_IMPORT_SETTINGS_BASE()
m_TuningPatternsOpt->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_IMPORT_SETTINGS_BASE::OnCheckboxClicked ), NULL, this );
m_NetclassesOpt->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_IMPORT_SETTINGS_BASE::OnCheckboxClicked ), NULL, this );
m_ComponentClassesOpt->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_IMPORT_SETTINGS_BASE::OnCheckboxClicked ), NULL, this );
- m_TimeDomainParametersOpt->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_IMPORT_SETTINGS_BASE::OnCheckboxClicked ), NULL, this );
+ m_TuningProfilesOpt->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_IMPORT_SETTINGS_BASE::OnCheckboxClicked ), NULL, this );
m_CustomRulesOpt->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_IMPORT_SETTINGS_BASE::OnCheckboxClicked ), NULL, this );
m_SeveritiesOpt->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_IMPORT_SETTINGS_BASE::OnCheckboxClicked ), NULL, this );
m_selectAllButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_IMPORT_SETTINGS_BASE::OnSelectAll ), NULL, this );
diff --git a/pcbnew/dialogs/dialog_import_settings_base.fbp b/pcbnew/dialogs/dialog_import_settings_base.fbp
index 04b97a37b4..b1d48d9848 100644
--- a/pcbnew/dialogs/dialog_import_settings_base.fbp
+++ b/pcbnew/dialogs/dialog_import_settings_base.fbp
@@ -1050,7 +1050,7 @@
0
0
wxID_ANY
- Time domain parameters
+ Tuning Profiles
0
@@ -1058,7 +1058,7 @@
0
1
- m_TimeDomainParametersOpt
+ m_TuningProfilesOpt
1
diff --git a/pcbnew/dialogs/dialog_import_settings_base.h b/pcbnew/dialogs/dialog_import_settings_base.h
index dcc6fa3ad3..9e70c5603d 100644
--- a/pcbnew/dialogs/dialog_import_settings_base.h
+++ b/pcbnew/dialogs/dialog_import_settings_base.h
@@ -65,7 +65,7 @@ class DIALOG_IMPORT_SETTINGS_BASE : public DIALOG_SHIM
wxCheckBox* m_TuningPatternsOpt;
wxCheckBox* m_NetclassesOpt;
wxCheckBox* m_ComponentClassesOpt;
- wxCheckBox* m_TimeDomainParametersOpt;
+ wxCheckBox* m_TuningProfilesOpt;
wxCheckBox* m_CustomRulesOpt;
wxCheckBox* m_SeveritiesOpt;
diff --git a/pcbnew/dialogs/panel_setup_time_domain_parameters.cpp b/pcbnew/dialogs/panel_setup_time_domain_parameters.cpp
deleted file mode 100644
index 739b192e20..0000000000
--- a/pcbnew/dialogs/panel_setup_time_domain_parameters.cpp
+++ /dev/null
@@ -1,661 +0,0 @@
-/*
- * This program source code file is part of KiCad, a free EDA CAD application.
- *
- * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, you may find one here:
- * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
- * or you may search the http://www.gnu.org website for the version 2 license,
- * or you may write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include
-#include
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-PANEL_SETUP_TIME_DOMAIN_PARAMETERS::PANEL_SETUP_TIME_DOMAIN_PARAMETERS(
- wxWindow* aParentWindow, PCB_EDIT_FRAME* aFrame, BOARD* aBoard,
- std::shared_ptr aTimeDomainParameters ) :
- PANEL_SETUP_TIME_DOMAIN_PARAMETERS_BASE( aParentWindow ),
- m_timeDomainParameters( std::move( aTimeDomainParameters ) ),
- m_frame( aFrame ),
- m_board( aFrame->GetBoard() )
-{
- m_timeDomainParametersPane->SetBorders( true, false, false, false );
- m_viaDelayOverridesPane->SetBorders( true, false, false, false );
-
- // Set up units
- m_unitsProvider = std::make_unique( pcbIUScale, m_frame->GetUserUnits() );
- m_tracePropagationGrid->SetUnitsProvider( m_unitsProvider.get() );
- m_viaPropagationGrid->SetUnitsProvider( m_unitsProvider.get() );
-
- Freeze();
-
- m_splitter->SetMinimumPaneSize( FromDIP( m_splitter->GetMinimumPaneSize() ) );
-
- // Set up the tuning profiles grid
- m_tracePropagationGrid->BeginBatch();
- m_tracePropagationGrid->SetUseNativeColLabels();
-
- m_tracePropagationGrid->EnsureColLabelsVisible();
- m_tracePropagationGrid->PushEventHandler( new GRID_TRICKS( m_tracePropagationGrid ) );
- m_tracePropagationGrid->SetSelectionMode( wxGrid::wxGridSelectRows );
-
- m_addDelayProfileButton->SetBitmap( KiBitmapBundle( BITMAPS::small_plus ) );
- m_removeDelayProfileButton->SetBitmap( KiBitmapBundle( BITMAPS::small_trash ) );
-
- m_tracePropagationGrid->EndBatch();
-
- m_tracePropagationGrid->Connect(
- wxEVT_GRID_CELL_CHANGING,
- wxGridEventHandler( PANEL_SETUP_TIME_DOMAIN_PARAMETERS::OnDelayProfileGridCellChanging ), nullptr, this );
-
- // Set up the via override grid
- m_viaPropagationGrid->BeginBatch();
- m_viaPropagationGrid->SetUseNativeColLabels();
-
- m_viaPropagationGrid->EnsureColLabelsVisible();
- m_viaPropagationGrid->PushEventHandler( new GRID_TRICKS( m_viaPropagationGrid ) );
- m_viaPropagationGrid->SetSelectionMode( wxGrid::wxGridSelectRows );
-
- std::vector viaColIds;
- m_viaPropagationGrid->SetAutoEvalColUnits( VIA_GRID_DELAY,
- m_unitsProvider->GetUnitsFromType( EDA_DATA_TYPE::TIME ) );
- viaColIds.push_back( VIA_GRID_DELAY );
- m_viaPropagationGrid->SetAutoEvalCols( viaColIds );
- m_viaPropagationGrid->EndBatch();
-
- m_addViaOverrideButton->SetBitmap( KiBitmapBundle( BITMAPS::small_plus ) );
- m_removeViaOverrideButton->SetBitmap( KiBitmapBundle( BITMAPS::small_trash ) );
-
- setColumnWidths();
-
- Thaw();
-}
-
-
-PANEL_SETUP_TIME_DOMAIN_PARAMETERS::~PANEL_SETUP_TIME_DOMAIN_PARAMETERS()
-{
- // Delete the GRID_TRICKS
- m_tracePropagationGrid->PopEventHandler( true );
- m_viaPropagationGrid->PopEventHandler( true );
-
- m_tracePropagationGrid->Disconnect(
- wxEVT_GRID_CELL_CHANGING,
- wxGridEventHandler( PANEL_SETUP_TIME_DOMAIN_PARAMETERS::OnDelayProfileGridCellChanging ), nullptr, this );
-}
-
-
-bool PANEL_SETUP_TIME_DOMAIN_PARAMETERS::TransferDataToWindow()
-{
- m_tracePropagationGrid->ClearRows();
- m_viaPropagationGrid->ClearRows();
-
- const std::vector& delayProfiles = m_timeDomainParameters->GetDelayProfiles();
-
- SyncCopperLayers( m_board->GetCopperLayerCount() );
-
- for( const DELAY_PROFILE& profile : delayProfiles )
- {
- addProfileRow( profile );
-
- for( const DELAY_PROFILE_VIA_OVERRIDE_ENTRY& viaOverride : profile.m_ViaOverrides )
- addViaRow( profile.m_ProfileName, viaOverride );
- }
-
- updateViaProfileNamesEditor();
-
- return true;
-}
-
-
-bool PANEL_SETUP_TIME_DOMAIN_PARAMETERS::TransferDataFromWindow()
-{
- if( !Validate() )
- return false;
-
- m_timeDomainParameters->ClearDelayProfiles();
-
- for( int i = 0; i < m_tracePropagationGrid->GetNumberRows(); ++i )
- {
- DELAY_PROFILE profile = getProfileRow( i );
- wxString profileName = profile.m_ProfileName;
-
- for( int j = 0; j < m_viaPropagationGrid->GetNumberRows(); ++j )
- {
- if( m_viaPropagationGrid->GetCellValue( j, VIA_GRID_PROFILE_NAME ) == profileName )
- profile.m_ViaOverrides.emplace_back( getViaRow( j ) );
- }
-
- m_timeDomainParameters->AddDelayProfile( std::move( profile ) );
- }
-
- return true;
-}
-
-
-void PANEL_SETUP_TIME_DOMAIN_PARAMETERS::addProfileRow( const DELAY_PROFILE& aDelayProfile )
-{
- const int rowId = m_tracePropagationGrid->GetNumberRows();
- m_tracePropagationGrid->AppendRows();
-
- m_tracePropagationGrid->SetCellValue( rowId, PROFILE_GRID_PROFILE_NAME, aDelayProfile.m_ProfileName );
- m_tracePropagationGrid->SetUnitValue( rowId, PROFILE_GRID_VIA_PROP_DELAY, aDelayProfile.m_ViaPropagationDelay );
-
- for( const auto& [layerId, velocity] : aDelayProfile.m_LayerPropagationDelays )
- {
- if( !m_copperLayerIdsToColumns.contains( layerId ) )
- continue;
-
- int col = m_copperLayerIdsToColumns[layerId];
-
- if( col < m_tracePropagationGrid->GetNumberCols() )
- m_tracePropagationGrid->SetUnitValue( rowId, col, velocity );
- }
-}
-
-
-DELAY_PROFILE PANEL_SETUP_TIME_DOMAIN_PARAMETERS::getProfileRow( const int aRow )
-{
- DELAY_PROFILE entry;
- entry.m_ProfileName = getProfileNameForProfileGridRow( aRow );
- entry.m_ViaPropagationDelay = m_tracePropagationGrid->GetUnitValue( aRow, PROFILE_GRID_VIA_PROP_DELAY );
-
- std::map propDelays;
-
- for( const auto& [layer, col] : m_copperLayerIdsToColumns )
- propDelays[layer] = m_tracePropagationGrid->GetUnitValue( aRow, col );
-
- entry.m_LayerPropagationDelays = std::move( propDelays );
-
- return entry;
-}
-
-
-void PANEL_SETUP_TIME_DOMAIN_PARAMETERS::addViaRow( const wxString& aProfileName,
- const DELAY_PROFILE_VIA_OVERRIDE_ENTRY& aViaOverrideEntry ) const
-{
- const int rowId = m_viaPropagationGrid->GetNumberRows();
- m_viaPropagationGrid->AppendRows();
- m_viaPropagationGrid->SetCellValue( rowId, VIA_GRID_PROFILE_NAME, aProfileName );
- m_viaPropagationGrid->SetCellValue( rowId, VIA_GRID_SIGNAL_LAYER_FROM,
- m_board->GetLayerName( aViaOverrideEntry.m_SignalLayerFrom ) );
- m_viaPropagationGrid->SetCellValue( rowId, VIA_GRID_SIGNAL_LAYER_TO,
- m_board->GetLayerName( aViaOverrideEntry.m_SignalLayerTo ) );
- m_viaPropagationGrid->SetCellValue( rowId, VIA_GRID_VIA_LAYER_FROM,
- m_board->GetLayerName( aViaOverrideEntry.m_ViaLayerFrom ) );
- m_viaPropagationGrid->SetCellValue( rowId, VIA_GRID_VIA_LAYER_TO,
- m_board->GetLayerName( aViaOverrideEntry.m_ViaLayerTo ) );
- m_viaPropagationGrid->SetUnitValue( rowId, VIA_GRID_DELAY, aViaOverrideEntry.m_Delay );
-}
-
-
-DELAY_PROFILE_VIA_OVERRIDE_ENTRY PANEL_SETUP_TIME_DOMAIN_PARAMETERS::getViaRow( const int aRow )
-{
- // Get layer info
- const wxString signalLayerFrom = m_viaPropagationGrid->GetCellValue( aRow, VIA_GRID_SIGNAL_LAYER_FROM );
- const wxString signalLayerTo = m_viaPropagationGrid->GetCellValue( aRow, VIA_GRID_SIGNAL_LAYER_TO );
- const wxString viaLayerFrom = m_viaPropagationGrid->GetCellValue( aRow, VIA_GRID_VIA_LAYER_FROM );
- const wxString viaLayerTo = m_viaPropagationGrid->GetCellValue( aRow, VIA_GRID_VIA_LAYER_TO );
- PCB_LAYER_ID signalLayerIdFrom = m_layerNamesToIDs[signalLayerFrom];
- PCB_LAYER_ID signalLayerIdTo = m_layerNamesToIDs[signalLayerTo];
- PCB_LAYER_ID viaLayerIdFrom = m_layerNamesToIDs[viaLayerFrom];
- PCB_LAYER_ID viaLayerIdTo = m_layerNamesToIDs[viaLayerTo];
-
- // Order layers in stackup order (from F_Cu first)
- if( IsCopperLayerLowerThan( signalLayerIdFrom, signalLayerIdTo ) )
- std::swap( signalLayerIdFrom, signalLayerIdTo );
-
- if( IsCopperLayerLowerThan( viaLayerIdFrom, viaLayerIdTo ) )
- std::swap( viaLayerIdFrom, viaLayerIdTo );
-
- const DELAY_PROFILE_VIA_OVERRIDE_ENTRY entry{ signalLayerIdFrom, signalLayerIdTo, viaLayerIdFrom, viaLayerIdTo,
- m_viaPropagationGrid->GetUnitValue( aRow, VIA_GRID_DELAY ) };
-
- return entry;
-}
-
-
-void PANEL_SETUP_TIME_DOMAIN_PARAMETERS::SyncCopperLayers( int aNumCopperLayers )
-{
- m_prevLayerNamesToIDs = m_layerNamesToIDs;
- m_copperLayerIdsToColumns.clear();
- m_copperColumnsToLayerId.clear();
- m_layerNames.clear();
- m_layerNamesToIDs.clear();
-
- int colIdx = PROFILE_GRID_NUM_REQUIRED_COLS;
-
- for( const auto& layer : LSET::AllCuMask( aNumCopperLayers ).CuStack() )
- {
- wxString layerName = m_board->GetLayerName( layer );
- m_layerNames.emplace_back( layerName );
- m_layerNamesToIDs[layerName] = layer;
- m_copperLayerIdsToColumns[layer] = colIdx;
- m_copperColumnsToLayerId[colIdx] = layer;
- ++colIdx;
- }
-
- updateProfileGridColumns();
- updateViaGridColumns();
- setColumnWidths();
-}
-
-
-void PANEL_SETUP_TIME_DOMAIN_PARAMETERS::setColumnWidths()
-{
- const int minValueWidth = m_tracePropagationGrid->GetTextExtent( wxT( "000.00 ps/mm" ) ).x;
- const int minNameWidth = m_tracePropagationGrid->GetTextExtent( wxT( "MMMMMMMMMMMM" ) ).x;
-
- for( int i = 0; i < m_tracePropagationGrid->GetNumberCols(); ++i )
- {
- const int titleSize = m_tracePropagationGrid->GetTextExtent( m_tracePropagationGrid->GetColLabelValue( i ) ).x;
-
- if( i == PROFILE_GRID_PROFILE_NAME )
- m_tracePropagationGrid->SetColSize( i, std::max( titleSize, minNameWidth ) );
- else
- m_tracePropagationGrid->SetColSize( i, std::max( titleSize, minValueWidth ) );
- }
-
- for( int i = 0; i < m_viaPropagationGrid->GetNumberCols(); ++i )
- {
- const int titleSize = GetTextExtent( m_viaPropagationGrid->GetColLabelValue( i ) ).x;
- if( i == VIA_GRID_PROFILE_NAME )
- m_viaPropagationGrid->SetColSize( i, std::max( titleSize, minNameWidth ) );
- else
- m_viaPropagationGrid->SetColSize( i, titleSize + 30 );
- }
-}
-
-
-void PANEL_SETUP_TIME_DOMAIN_PARAMETERS::updateProfileGridColumns()
-{
- const int newCopperLayers = static_cast( m_copperLayerIdsToColumns.size() );
- const int curCopperLayers = m_tracePropagationGrid->GetNumberCols() - PROFILE_GRID_NUM_REQUIRED_COLS;
-
- if( newCopperLayers < curCopperLayers )
- {
- // TODO: WARN OF DELETING DATA?
- m_tracePropagationGrid->DeleteCols( curCopperLayers - newCopperLayers + PROFILE_GRID_NUM_REQUIRED_COLS,
- curCopperLayers - newCopperLayers );
- }
- else if( newCopperLayers > curCopperLayers )
- {
- m_tracePropagationGrid->AppendCols( newCopperLayers - curCopperLayers );
- }
-
- std::vector copperColIds;
-
- m_tracePropagationGrid->SetAutoEvalColUnits( PROFILE_GRID_VIA_PROP_DELAY,
- m_unitsProvider->GetUnitsFromType( EDA_DATA_TYPE::LENGTH_DELAY ) );
- copperColIds.push_back( PROFILE_GRID_VIA_PROP_DELAY );
-
- for( const auto& [colIdx, layerId] : m_copperColumnsToLayerId )
- {
- m_tracePropagationGrid->SetColLabelValue( colIdx, m_board->GetLayerName( layerId ) );
- m_tracePropagationGrid->SetAutoEvalColUnits( colIdx,
- m_unitsProvider->GetUnitsFromType( EDA_DATA_TYPE::LENGTH_DELAY ) );
- copperColIds.push_back( colIdx );
- }
-
- m_tracePropagationGrid->SetAutoEvalCols( copperColIds );
-
- m_tracePropagationGrid->EnsureColLabelsVisible();
- m_tracePropagationGrid->Refresh();
-}
-
-
-void PANEL_SETUP_TIME_DOMAIN_PARAMETERS::updateViaGridColumns()
-{
- wxArrayString layerNames;
- std::ranges::for_each( m_layerNames,
- [&layerNames]( const wxString& aLayerName )
- {
- layerNames.push_back( aLayerName );
- } );
-
- // Save the current data
- std::vector currentSignalLayersFrom;
- std::vector currentSignalLayersTo;
- std::vector currentViaLayersFrom;
- std::vector currentViaLayersTo;
-
- for( int row = 0; row < m_viaPropagationGrid->GetNumberRows(); ++row )
- {
- currentSignalLayersFrom.emplace_back( m_viaPropagationGrid->GetCellValue( row, VIA_GRID_SIGNAL_LAYER_FROM ) );
- currentSignalLayersTo.emplace_back( m_viaPropagationGrid->GetCellValue( row, VIA_GRID_SIGNAL_LAYER_TO ) );
- currentViaLayersFrom.emplace_back( m_viaPropagationGrid->GetCellValue( row, VIA_GRID_VIA_LAYER_FROM ) );
- currentViaLayersTo.emplace_back( m_viaPropagationGrid->GetCellValue( row, VIA_GRID_VIA_LAYER_TO ) );
- }
-
- // Reset the via layers lists
- wxGridCellAttr* attr = new wxGridCellAttr;
- attr->SetEditor( new wxGridCellChoiceEditor( layerNames, false ) );
- m_viaPropagationGrid->SetColAttr( VIA_GRID_SIGNAL_LAYER_FROM, attr );
-
- attr = new wxGridCellAttr;
- attr->SetEditor( new wxGridCellChoiceEditor( layerNames, false ) );
- m_viaPropagationGrid->SetColAttr( VIA_GRID_SIGNAL_LAYER_TO, attr );
-
- attr = new wxGridCellAttr;
- attr->SetEditor( new wxGridCellChoiceEditor( layerNames, false ) );
- m_viaPropagationGrid->SetColAttr( VIA_GRID_VIA_LAYER_FROM, attr );
-
- attr = new wxGridCellAttr;
- attr->SetEditor( new wxGridCellChoiceEditor( layerNames, false ) );
- m_viaPropagationGrid->SetColAttr( VIA_GRID_VIA_LAYER_TO, attr );
-
- // Restore the data, changing or resetting layer names if required
- for( int row = 0; row < m_viaPropagationGrid->GetNumberRows(); ++row )
- {
- const PCB_LAYER_ID lastSignalFromId = m_prevLayerNamesToIDs[currentSignalLayersFrom[row]];
-
- if( m_copperLayerIdsToColumns.contains( lastSignalFromId ) )
- m_viaPropagationGrid->SetCellValue( row, VIA_GRID_SIGNAL_LAYER_FROM,
- m_board->GetLayerName( lastSignalFromId ) );
- else
- m_viaPropagationGrid->SetCellValue( row, VIA_GRID_SIGNAL_LAYER_FROM, m_layerNames.front() );
-
- const PCB_LAYER_ID lastSignalToId = m_prevLayerNamesToIDs[currentSignalLayersTo[row]];
-
- if( m_copperLayerIdsToColumns.contains( lastSignalToId ) )
- m_viaPropagationGrid->SetCellValue( row, VIA_GRID_SIGNAL_LAYER_TO,
- m_board->GetLayerName( lastSignalToId ) );
- else
- m_viaPropagationGrid->SetCellValue( row, VIA_GRID_SIGNAL_LAYER_TO, m_layerNames.back() );
-
- const PCB_LAYER_ID lastViaFromId = m_prevLayerNamesToIDs[currentViaLayersFrom[row]];
-
- if( m_copperLayerIdsToColumns.contains( lastViaFromId ) )
- m_viaPropagationGrid->SetCellValue( row, VIA_GRID_VIA_LAYER_FROM, m_board->GetLayerName( lastViaFromId ) );
- else
- m_viaPropagationGrid->SetCellValue( row, VIA_GRID_VIA_LAYER_FROM, m_layerNames.front() );
-
- const PCB_LAYER_ID lastViaToId = m_prevLayerNamesToIDs[currentViaLayersTo[row]];
-
- if( m_copperLayerIdsToColumns.contains( lastViaToId ) )
- m_viaPropagationGrid->SetCellValue( row, VIA_GRID_VIA_LAYER_TO, m_board->GetLayerName( lastViaToId ) );
- else
- m_viaPropagationGrid->SetCellValue( row, VIA_GRID_VIA_LAYER_TO, m_layerNames.back() );
- }
-}
-
-
-void PANEL_SETUP_TIME_DOMAIN_PARAMETERS::OnAddDelayProfileClick( wxCommandEvent& event )
-{
- m_tracePropagationGrid->OnAddRow(
- [&]() -> std::pair
- {
- const int row = m_tracePropagationGrid->GetNumberRows();
- m_tracePropagationGrid->AppendRows();
- m_tracePropagationGrid->SetCellValue( row, PROFILE_GRID_PROFILE_NAME, "" );
-
- for( int i = PROFILE_GRID_VIA_PROP_DELAY; i < m_tracePropagationGrid->GetNumberCols(); ++i )
- m_tracePropagationGrid->SetUnitValue( row, i, 0 );
-
- return { row, PROFILE_GRID_PROFILE_NAME };
- } );
-}
-
-
-void PANEL_SETUP_TIME_DOMAIN_PARAMETERS::OnRemoveDelayProfileClick( wxCommandEvent& event )
-{
- m_tracePropagationGrid->OnDeleteRows(
- [&]( int row )
- {
- wxString profileName = getProfileNameForProfileGridRow( row );
-
- // Delete associated via overrides
- for( int viaRow = m_viaPropagationGrid->GetNumberRows() - 1; viaRow >= 0; --viaRow )
- {
- if( m_viaPropagationGrid->GetCellValue( viaRow, VIA_GRID_PROFILE_NAME ) == profileName )
- m_viaPropagationGrid->DeleteRows( viaRow, 1 );
- }
-
- // Delete tuning profile
- m_tracePropagationGrid->DeleteRows( row, 1 );
-
- updateViaProfileNamesEditor();
- } );
-}
-
-
-void PANEL_SETUP_TIME_DOMAIN_PARAMETERS::OnAddViaOverrideClick( wxCommandEvent& event )
-{
- m_viaPropagationGrid->OnAddRow(
- [&]() -> std::pair
- {
- const int row = m_viaPropagationGrid->GetNumberRows();
-
- // Check we have delay profiles to override
- if( m_tracePropagationGrid->GetNumberRows() == 0 )
- {
- PAGED_DIALOG::GetDialog( this )->SetError( _( "No delay profiles to override" ), this, nullptr );
- return { row, -1 };
- }
-
- m_viaPropagationGrid->AppendRows();
- m_viaPropagationGrid->SetCellValue( row, VIA_GRID_PROFILE_NAME, getProfileNameForProfileGridRow( 0 ) );
- m_viaPropagationGrid->SetCellValue( row, VIA_GRID_SIGNAL_LAYER_FROM, m_layerNames.front() );
- m_viaPropagationGrid->SetCellValue( row, VIA_GRID_SIGNAL_LAYER_TO, m_layerNames.back() );
- m_viaPropagationGrid->SetCellValue( row, VIA_GRID_VIA_LAYER_FROM, m_layerNames.front() );
- m_viaPropagationGrid->SetCellValue( row, VIA_GRID_VIA_LAYER_TO, m_layerNames.back() );
- m_viaPropagationGrid->SetUnitValue( row, VIA_GRID_DELAY, 0 );
-
- return { row, VIA_GRID_DELAY };
- } );
-}
-
-
-void PANEL_SETUP_TIME_DOMAIN_PARAMETERS::OnRemoveViaOverrideClick( wxCommandEvent& event )
-{
- m_viaPropagationGrid->OnDeleteRows(
- [&]( int row )
- {
- m_viaPropagationGrid->DeleteRows( row, 1 );
- } );
-}
-
-
-void PANEL_SETUP_TIME_DOMAIN_PARAMETERS::OnDelayProfileGridCellChanging( wxGridEvent& event )
-{
- if( event.GetCol() == PROFILE_GRID_PROFILE_NAME )
- {
- if( validateDelayProfileName( event.GetRow(), event.GetString() ) )
- {
- const wxString oldName = getProfileNameForProfileGridRow( event.GetRow() );
- wxString newName = event.GetString();
- newName.Trim( true ).Trim( false );
-
- if( !oldName.IsEmpty() )
- {
- wxWindowUpdateLocker updateLocker( m_viaPropagationGrid );
-
- updateViaProfileNamesEditor( oldName, newName );
-
- // Update changed profile names
- for( int row = 0; row < m_viaPropagationGrid->GetNumberRows(); ++row )
- {
- if( m_viaPropagationGrid->GetCellValue( row, VIA_GRID_PROFILE_NAME ) == oldName )
- m_viaPropagationGrid->SetCellValue( row, VIA_GRID_PROFILE_NAME, newName );
- }
- }
- else
- {
- updateViaProfileNamesEditor( oldName, newName );
- }
- }
- else
- {
- event.Veto();
- }
- }
-}
-
-
-void PANEL_SETUP_TIME_DOMAIN_PARAMETERS::updateViaProfileNamesEditor( const wxString& aOldName,
- const wxString& aNewName ) const
-{
- wxArrayString profileNames;
-
- for( int i = 0; i < m_tracePropagationGrid->GetNumberRows(); ++i )
- {
- wxString profileName = getProfileNameForProfileGridRow( i );
-
- if( profileName == aOldName )
- profileName = aNewName;
-
- profileNames.push_back( profileName );
- }
-
- std::ranges::sort( profileNames,
- []( const wxString& a, const wxString& b )
- {
- return a.CmpNoCase( b ) < 0;
- } );
-
- wxGridCellAttr* attr = new wxGridCellAttr;
- attr->SetEditor( new wxGridCellChoiceEditor( profileNames, false ) );
- m_viaPropagationGrid->SetColAttr( VIA_GRID_PROFILE_NAME, attr );
-}
-
-
-bool PANEL_SETUP_TIME_DOMAIN_PARAMETERS::validateDelayProfileName( int aRow, const wxString& aName, bool focusFirst )
-{
- wxString tmp = aName;
- tmp.Trim( true );
- tmp.Trim( false );
-
- if( tmp.IsEmpty() )
- {
- const wxString msg = _( "Tuning profile must have a name" );
- PAGED_DIALOG::GetDialog( this )->SetError( msg, this, m_tracePropagationGrid, aRow, PROFILE_GRID_PROFILE_NAME );
- return false;
- }
-
- for( int ii = 0; ii < m_tracePropagationGrid->GetNumberRows(); ii++ )
- {
- if( ii != aRow && getProfileNameForProfileGridRow( ii ).CmpNoCase( tmp ) == 0 )
- {
- const wxString msg = _( "Tuning profile name already in use" );
- PAGED_DIALOG::GetDialog( this )->SetError( msg, this, m_tracePropagationGrid, focusFirst ? aRow : ii,
- PROFILE_GRID_PROFILE_NAME );
- return false;
- }
- }
-
- return true;
-}
-
-
-bool PANEL_SETUP_TIME_DOMAIN_PARAMETERS::Validate()
-{
- if( !m_tracePropagationGrid->CommitPendingChanges() || !m_viaPropagationGrid->CommitPendingChanges() )
- return false;
-
- // Test delay profile parameters
- for( int row = 0; row < m_tracePropagationGrid->GetNumberRows(); row++ )
- {
- const wxString profileName = getProfileNameForProfileGridRow( row );
-
- if( !validateDelayProfileName( row, profileName, false ) )
- return false;
- }
-
- // Test via override parameters
- if( !validateViaRows() )
- return false;
-
- return true;
-}
-
-
-bool PANEL_SETUP_TIME_DOMAIN_PARAMETERS::validateViaRows()
-{
- std::map> rowCache;
-
- for( int row = 0; row < m_viaPropagationGrid->GetNumberRows(); row++ )
- {
- DELAY_PROFILE_VIA_OVERRIDE_ENTRY entry = getViaRow( row );
- const wxString profileName = m_viaPropagationGrid->GetCellValue( row, VIA_GRID_PROFILE_NAME );
- std::set& viaOverrides = rowCache[profileName];
-
- if( viaOverrides.contains( entry ) )
- {
- const wxString msg = _( "Via override configuration is duplicated" );
- PAGED_DIALOG::GetDialog( this )->SetError( msg, this, m_viaPropagationGrid, row, VIA_GRID_PROFILE_NAME );
- return false;
- }
- else
- {
- viaOverrides.insert( entry );
- }
- }
-
- return true;
-}
-
-
-std::vector PANEL_SETUP_TIME_DOMAIN_PARAMETERS::GetDelayProfileNames() const
-{
- std::vector profileNames;
-
- for( int i = 0; i < m_tracePropagationGrid->GetNumberRows(); i++ )
- {
- const wxString profileName = getProfileNameForProfileGridRow( i );
- profileNames.emplace_back( profileName );
- }
-
- std::ranges::sort( profileNames,
- []( const wxString& a, const wxString& b )
- {
- return a.CmpNoCase( b ) < 0;
- } );
-
- return profileNames;
-}
-
-
-void PANEL_SETUP_TIME_DOMAIN_PARAMETERS::ImportSettingsFrom(
- const std::shared_ptr& aOtherParameters )
-{
- std::shared_ptr savedParameters = m_timeDomainParameters;
-
- m_timeDomainParameters = aOtherParameters;
- TransferDataToWindow();
-
- updateViaProfileNamesEditor();
-
- m_viaPropagationGrid->ForceRefresh();
-
- m_timeDomainParameters = std::move( savedParameters );
-}
-
-
-wxString PANEL_SETUP_TIME_DOMAIN_PARAMETERS::getProfileNameForProfileGridRow( const int aRow ) const
-{
- wxString profileName = m_tracePropagationGrid->GetCellValue( aRow, PROFILE_GRID_PROFILE_NAME );
- profileName.Trim( true ).Trim( false );
- return profileName;
-}
\ No newline at end of file
diff --git a/pcbnew/dialogs/panel_setup_time_domain_parameters.h b/pcbnew/dialogs/panel_setup_time_domain_parameters.h
deleted file mode 100644
index 90e310319c..0000000000
--- a/pcbnew/dialogs/panel_setup_time_domain_parameters.h
+++ /dev/null
@@ -1,156 +0,0 @@
-/*
- * This program source code file is part of KiCad, a free EDA CAD application.
- *
- * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, you may find one here:
- * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
- * or you may search the http://www.gnu.org website for the version 2 license,
- * or you may write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-
-#ifndef PANEL_SETUP_TIME_DOMAIN_PARAMETERS_H
-#define PANEL_SETUP_TIME_DOMAIN_PARAMETERS_H
-
-#include
-
-#include
-#include
-#include
-
-class NET_SETTINGS;
-
-
-class PANEL_SETUP_TIME_DOMAIN_PARAMETERS : public PANEL_SETUP_TIME_DOMAIN_PARAMETERS_BASE
-{
-public:
- PANEL_SETUP_TIME_DOMAIN_PARAMETERS(
- wxWindow* aParentWindow, PCB_EDIT_FRAME* aFrame, BOARD* aBoard,
- std::shared_ptr aTimeDomainParameters );
- ~PANEL_SETUP_TIME_DOMAIN_PARAMETERS() override;
-
- /**
- * Called when switching to this tab to make sure that any changes to the copper layer count
- * made on the physical stackup page are reflected here
- * @param aNumCopperLayers is the number of copper layers in the board
- */
- void SyncCopperLayers( int aNumCopperLayers );
-
- /// Load parameter data from the settings object
- bool TransferDataToWindow() override;
-
- /// Save parameter data to the settings object
- bool TransferDataFromWindow() override;
-
- /// Returns all configured tuning profile names. Used by the netclass setup panel
- std::vector GetDelayProfileNames() const;
-
- /// Load configuration from the given settings object
- void ImportSettingsFrom( const std::shared_ptr& aOtherParameters );
-
-private:
- enum PROFILE_GRID_REQUIRED_COLS
- {
- PROFILE_GRID_PROFILE_NAME = 0,
- PROFILE_GRID_VIA_PROP_DELAY,
- PROFILE_GRID_NUM_REQUIRED_COLS
- };
-
- enum VIA_GRID_REQUIRED_COLS
- {
- VIA_GRID_PROFILE_NAME = 0,
- VIA_GRID_SIGNAL_LAYER_FROM,
- VIA_GRID_SIGNAL_LAYER_TO,
- VIA_GRID_VIA_LAYER_FROM,
- VIA_GRID_VIA_LAYER_TO,
- VIA_GRID_DELAY
- };
-
- /// Optimise grid columns to fit titles and content
- void setColumnWidths();
-
- /// Updates the via override tuning profile name dropdown lists
- /// Updates entries if aOldName and aNewName are passed
- void updateViaProfileNamesEditor( const wxString& aOldName = wxEmptyString,
- const wxString& aNewName = wxEmptyString ) const;
-
- /// Update the dynamic (per-layer) columns in the tuning profiles grid
- void updateProfileGridColumns();
-
- /// Update the dynamic (per-layer) columns in the via overrides grid
- void updateViaGridColumns();
-
- /// Adds a new tuning profile entry to the tuning profile grid
- void OnAddDelayProfileClick( wxCommandEvent& event ) override;
-
- /// Removes a tuning profile entry from the tuning profile grid
- void OnRemoveDelayProfileClick( wxCommandEvent& event ) override;
-
- /// Adds a new via override profile entry to the via overrides grid
- void OnAddViaOverrideClick( wxCommandEvent& event ) override;
-
- /// Removes a via override profile entry from the via overrides grid
- void OnRemoveViaOverrideClick( wxCommandEvent& event ) override;
-
- /// Validates a tuning profile row data
- void OnDelayProfileGridCellChanging( wxGridEvent& event );
-
- /// Validates a tuning profile name (checks for not empty and not duplicated)
- bool validateDelayProfileName( int aRow, const wxString& aName, bool focusFirst = true );
-
- /// Validates all data
- bool Validate() override;
-
- /// Validates all via override rows
- bool validateViaRows();
-
- /// Adds a tuning profile row with the given persisted parameters
- void addProfileRow( const DELAY_PROFILE& aDelayProfile );
-
- /// Gets a tuning profile row as a set of persistable parameters
- DELAY_PROFILE getProfileRow( int aRow );
-
- /// Adds a via override row with the given persisted parameters
- void addViaRow( const wxString& aProfileName, const DELAY_PROFILE_VIA_OVERRIDE_ENTRY& aViaOverrideEntry ) const;
-
- /// Gets a via override row as a set of persistable parameters
- DELAY_PROFILE_VIA_OVERRIDE_ENTRY getViaRow( int aRow );
-
- /// Gets the profile name for the given profile grid row
- wxString getProfileNameForProfileGridRow( int aRow ) const;
-
- /// The parameters object to load / save data from / to
- std::shared_ptr m_timeDomainParameters;
-
- /// The active edit frame
- PCB_EDIT_FRAME* m_frame;
-
- /// The current board
- BOARD* m_board;
-
- std::unique_ptr m_unitsProvider;
-
- // Layer / column lookups
- std::map m_copperLayerIdsToColumns;
- std::map m_copperColumnsToLayerId;
- std::vector m_layerNames;
-
- // We cache these in case the names change on the layers panel
- std::map m_layerNamesToIDs;
- std::map m_prevLayerNamesToIDs;
-};
-
-#endif // PANEL_SETUP_TIME_DOMAIN_PARAMETERS_H
diff --git a/pcbnew/dialogs/panel_setup_time_domain_parameters_base.cpp b/pcbnew/dialogs/panel_setup_time_domain_parameters_base.cpp
deleted file mode 100644
index 8f25c84950..0000000000
--- a/pcbnew/dialogs/panel_setup_time_domain_parameters_base.cpp
+++ /dev/null
@@ -1,185 +0,0 @@
-///////////////////////////////////////////////////////////////////////////
-// C++ code generated with wxFormBuilder (version 4.2.1-0-g80c4cb6)
-// http://www.wxformbuilder.org/
-//
-// PLEASE DO *NOT* EDIT THIS FILE!
-///////////////////////////////////////////////////////////////////////////
-
-#include "widgets/std_bitmap_button.h"
-#include "widgets/wx_grid.h"
-#include "widgets/wx_panel.h"
-
-#include "panel_setup_time_domain_parameters_base.h"
-
-///////////////////////////////////////////////////////////////////////////
-
-PANEL_SETUP_TIME_DOMAIN_PARAMETERS_BASE::PANEL_SETUP_TIME_DOMAIN_PARAMETERS_BASE( wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style, const wxString& name ) : wxPanel( parent, id, pos, size, style, name )
-{
- wxBoxSizer* bpanelTomeDomainSizer;
- bpanelTomeDomainSizer = new wxBoxSizer( wxVERTICAL );
-
- wxBoxSizer* bMargins;
- bMargins = new wxBoxSizer( wxVERTICAL );
-
- m_splitter = new wxSplitterWindow( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSP_3DSASH|wxSP_LIVE_UPDATE|wxSP_NO_XP_THEME );
- m_splitter->SetMinimumPaneSize( 160 );
-
- m_timeDomainParametersPane = new WX_PANEL( m_splitter, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
- wxBoxSizer* bUpperSizer;
- bUpperSizer = new wxBoxSizer( wxVERTICAL );
-
- m_staticText3 = new wxStaticText( m_timeDomainParametersPane, wxID_ANY, _("Delay Profiles"), wxDefaultPosition, wxDefaultSize, 0 );
- m_staticText3->Wrap( -1 );
- bUpperSizer->Add( m_staticText3, 0, wxTOP|wxLEFT|wxEXPAND, 8 );
-
-
- bUpperSizer->Add( 0, 3, 0, wxEXPAND, 5 );
-
- m_tracePropagationGrid = new WX_GRID( m_timeDomainParametersPane, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxHSCROLL|wxTAB_TRAVERSAL|wxVSCROLL );
-
- // Grid
- m_tracePropagationGrid->CreateGrid( 0, 2 );
- m_tracePropagationGrid->EnableEditing( true );
- m_tracePropagationGrid->EnableGridLines( true );
- m_tracePropagationGrid->EnableDragGridSize( false );
- m_tracePropagationGrid->SetMargins( 0, 0 );
-
- // Columns
- m_tracePropagationGrid->EnableDragColMove( false );
- m_tracePropagationGrid->EnableDragColSize( true );
- m_tracePropagationGrid->SetColLabelValue( 0, _("Profile Name") );
- m_tracePropagationGrid->SetColLabelValue( 1, _("Vias") );
- m_tracePropagationGrid->SetColLabelSize( wxGRID_AUTOSIZE );
- m_tracePropagationGrid->SetColLabelAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
-
- // Rows
- m_tracePropagationGrid->EnableDragRowSize( true );
- m_tracePropagationGrid->SetRowLabelSize( 0 );
- m_tracePropagationGrid->SetRowLabelAlignment( wxALIGN_LEFT, wxALIGN_CENTER );
-
- // Label Appearance
-
- // Cell Defaults
- m_tracePropagationGrid->SetDefaultCellAlignment( wxALIGN_LEFT, wxALIGN_CENTER );
- bUpperSizer->Add( m_tracePropagationGrid, 1, wxEXPAND|wxFIXED_MINSIZE|wxRIGHT|wxLEFT, 5 );
-
- wxBoxSizer* buttonBoxSizer;
- buttonBoxSizer = new wxBoxSizer( wxHORIZONTAL );
-
- m_addDelayProfileButton = new STD_BITMAP_BUTTON( m_timeDomainParametersPane, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( -1,-1 ), wxBU_AUTODRAW|0 );
- buttonBoxSizer->Add( m_addDelayProfileButton, 0, wxBOTTOM|wxLEFT, 5 );
-
-
- buttonBoxSizer->Add( 20, 0, 0, wxEXPAND, 5 );
-
- m_removeDelayProfileButton = new STD_BITMAP_BUTTON( m_timeDomainParametersPane, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( -1,-1 ), wxBU_AUTODRAW|0 );
- buttonBoxSizer->Add( m_removeDelayProfileButton, 0, wxBOTTOM|wxLEFT, 5 );
-
-
- buttonBoxSizer->Add( 20, 0, 0, wxEXPAND, 5 );
-
-
- bUpperSizer->Add( buttonBoxSizer, 0, wxEXPAND|wxTOP, 3 );
-
-
- m_timeDomainParametersPane->SetSizer( bUpperSizer );
- m_timeDomainParametersPane->Layout();
- bUpperSizer->Fit( m_timeDomainParametersPane );
- m_viaDelayOverridesPane = new WX_PANEL( m_splitter, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
- wxBoxSizer* bUpperSizer1;
- bUpperSizer1 = new wxBoxSizer( wxVERTICAL );
-
- m_staticText31 = new wxStaticText( m_viaDelayOverridesPane, wxID_ANY, _("Via Delay Overrides"), wxDefaultPosition, wxDefaultSize, 0 );
- m_staticText31->Wrap( -1 );
- bUpperSizer1->Add( m_staticText31, 0, wxTOP|wxLEFT|wxEXPAND, 8 );
-
-
- bUpperSizer1->Add( 0, 3, 0, wxEXPAND, 5 );
-
- m_viaPropagationGrid = new WX_GRID( m_viaDelayOverridesPane, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxHSCROLL|wxTAB_TRAVERSAL|wxVSCROLL );
-
- // Grid
- m_viaPropagationGrid->CreateGrid( 0, 6 );
- m_viaPropagationGrid->EnableEditing( true );
- m_viaPropagationGrid->EnableGridLines( true );
- m_viaPropagationGrid->EnableDragGridSize( false );
- m_viaPropagationGrid->SetMargins( 0, 0 );
-
- // Columns
- m_viaPropagationGrid->EnableDragColMove( false );
- m_viaPropagationGrid->EnableDragColSize( true );
- m_viaPropagationGrid->SetColLabelValue( 0, _("Profile Name") );
- m_viaPropagationGrid->SetColLabelValue( 1, _("Signal Layer From") );
- m_viaPropagationGrid->SetColLabelValue( 2, _("Signal Layer To") );
- m_viaPropagationGrid->SetColLabelValue( 3, _("Via Layer From") );
- m_viaPropagationGrid->SetColLabelValue( 4, _("Via Layer To") );
- m_viaPropagationGrid->SetColLabelValue( 5, _("Delay") );
- m_viaPropagationGrid->SetColLabelSize( wxGRID_AUTOSIZE );
- m_viaPropagationGrid->SetColLabelAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
-
- // Rows
- m_viaPropagationGrid->EnableDragRowSize( true );
- m_viaPropagationGrid->SetRowLabelSize( 0 );
- m_viaPropagationGrid->SetRowLabelAlignment( wxALIGN_LEFT, wxALIGN_CENTER );
-
- // Label Appearance
-
- // Cell Defaults
- m_viaPropagationGrid->SetDefaultCellAlignment( wxALIGN_LEFT, wxALIGN_CENTER );
- bUpperSizer1->Add( m_viaPropagationGrid, 1, wxEXPAND|wxFIXED_MINSIZE|wxRIGHT|wxLEFT, 5 );
-
- wxBoxSizer* buttonBoxSizer1;
- buttonBoxSizer1 = new wxBoxSizer( wxHORIZONTAL );
-
- m_addViaOverrideButton = new STD_BITMAP_BUTTON( m_viaDelayOverridesPane, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( -1,-1 ), wxBU_AUTODRAW|0 );
- buttonBoxSizer1->Add( m_addViaOverrideButton, 0, wxBOTTOM|wxLEFT, 5 );
-
-
- buttonBoxSizer1->Add( 20, 0, 0, wxEXPAND, 5 );
-
- m_removeViaOverrideButton = new STD_BITMAP_BUTTON( m_viaDelayOverridesPane, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( -1,-1 ), wxBU_AUTODRAW|0 );
- buttonBoxSizer1->Add( m_removeViaOverrideButton, 0, wxBOTTOM|wxLEFT, 5 );
-
-
- buttonBoxSizer1->Add( 20, 0, 0, wxEXPAND, 5 );
-
-
- bUpperSizer1->Add( buttonBoxSizer1, 0, wxEXPAND|wxTOP, 3 );
-
-
- m_viaDelayOverridesPane->SetSizer( bUpperSizer1 );
- m_viaDelayOverridesPane->Layout();
- bUpperSizer1->Fit( m_viaDelayOverridesPane );
- m_splitter->SplitHorizontally( m_timeDomainParametersPane, m_viaDelayOverridesPane, -1 );
- bMargins->Add( m_splitter, 1, wxEXPAND, 10 );
-
-
- bpanelTomeDomainSizer->Add( bMargins, 1, wxEXPAND|wxTOP, 2 );
-
-
- this->SetSizer( bpanelTomeDomainSizer );
- this->Layout();
- bpanelTomeDomainSizer->Fit( this );
-
- // Connect Events
- this->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( PANEL_SETUP_TIME_DOMAIN_PARAMETERS_BASE::OnUpdateUI ) );
- m_tracePropagationGrid->Connect( wxEVT_SIZE, wxSizeEventHandler( PANEL_SETUP_TIME_DOMAIN_PARAMETERS_BASE::OnSizeTraceParametersGrid ), NULL, this );
- m_addDelayProfileButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_SETUP_TIME_DOMAIN_PARAMETERS_BASE::OnAddDelayProfileClick ), NULL, this );
- m_removeDelayProfileButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_SETUP_TIME_DOMAIN_PARAMETERS_BASE::OnRemoveDelayProfileClick ), NULL, this );
- m_viaPropagationGrid->Connect( wxEVT_SIZE, wxSizeEventHandler( PANEL_SETUP_TIME_DOMAIN_PARAMETERS_BASE::OnSizeTraceParametersGrid ), NULL, this );
- m_addViaOverrideButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_SETUP_TIME_DOMAIN_PARAMETERS_BASE::OnAddViaOverrideClick ), NULL, this );
- m_removeViaOverrideButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_SETUP_TIME_DOMAIN_PARAMETERS_BASE::OnRemoveViaOverrideClick ), NULL, this );
-}
-
-PANEL_SETUP_TIME_DOMAIN_PARAMETERS_BASE::~PANEL_SETUP_TIME_DOMAIN_PARAMETERS_BASE()
-{
- // Disconnect Events
- this->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( PANEL_SETUP_TIME_DOMAIN_PARAMETERS_BASE::OnUpdateUI ) );
- m_tracePropagationGrid->Disconnect( wxEVT_SIZE, wxSizeEventHandler( PANEL_SETUP_TIME_DOMAIN_PARAMETERS_BASE::OnSizeTraceParametersGrid ), NULL, this );
- m_addDelayProfileButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_SETUP_TIME_DOMAIN_PARAMETERS_BASE::OnAddDelayProfileClick ), NULL, this );
- m_removeDelayProfileButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_SETUP_TIME_DOMAIN_PARAMETERS_BASE::OnRemoveDelayProfileClick ), NULL, this );
- m_viaPropagationGrid->Disconnect( wxEVT_SIZE, wxSizeEventHandler( PANEL_SETUP_TIME_DOMAIN_PARAMETERS_BASE::OnSizeTraceParametersGrid ), NULL, this );
- m_addViaOverrideButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_SETUP_TIME_DOMAIN_PARAMETERS_BASE::OnAddViaOverrideClick ), NULL, this );
- m_removeViaOverrideButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_SETUP_TIME_DOMAIN_PARAMETERS_BASE::OnRemoveViaOverrideClick ), NULL, this );
-
-}
diff --git a/pcbnew/dialogs/panel_setup_time_domain_parameters_base.fbp b/pcbnew/dialogs/panel_setup_time_domain_parameters_base.fbp
deleted file mode 100644
index 07e4e39826..0000000000
--- a/pcbnew/dialogs/panel_setup_time_domain_parameters_base.fbp
+++ /dev/null
@@ -1,950 +0,0 @@
-
-
-
-
-
diff --git a/pcbnew/dialogs/panel_setup_time_domain_parameters_base.h b/pcbnew/dialogs/panel_setup_time_domain_parameters_base.h
deleted file mode 100644
index b05d18c433..0000000000
--- a/pcbnew/dialogs/panel_setup_time_domain_parameters_base.h
+++ /dev/null
@@ -1,71 +0,0 @@
-///////////////////////////////////////////////////////////////////////////
-// C++ code generated with wxFormBuilder (version 4.2.1-0-g80c4cb6)
-// http://www.wxformbuilder.org/
-//
-// PLEASE DO *NOT* EDIT THIS FILE!
-///////////////////////////////////////////////////////////////////////////
-
-#pragma once
-
-#include
-#include
-#include
-class STD_BITMAP_BUTTON;
-class WX_GRID;
-class WX_PANEL;
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-///////////////////////////////////////////////////////////////////////////
-
-///////////////////////////////////////////////////////////////////////////////
-/// Class PANEL_SETUP_TIME_DOMAIN_PARAMETERS_BASE
-///////////////////////////////////////////////////////////////////////////////
-class PANEL_SETUP_TIME_DOMAIN_PARAMETERS_BASE : public wxPanel
-{
- private:
-
- protected:
- wxSplitterWindow* m_splitter;
- WX_PANEL* m_timeDomainParametersPane;
- wxStaticText* m_staticText3;
- WX_GRID* m_tracePropagationGrid;
- STD_BITMAP_BUTTON* m_addDelayProfileButton;
- STD_BITMAP_BUTTON* m_removeDelayProfileButton;
- WX_PANEL* m_viaDelayOverridesPane;
- wxStaticText* m_staticText31;
- WX_GRID* m_viaPropagationGrid;
- STD_BITMAP_BUTTON* m_addViaOverrideButton;
- STD_BITMAP_BUTTON* m_removeViaOverrideButton;
-
- // Virtual event handlers, override them in your derived class
- virtual void OnUpdateUI( wxUpdateUIEvent& event ) { event.Skip(); }
- virtual void OnSizeTraceParametersGrid( wxSizeEvent& event ) { event.Skip(); }
- virtual void OnAddDelayProfileClick( wxCommandEvent& event ) { event.Skip(); }
- virtual void OnRemoveDelayProfileClick( wxCommandEvent& event ) { event.Skip(); }
- virtual void OnAddViaOverrideClick( wxCommandEvent& event ) { event.Skip(); }
- virtual void OnRemoveViaOverrideClick( wxCommandEvent& event ) { event.Skip(); }
-
-
- public:
-
- PANEL_SETUP_TIME_DOMAIN_PARAMETERS_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxTAB_TRAVERSAL, const wxString& name = wxEmptyString );
-
- ~PANEL_SETUP_TIME_DOMAIN_PARAMETERS_BASE();
-
-};
-
diff --git a/pcbnew/dialogs/panel_setup_tuning_profile_info.cpp b/pcbnew/dialogs/panel_setup_tuning_profile_info.cpp
new file mode 100644
index 0000000000..77d46879e1
--- /dev/null
+++ b/pcbnew/dialogs/panel_setup_tuning_profile_info.cpp
@@ -0,0 +1,1398 @@
+/*
+* This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+PANEL_SETUP_TUNING_PROFILE_INFO::PANEL_SETUP_TUNING_PROFILE_INFO( wxWindow* aParentWindow,
+ PANEL_SETUP_TUNING_PROFILES* parentPanel ) :
+ PANEL_SETUP_TUNING_PROFILE_INFO_BASE( aParentWindow ),
+ m_parentPanel( parentPanel ),
+ m_viaPropagationUnits( parentPanel->m_frame, m_viaPropagationSpeedLabel, m_viaPropagationSpeed,
+ m_viaPropSpeedUnits )
+{
+ Freeze();
+ initPanel();
+ Thaw();
+}
+
+
+void PANEL_SETUP_TUNING_PROFILE_INFO::initPanel()
+{
+ if( EDA_UNIT_UTILS::IsImperialUnit( m_parentPanel->m_unitsProvider->GetUserUnits() ) )
+ m_viaPropagationUnits.SetUnits( EDA_UNITS::PS_PER_INCH );
+ else
+ m_viaPropagationUnits.SetUnits( EDA_UNITS::PS_PER_CM );
+
+ m_viaPropagationUnits.SetValue( 0 );
+
+ m_addTrackPropogationLayer->SetBitmap( KiBitmapBundle( BITMAPS::small_plus ) );
+ m_deleteTrackPropogationLayer->SetBitmap( KiBitmapBundle( BITMAPS::small_trash ) );
+
+ m_addViaPropagationOverride->SetBitmap( KiBitmapBundle( BITMAPS::small_plus ) );
+ m_removeViaPropagationOverride->SetBitmap( KiBitmapBundle( BITMAPS::small_trash ) );
+
+ m_targetImpedance->SetValue( "0" );
+
+ UNITS_PROVIDER* unitsProvider = m_parentPanel->m_unitsProvider.get();
+
+ m_trackPropagationGrid->SetUnitsProvider( unitsProvider );
+ m_viaOverrides->SetUnitsProvider( unitsProvider );
+
+ // Configure the track grid
+ m_trackPropagationGrid->BeginBatch();
+ m_trackPropagationGrid->SetUseNativeColLabels();
+
+ m_trackPropagationGrid->EnsureColLabelsVisible();
+ m_trackPropagationGrid->PushEventHandler( new GRID_TRICKS( m_trackPropagationGrid ) );
+ m_trackPropagationGrid->SetSelectionMode( wxGrid::wxGridSelectRows );
+
+ std::vector trackColIds;
+ m_trackPropagationGrid->SetAutoEvalColUnits( TRACK_GRID_DELAY,
+ unitsProvider->GetUnitsFromType( EDA_DATA_TYPE::LENGTH_DELAY ) );
+ trackColIds.push_back( TRACK_GRID_DELAY );
+ m_trackPropagationGrid->SetAutoEvalColUnits( TRACK_GRID_TRACK_WIDTH,
+ unitsProvider->GetUnitsFromType( EDA_DATA_TYPE::DISTANCE ) );
+ trackColIds.push_back( TRACK_GRID_TRACK_WIDTH );
+ m_trackPropagationGrid->SetAutoEvalColUnits( TRACK_GRID_TRACK_GAP,
+ unitsProvider->GetUnitsFromType( EDA_DATA_TYPE::DISTANCE ) );
+ trackColIds.push_back( TRACK_GRID_TRACK_GAP );
+ m_trackPropagationGrid->SetAutoEvalCols( trackColIds );
+
+ // Add the calculation editors
+ wxGridCellAttr* attr = new wxGridCellAttr;
+ attr->SetEditor( new GRID_CELL_RUN_FUNCTION_EDITOR(
+ m_parentPanel->m_dlg,
+ [this]( int row, int col )
+ {
+ calculateTrackParametersForCell( row, col );
+ },
+ false ) );
+ m_trackPropagationGrid->SetColAttr( TRACK_GRID_TRACK_WIDTH, attr );
+
+ attr = new wxGridCellAttr;
+ attr->SetEditor( new GRID_CELL_RUN_FUNCTION_EDITOR(
+ m_parentPanel->m_dlg,
+ [this]( int row, int col )
+ {
+ calculateTrackParametersForCell( row, col );
+ },
+ false ) );
+ m_trackPropagationGrid->SetColAttr( TRACK_GRID_TRACK_GAP, attr );
+
+ attr = new wxGridCellAttr;
+ attr->SetEditor( new GRID_CELL_RUN_FUNCTION_EDITOR(
+ m_parentPanel->m_dlg,
+ [this]( int row, int col )
+ {
+ calculateTrackParametersForCell( row, col );
+ },
+ false ) );
+ m_trackPropagationGrid->SetColAttr( TRACK_GRID_DELAY, attr );
+
+ m_trackPropagationGrid->EndBatch();
+
+ // Configure the via grid
+ m_viaOverrides->BeginBatch();
+ m_viaOverrides->SetUseNativeColLabels();
+
+ m_viaOverrides->EnsureColLabelsVisible();
+ m_viaOverrides->PushEventHandler( new GRID_TRICKS( m_viaOverrides ) );
+ m_viaOverrides->SetSelectionMode( wxGrid::wxGridSelectRows );
+
+ std::vector viaColIds;
+ m_viaOverrides->SetAutoEvalColUnits( VIA_GRID_DELAY, unitsProvider->GetUnitsFromType( EDA_DATA_TYPE::TIME ) );
+ viaColIds.push_back( VIA_GRID_DELAY );
+ m_viaOverrides->SetAutoEvalCols( viaColIds );
+ m_viaOverrides->EndBatch();
+
+ setColumnWidths();
+
+ // Hide the trace gap as we start in single mode
+ m_trackPropagationGrid->HideCol( TRACK_GRID_TRACK_GAP );
+
+ UpdateLayerNames();
+}
+
+
+void PANEL_SETUP_TUNING_PROFILE_INFO::LoadProfile( const TUNING_PROFILE& aProfile )
+{
+ m_name->SetValue( aProfile.m_ProfileName );
+ m_type->SetSelection( static_cast( aProfile.m_Type ) );
+ onChangeProfileType( aProfile.m_Type );
+ m_targetImpedance->SetValue( wxString::FromDouble( aProfile.m_TargetImpedance ) );
+ m_enableDrcGeneration->SetValue( aProfile.m_GenerateNetClassDRCRules );
+ m_enableDelayTuning->SetValue( aProfile.m_EnableTimeDomainTuning );
+ m_viaPropagationUnits.SetValue( aProfile.m_ViaPropagationDelay );
+
+ for( const auto& entry : aProfile.m_TrackPropagationEntries )
+ {
+ const int row = m_trackPropagationGrid->GetNumberRows();
+ m_trackPropagationGrid->AppendRows();
+
+ m_trackPropagationGrid->SetCellValue( row, TRACK_GRID_SIGNAL_LAYER,
+ m_parentPanel->m_board->GetLayerName( entry.GetSignalLayer() ) );
+
+ if( entry.GetTopReferenceLayer() != UNDEFINED_LAYER )
+ m_trackPropagationGrid->SetCellValue(
+ row, TRACK_GRID_TOP_REFERENCE,
+ m_parentPanel->m_board->GetLayerName( entry.GetTopReferenceLayer() ) );
+
+ if( entry.GetBottomReferenceLayer() != UNDEFINED_LAYER )
+ m_trackPropagationGrid->SetCellValue(
+ row, TRACK_GRID_BOTTOM_REFERENCE,
+ m_parentPanel->m_board->GetLayerName( entry.GetBottomReferenceLayer() ) );
+
+ m_trackPropagationGrid->SetUnitValue( row, TRACK_GRID_TRACK_WIDTH, entry.GetWidth() );
+ m_trackPropagationGrid->SetUnitValue( row, TRACK_GRID_TRACK_GAP, entry.GetDiffPairGap() );
+ m_trackPropagationGrid->SetUnitValue( row, TRACK_GRID_DELAY, entry.GetDelay() );
+ }
+
+ for( const auto& entry : aProfile.m_ViaOverrides )
+ {
+ const int row = m_viaOverrides->GetNumberRows();
+ m_viaOverrides->AppendRows();
+
+ m_viaOverrides->SetCellValue( row, VIA_GRID_SIGNAL_LAYER_FROM,
+ m_parentPanel->m_board->GetLayerName( entry.m_SignalLayerFrom ) );
+ m_viaOverrides->SetCellValue( row, VIA_GRID_SIGNAL_LAYER_TO,
+ m_parentPanel->m_board->GetLayerName( entry.m_SignalLayerTo ) );
+ m_viaOverrides->SetCellValue( row, VIA_GRID_VIA_LAYER_FROM,
+ m_parentPanel->m_board->GetLayerName( entry.m_ViaLayerFrom ) );
+ m_viaOverrides->SetCellValue( row, VIA_GRID_VIA_LAYER_TO,
+ m_parentPanel->m_board->GetLayerName( entry.m_ViaLayerTo ) );
+ m_viaOverrides->SetUnitValue( row, VIA_GRID_DELAY, entry.m_Delay );
+ }
+
+ UpdateLayerNames();
+}
+
+
+TUNING_PROFILE PANEL_SETUP_TUNING_PROFILE_INFO::GetProfile() const
+{
+ TUNING_PROFILE profile;
+ profile.m_ProfileName = m_name->GetValue();
+ profile.m_Type = static_cast( m_type->GetSelection() );
+ profile.m_GenerateNetClassDRCRules = m_enableDrcGeneration->GetValue();
+ profile.m_EnableTimeDomainTuning = m_enableDelayTuning->GetValue();
+ profile.m_ViaPropagationDelay = m_viaPropagationUnits.GetValue();
+
+ double targetImpedance;
+
+ if( m_targetImpedance->GetValue().ToDouble( &targetImpedance ) )
+ profile.m_TargetImpedance = targetImpedance;
+ else
+ profile.m_TargetImpedance = 0.0;
+
+ for( int row = 0; row < m_trackPropagationGrid->GetNumberRows(); row++ )
+ {
+ DELAY_PROFILE_TRACK_PROPAGATION_ENTRY entry;
+
+ wxString signalLayerName = m_trackPropagationGrid->GetCellValue( row, TRACK_GRID_SIGNAL_LAYER );
+ entry.SetSignalLayer( m_parentPanel->m_layerNamesToIDs[signalLayerName] );
+
+ if( wxString topReferenceLayerName = m_trackPropagationGrid->GetCellValue( row, TRACK_GRID_TOP_REFERENCE );
+ m_parentPanel->m_layerNamesToIDs.contains( topReferenceLayerName ) )
+ {
+ entry.SetTopReferenceLayer( m_parentPanel->m_layerNamesToIDs[topReferenceLayerName] );
+ }
+ else
+ {
+ entry.SetTopReferenceLayer( UNDEFINED_LAYER );
+ }
+
+ if( wxString bottomReferenceLayerName =
+ m_trackPropagationGrid->GetCellValue( row, TRACK_GRID_BOTTOM_REFERENCE );
+ m_parentPanel->m_layerNamesToIDs.contains( bottomReferenceLayerName ) )
+ {
+ entry.SetBottomReferenceLayer( m_parentPanel->m_layerNamesToIDs[bottomReferenceLayerName] );
+ }
+ else
+ {
+ entry.SetBottomReferenceLayer( UNDEFINED_LAYER );
+ }
+
+ entry.SetWidth( m_trackPropagationGrid->GetUnitValue( row, TRACK_GRID_TRACK_WIDTH ) );
+ entry.SetDiffPairGap( m_trackPropagationGrid->GetUnitValue( row, TRACK_GRID_TRACK_GAP ) );
+ entry.SetDelay( m_trackPropagationGrid->GetUnitValue( row, TRACK_GRID_DELAY ) );
+ entry.SetEnableTimeDomainTuning( profile.m_EnableTimeDomainTuning );
+
+ profile.m_TrackPropagationEntries.push_back( entry );
+ profile.m_TrackPropagationEntriesMap[entry.GetSignalLayer()] = entry;
+ }
+
+ for( int row = 0; row < m_viaOverrides->GetNumberRows(); row++ )
+ {
+ const wxString signalLayerFrom = m_viaOverrides->GetCellValue( row, VIA_GRID_SIGNAL_LAYER_FROM );
+ const wxString signalLayerTo = m_viaOverrides->GetCellValue( row, VIA_GRID_SIGNAL_LAYER_TO );
+ const wxString viaLayerFrom = m_viaOverrides->GetCellValue( row, VIA_GRID_VIA_LAYER_FROM );
+ const wxString viaLayerTo = m_viaOverrides->GetCellValue( row, VIA_GRID_VIA_LAYER_TO );
+ PCB_LAYER_ID signalLayerIdFrom = m_parentPanel->m_layerNamesToIDs[signalLayerFrom];
+ PCB_LAYER_ID signalLayerIdTo = m_parentPanel->m_layerNamesToIDs[signalLayerTo];
+ PCB_LAYER_ID viaLayerIdFrom = m_parentPanel->m_layerNamesToIDs[viaLayerFrom];
+ PCB_LAYER_ID viaLayerIdTo = m_parentPanel->m_layerNamesToIDs[viaLayerTo];
+
+ // Order layers in stackup order (from F_Cu first)
+ if( IsCopperLayerLowerThan( signalLayerIdFrom, signalLayerIdTo ) )
+ std::swap( signalLayerIdFrom, signalLayerIdTo );
+
+ if( IsCopperLayerLowerThan( viaLayerIdFrom, viaLayerIdTo ) )
+ std::swap( viaLayerIdFrom, viaLayerIdTo );
+
+ const DELAY_PROFILE_VIA_OVERRIDE_ENTRY entry{ signalLayerIdFrom, signalLayerIdTo, viaLayerIdFrom, viaLayerIdTo,
+ m_viaOverrides->GetUnitValue( row, VIA_GRID_DELAY ) };
+ profile.m_ViaOverrides.push_back( entry );
+ }
+
+ return profile;
+}
+
+
+PANEL_SETUP_TUNING_PROFILE_INFO::~PANEL_SETUP_TUNING_PROFILE_INFO()
+{
+ m_trackPropagationGrid->PopEventHandler( true );
+ m_viaOverrides->PopEventHandler( true );
+}
+
+
+void PANEL_SETUP_TUNING_PROFILE_INFO::UpdateLayerNames()
+{
+ wxArrayString layerNames, layerNamesWithNone;
+ layerNamesWithNone.push_back( "" );
+ std::ranges::for_each( m_parentPanel->m_layerNames,
+ [&layerNames, &layerNamesWithNone]( const wxString& aLayerName )
+ {
+ layerNames.push_back( aLayerName );
+ layerNamesWithNone.push_back( aLayerName );
+ } );
+
+
+ // Save the current data - track grid
+ std::vector currentSignalLayer;
+ std::vector currentTopReferenceLayer;
+ std::vector currentBottomReferenceLayer;
+
+ for( int row = 0; row < m_trackPropagationGrid->GetNumberRows(); ++row )
+ {
+ currentSignalLayer.emplace_back( m_trackPropagationGrid->GetCellValue( row, TRACK_GRID_SIGNAL_LAYER ) );
+ currentTopReferenceLayer.emplace_back( m_trackPropagationGrid->GetCellValue( row, TRACK_GRID_TOP_REFERENCE ) );
+ currentBottomReferenceLayer.emplace_back(
+ m_trackPropagationGrid->GetCellValue( row, TRACK_GRID_BOTTOM_REFERENCE ) );
+ }
+
+ // Save the current data - via grid
+ std::vector currentSignalLayersFrom;
+ std::vector currentSignalLayersTo;
+ std::vector currentViaLayersFrom;
+ std::vector currentViaLayersTo;
+
+ for( int row = 0; row < m_viaOverrides->GetNumberRows(); ++row )
+ {
+ currentSignalLayersFrom.emplace_back( m_viaOverrides->GetCellValue( row, VIA_GRID_SIGNAL_LAYER_FROM ) );
+ currentSignalLayersTo.emplace_back( m_viaOverrides->GetCellValue( row, VIA_GRID_SIGNAL_LAYER_TO ) );
+ currentViaLayersFrom.emplace_back( m_viaOverrides->GetCellValue( row, VIA_GRID_VIA_LAYER_FROM ) );
+ currentViaLayersTo.emplace_back( m_viaOverrides->GetCellValue( row, VIA_GRID_VIA_LAYER_TO ) );
+ }
+
+ // Reset the via layers lists
+ wxGridCellAttr* attr = new wxGridCellAttr;
+ attr->SetEditor( new wxGridCellChoiceEditor( layerNames, false ) );
+ m_trackPropagationGrid->SetColAttr( TRACK_GRID_SIGNAL_LAYER, attr );
+
+ attr = new wxGridCellAttr;
+ attr->SetEditor( new wxGridCellChoiceEditor( layerNamesWithNone, false ) );
+ m_trackPropagationGrid->SetColAttr( TRACK_GRID_TOP_REFERENCE, attr );
+
+ attr = new wxGridCellAttr;
+ attr->SetEditor( new wxGridCellChoiceEditor( layerNamesWithNone, false ) );
+ m_trackPropagationGrid->SetColAttr( TRACK_GRID_BOTTOM_REFERENCE, attr );
+
+ attr = new wxGridCellAttr;
+ attr->SetEditor( new wxGridCellChoiceEditor( layerNames, false ) );
+ m_viaOverrides->SetColAttr( VIA_GRID_SIGNAL_LAYER_FROM, attr );
+
+ attr = new wxGridCellAttr;
+ attr->SetEditor( new wxGridCellChoiceEditor( layerNames, false ) );
+ m_viaOverrides->SetColAttr( VIA_GRID_SIGNAL_LAYER_TO, attr );
+
+ attr = new wxGridCellAttr;
+ attr->SetEditor( new wxGridCellChoiceEditor( layerNames, false ) );
+ m_viaOverrides->SetColAttr( VIA_GRID_VIA_LAYER_FROM, attr );
+
+ attr = new wxGridCellAttr;
+ attr->SetEditor( new wxGridCellChoiceEditor( layerNames, false ) );
+ m_viaOverrides->SetColAttr( VIA_GRID_VIA_LAYER_TO, attr );
+
+ // Restore the data, changing or resetting layer names if required
+ for( int row = 0; row < m_trackPropagationGrid->GetNumberRows(); ++row )
+ {
+ if( m_parentPanel->m_prevLayerNamesToIDs.contains( currentSignalLayer[row] ) )
+ {
+ PCB_LAYER_ID lastSignalId = m_parentPanel->m_prevLayerNamesToIDs[currentSignalLayer[row]];
+
+ if( m_parentPanel->m_copperLayerIdsToIndex.contains( lastSignalId ) )
+ m_trackPropagationGrid->SetCellValue( row, TRACK_GRID_SIGNAL_LAYER,
+ m_parentPanel->m_board->GetLayerName( lastSignalId ) );
+ else
+ m_trackPropagationGrid->SetCellValue( row, TRACK_GRID_SIGNAL_LAYER,
+ m_parentPanel->m_layerNames.front() );
+ }
+ else
+ {
+ m_trackPropagationGrid->SetCellValue( row, TRACK_GRID_SIGNAL_LAYER, m_parentPanel->m_layerNames.front() );
+ }
+
+ if( m_parentPanel->m_prevLayerNamesToIDs.contains( currentTopReferenceLayer[row] ) )
+ {
+ const PCB_LAYER_ID lastTopReferenceId = m_parentPanel->m_prevLayerNamesToIDs[currentTopReferenceLayer[row]];
+
+ if( m_parentPanel->m_copperLayerIdsToIndex.contains( lastTopReferenceId ) )
+ m_trackPropagationGrid->SetCellValue( row, TRACK_GRID_TOP_REFERENCE,
+ m_parentPanel->m_board->GetLayerName( lastTopReferenceId ) );
+ else
+ m_trackPropagationGrid->SetCellValue( row, TRACK_GRID_TOP_REFERENCE, layerNamesWithNone[0] );
+ }
+ else
+ {
+ m_trackPropagationGrid->SetCellValue( row, TRACK_GRID_TOP_REFERENCE, layerNamesWithNone[0] );
+ }
+
+ if( m_parentPanel->m_prevLayerNamesToIDs.contains( currentBottomReferenceLayer[row] ) )
+ {
+ const PCB_LAYER_ID lastBottomReferenceId =
+ m_parentPanel->m_prevLayerNamesToIDs[currentBottomReferenceLayer[row]];
+
+ if( m_parentPanel->m_copperLayerIdsToIndex.contains( lastBottomReferenceId ) )
+ m_trackPropagationGrid->SetCellValue( row, TRACK_GRID_BOTTOM_REFERENCE,
+ m_parentPanel->m_board->GetLayerName( lastBottomReferenceId ) );
+ else
+ m_trackPropagationGrid->SetCellValue( row, TRACK_GRID_BOTTOM_REFERENCE, layerNamesWithNone[0] );
+ }
+ else
+ {
+ m_trackPropagationGrid->SetCellValue( row, TRACK_GRID_BOTTOM_REFERENCE, layerNamesWithNone[0] );
+ }
+ }
+
+ for( int row = 0; row < m_viaOverrides->GetNumberRows(); ++row )
+ {
+ const PCB_LAYER_ID lastSignalFromId = m_parentPanel->m_prevLayerNamesToIDs[currentSignalLayersFrom[row]];
+
+ if( m_parentPanel->m_copperLayerIdsToIndex.contains( lastSignalFromId ) )
+ m_viaOverrides->SetCellValue( row, VIA_GRID_SIGNAL_LAYER_FROM,
+ m_parentPanel->m_board->GetLayerName( lastSignalFromId ) );
+ else
+ m_viaOverrides->SetCellValue( row, VIA_GRID_SIGNAL_LAYER_FROM, m_parentPanel->m_layerNames.front() );
+
+ const PCB_LAYER_ID lastSignalToId = m_parentPanel->m_prevLayerNamesToIDs[currentSignalLayersTo[row]];
+
+ if( m_parentPanel->m_copperLayerIdsToIndex.contains( lastSignalToId ) )
+ m_viaOverrides->SetCellValue( row, VIA_GRID_SIGNAL_LAYER_TO,
+ m_parentPanel->m_board->GetLayerName( lastSignalToId ) );
+ else
+ m_viaOverrides->SetCellValue( row, VIA_GRID_SIGNAL_LAYER_TO, m_parentPanel->m_layerNames.back() );
+
+ const PCB_LAYER_ID lastViaFromId = m_parentPanel->m_prevLayerNamesToIDs[currentViaLayersFrom[row]];
+
+ if( m_parentPanel->m_copperLayerIdsToIndex.contains( lastViaFromId ) )
+ m_viaOverrides->SetCellValue( row, VIA_GRID_VIA_LAYER_FROM,
+ m_parentPanel->m_board->GetLayerName( lastViaFromId ) );
+ else
+ m_viaOverrides->SetCellValue( row, VIA_GRID_VIA_LAYER_FROM, m_parentPanel->m_layerNames.front() );
+
+ const PCB_LAYER_ID lastViaToId = m_parentPanel->m_prevLayerNamesToIDs[currentViaLayersTo[row]];
+
+ if( m_parentPanel->m_copperLayerIdsToIndex.contains( lastViaToId ) )
+ m_viaOverrides->SetCellValue( row, VIA_GRID_VIA_LAYER_TO,
+ m_parentPanel->m_board->GetLayerName( lastViaToId ) );
+ else
+ m_viaOverrides->SetCellValue( row, VIA_GRID_VIA_LAYER_TO, m_parentPanel->m_layerNames.back() );
+ }
+}
+
+
+void PANEL_SETUP_TUNING_PROFILE_INFO::setColumnWidths()
+{
+ const int minValueWidth = m_trackPropagationGrid->GetTextExtent( wxT( "000.0000 ps/mm" ) ).x;
+
+ for( int i = 0; i < m_trackPropagationGrid->GetNumberCols(); ++i )
+ {
+ const int titleSize = m_trackPropagationGrid->GetTextExtent( m_trackPropagationGrid->GetColLabelValue( i ) ).x;
+
+ if( i == TRACK_GRID_SIGNAL_LAYER || i == TRACK_GRID_TOP_REFERENCE || i == TRACK_GRID_BOTTOM_REFERENCE )
+ m_trackPropagationGrid->SetColSize( i, titleSize + 30 );
+ else
+ m_trackPropagationGrid->SetColSize( i, std::max( titleSize, minValueWidth ) );
+ }
+
+ for( int i = 0; i < m_viaOverrides->GetNumberCols(); ++i )
+ {
+ const int titleSize = GetTextExtent( m_viaOverrides->GetColLabelValue( i ) ).x;
+ if( i == VIA_GRID_DELAY )
+ m_viaOverrides->SetColSize( i, std::max( titleSize, minValueWidth ) );
+ else
+ m_viaOverrides->SetColSize( i, titleSize + 30 );
+ }
+
+ const int impedanceWidth = m_targetImpedance->GetTextExtent( wxT( "0000.00" ) ).x;
+ m_targetImpedance->SetSize( impedanceWidth, m_targetImpedance->GetSize().GetHeight() );
+
+ Layout();
+}
+
+
+void PANEL_SETUP_TUNING_PROFILE_INFO::OnProfileNameChanged( wxCommandEvent& event )
+{
+ const wxString newName = event.GetString();
+ m_parentPanel->UpdateProfileName( this, newName );
+}
+
+
+void PANEL_SETUP_TUNING_PROFILE_INFO::OnChangeProfileType( wxCommandEvent& event )
+{
+ if( event.GetSelection() == 0 )
+ onChangeProfileType( TUNING_PROFILE::PROFILE_TYPE::SINGLE );
+ else
+ onChangeProfileType( TUNING_PROFILE::PROFILE_TYPE::DIFFERENTIAL );
+}
+
+
+void PANEL_SETUP_TUNING_PROFILE_INFO::onChangeProfileType( TUNING_PROFILE::PROFILE_TYPE aType ) const
+{
+ m_trackPropagationGrid->CommitPendingChanges();
+ m_viaOverrides->CommitPendingChanges();
+
+ if( aType == TUNING_PROFILE::PROFILE_TYPE::SINGLE )
+ m_trackPropagationGrid->HideCol( TRACK_GRID_TRACK_GAP );
+ else
+ m_trackPropagationGrid->ShowCol( TRACK_GRID_TRACK_GAP );
+}
+
+
+void PANEL_SETUP_TUNING_PROFILE_INFO::OnAddTrackRow( wxCommandEvent& event )
+{
+ const int numRows = m_trackPropagationGrid->GetNumberRows();
+ m_trackPropagationGrid->InsertRows( m_trackPropagationGrid->GetNumberRows() );
+
+ auto setFrontRowLayers = [&]( const int row )
+ {
+ auto nameItr = m_parentPanel->m_layerNames.begin();
+
+ if( nameItr == m_parentPanel->m_layerNames.end() )
+ return;
+
+ m_trackPropagationGrid->SetCellValue( row, TRACK_GRID_SIGNAL_LAYER, *nameItr );
+
+ ++nameItr;
+
+ if( nameItr == m_parentPanel->m_layerNames.end() )
+ return;
+
+ m_trackPropagationGrid->SetCellValue( row, TRACK_GRID_BOTTOM_REFERENCE, *nameItr );
+ };
+
+ auto setRowLayers = [&]()
+ {
+ if( numRows == 0 )
+ {
+ setFrontRowLayers( 0 );
+ return;
+ }
+
+ const wxString lastSignalLayerName =
+ m_trackPropagationGrid->GetCellValue( numRows - 1, TRACK_GRID_SIGNAL_LAYER );
+ auto nameItr = std::find( m_parentPanel->m_layerNames.begin(), m_parentPanel->m_layerNames.end(),
+ lastSignalLayerName );
+
+ if( nameItr == m_parentPanel->m_layerNames.end() )
+ return;
+
+ if( nameItr == m_parentPanel->m_layerNames.end() - 1 )
+ {
+ setFrontRowLayers( numRows );
+ return;
+ }
+
+ ++nameItr;
+
+ if( nameItr == m_parentPanel->m_layerNames.end() )
+ return;
+
+ m_trackPropagationGrid->SetCellValue( numRows, TRACK_GRID_SIGNAL_LAYER, *nameItr );
+ m_trackPropagationGrid->SetCellValue( numRows, TRACK_GRID_TOP_REFERENCE, *( nameItr - 1 ) );
+
+ ++nameItr;
+
+ if( nameItr != m_parentPanel->m_layerNames.end() )
+ m_trackPropagationGrid->SetCellValue( numRows, TRACK_GRID_BOTTOM_REFERENCE, *nameItr );
+ };
+
+ setRowLayers();
+
+ m_trackPropagationGrid->SetUnitValue( numRows, TRACK_GRID_TRACK_WIDTH, 0 );
+ m_trackPropagationGrid->SetUnitValue( numRows, TRACK_GRID_TRACK_GAP, 0 );
+ m_trackPropagationGrid->SetUnitValue( numRows, TRACK_GRID_DELAY, 0 );
+ UpdateLayerNames();
+}
+
+
+void PANEL_SETUP_TUNING_PROFILE_INFO::OnRemoveTrackRow( wxCommandEvent& event )
+{
+ wxArrayInt selRows = m_trackPropagationGrid->GetSelectedRows();
+
+ if( selRows.size() == 1 )
+ m_trackPropagationGrid->DeleteRows( selRows[0] );
+}
+
+
+void PANEL_SETUP_TUNING_PROFILE_INFO::OnAddViaOverride( wxCommandEvent& event )
+{
+ const int numRows = m_viaOverrides->GetNumberRows();
+ m_viaOverrides->InsertRows( numRows );
+ m_viaOverrides->SetUnitValue( numRows, VIA_GRID_DELAY, 0 );
+ m_viaOverrides->SetCellValue( numRows, VIA_GRID_SIGNAL_LAYER_FROM, m_parentPanel->m_layerNames.front() );
+ m_viaOverrides->SetCellValue( numRows, VIA_GRID_SIGNAL_LAYER_TO, m_parentPanel->m_layerNames.back() );
+ m_viaOverrides->SetCellValue( numRows, VIA_GRID_VIA_LAYER_FROM, m_parentPanel->m_layerNames.front() );
+ m_viaOverrides->SetCellValue( numRows, VIA_GRID_VIA_LAYER_TO, m_parentPanel->m_layerNames.back() );
+ UpdateLayerNames();
+}
+
+
+void PANEL_SETUP_TUNING_PROFILE_INFO::OnRemoveViaOverride( wxCommandEvent& event )
+{
+ wxArrayInt selRows = m_viaOverrides->GetSelectedRows();
+
+ if( selRows.size() == 1 )
+ m_viaOverrides->DeleteRows( selRows[0] );
+}
+
+
+wxString PANEL_SETUP_TUNING_PROFILE_INFO::GetProfileName() const
+{
+ return m_name->GetValue();
+}
+
+
+double PANEL_SETUP_TUNING_PROFILE_INFO::calculateSkinDepth( const double aFreq, const double aMurc,
+ const double aSigma )
+{
+ return 1.0 / sqrt( M_PI * aFreq * aMurc * TRANSLINE_CALCULATIONS::MU0 * aSigma );
+}
+
+
+int PANEL_SETUP_TUNING_PROFILE_INFO::getStackupLayerId( const std::vector& aLayerList,
+ PCB_LAYER_ID aPcbLayerId )
+{
+ bool layerFound = false;
+ int layerStackupId = 0;
+
+ while( layerStackupId < static_cast( aLayerList.size() ) && !layerFound )
+ {
+ if( aLayerList.at( layerStackupId )->GetBrdLayerId() != aPcbLayerId )
+ ++layerStackupId;
+ else
+ layerFound = true;
+ }
+
+ if( !layerFound )
+ return -1;
+
+ return layerStackupId;
+}
+
+
+double PANEL_SETUP_TUNING_PROFILE_INFO::getTargetImpedance() const
+{
+ const wxString zStr = m_targetImpedance->GetValue();
+
+ double z;
+ if( !zStr.ToDouble( &z ) )
+ z = -1;
+
+ return z;
+}
+
+
+std::pair PANEL_SETUP_TUNING_PROFILE_INFO::calculateAverageDielectricConstants(
+ const std::vector& aStackupLayerList, const std::vector& dielectricLayerStackupIds,
+ const EDA_IU_SCALE& aIuScale )
+{
+ double e_r = 0.0;
+ double lossTangent = 0.0;
+ double totalHeight = 0.0;
+
+ for( int i : dielectricLayerStackupIds )
+ {
+ const BOARD_STACKUP_ITEM* layer = aStackupLayerList.at( i );
+ totalHeight += aIuScale.IUTomm( layer->GetThickness() ) / 1000.0;
+ }
+
+ for( int i : dielectricLayerStackupIds )
+ {
+ const BOARD_STACKUP_ITEM* layer = aStackupLayerList.at( i );
+ e_r += layer->GetEpsilonR() * aIuScale.IUTomm( layer->GetThickness() ) / ( 1000.0 * totalHeight );
+ lossTangent += layer->GetLossTangent() * aIuScale.IUTomm( layer->GetThickness() ) / ( 1000.0 * totalHeight );
+ }
+
+ return { e_r, lossTangent };
+}
+
+
+void PANEL_SETUP_TUNING_PROFILE_INFO::getDielectricDetails( const std::vector& aStackupLayerList,
+ const int aSignalLayerId, const int aReferenceLayerId,
+ std::vector& aDielectricLayerStackupIds,
+ double& aDielectricLayerHeight )
+{
+ const EDA_IU_SCALE& iuScale = m_parentPanel->m_unitsProvider->GetIuScale();
+ aDielectricLayerHeight = 0.0;
+
+ for( int i = std::min( aSignalLayerId, aReferenceLayerId ) + 1; i < std::max( aSignalLayerId, aReferenceLayerId );
+ ++i )
+ {
+ const BOARD_STACKUP_ITEM* layer = aStackupLayerList.at( i );
+
+ if( layer->GetType() != BS_ITEM_TYPE_DIELECTRIC )
+ continue;
+
+ if( !layer->HasEpsilonRValue() )
+ continue;
+
+ aDielectricLayerStackupIds.push_back( i );
+ aDielectricLayerHeight += iuScale.IUTomm( aStackupLayerList.at( i )->GetThickness() ) / 1000.0;
+ }
+}
+
+
+void PANEL_SETUP_TUNING_PROFILE_INFO::calculateTrackParametersForCell( const int aRow, const int aCol )
+{
+ // Determine if this is a stripline or microstrip geometry
+ const wxString signalLayerName = m_trackPropagationGrid->GetCellValue( aRow, TRACK_GRID_SIGNAL_LAYER );
+
+ if( !m_parentPanel->m_layerNamesToIDs.contains( signalLayerName ) )
+ return;
+
+ const PCB_LAYER_ID signalLayer = m_parentPanel->m_layerNamesToIDs.at( signalLayerName );
+ const TUNING_PROFILE::PROFILE_TYPE profileType = m_type->GetSelection() == 0
+ ? TUNING_PROFILE::PROFILE_TYPE::SINGLE
+ : TUNING_PROFILE::PROFILE_TYPE::DIFFERENTIAL;
+ const bool isMicrostrip = IsFrontLayer( signalLayer ) || IsBackLayer( signalLayer );
+ CalculationType calculationType;
+
+ switch( aCol )
+ {
+ case TRACK_GRID_TRACK_WIDTH: calculationType = CalculationType::WIDTH; break;
+ case TRACK_GRID_TRACK_GAP: calculationType = CalculationType::GAP; break;
+ case TRACK_GRID_DELAY: calculationType = CalculationType::DELAY; break;
+ default: calculationType = CalculationType::WIDTH; break;
+ }
+
+ if( profileType == TUNING_PROFILE::PROFILE_TYPE::DIFFERENTIAL ) // Differential tracks mode
+ {
+ int calculatedWidth = 0;
+ int calculatedGap = 0;
+ int calculatedDelay = 0;
+
+ std::tuple result;
+
+ if( isMicrostrip )
+ result = calculateDifferentialMicrostrip( aRow, calculationType );
+ else
+ result = calculateDifferentialStripline( aRow, calculationType );
+
+ calculatedWidth = std::get<0>( result );
+ calculatedGap = std::get<1>( result );
+ calculatedDelay = std::get<2>( result );
+
+ const bool widthOk = calculatedWidth > 0;
+ const bool gapOk = calculatedGap > 0;
+ const bool delayOk = calculatedDelay > 0;
+
+ if( !widthOk )
+ {
+ DisplayErrorMessage( m_parentPanel->m_dlg, _( "Could not compute track width" ) );
+ return;
+ }
+ else if( !gapOk )
+ {
+ DisplayErrorMessage( m_parentPanel->m_dlg, _( "Could not compute differential pair gap" ) );
+ return;
+ }
+ else if( !delayOk )
+ {
+ DisplayErrorMessage( m_parentPanel->m_dlg, _( "Could not compute track propagation delay" ) );
+ return;
+ }
+
+ if( calculationType == CalculationType::WIDTH )
+ {
+ m_trackPropagationGrid->SetUnitValue( aRow, TRACK_GRID_TRACK_WIDTH, calculatedWidth );
+ }
+ else if( calculationType == CalculationType::GAP )
+ {
+ m_trackPropagationGrid->SetUnitValue( aRow, TRACK_GRID_TRACK_GAP, calculatedGap );
+ }
+
+ m_trackPropagationGrid->SetUnitValue( aRow, TRACK_GRID_DELAY, calculatedDelay );
+ }
+ else // Single track mode
+ {
+ int calculatedWidth = 0;
+ int calculatedDelay = 0;
+
+ std::pair result;
+
+ if( isMicrostrip )
+ result = calculateSingleMicrostrip( aRow, calculationType );
+ else
+ result = calculateSingleStripline( aRow, calculationType );
+
+ calculatedWidth = result.first;
+ calculatedDelay = result.second;
+
+ const bool widthOk = calculatedWidth > 0;
+ const bool delayOk = calculatedDelay > 0;
+
+ if( !widthOk )
+ {
+ DisplayErrorMessage( m_parentPanel->m_dlg, _( "Could not compute track width" ) );
+ return;
+ }
+ else if( !delayOk )
+ {
+ DisplayErrorMessage( m_parentPanel->m_dlg, _( "Could not compute track propagation delay" ) );
+ return;
+ }
+
+ if( calculationType == CalculationType::WIDTH )
+ {
+ m_trackPropagationGrid->SetUnitValue( aRow, TRACK_GRID_TRACK_WIDTH, calculatedWidth );
+ }
+
+ m_trackPropagationGrid->SetUnitValue( aRow, TRACK_GRID_DELAY, calculatedDelay );
+ }
+}
+
+
+bool PANEL_SETUP_TUNING_PROFILE_INFO::ValidateProfile( const size_t aPageIndex )
+{
+ if( m_name->GetValue() == wxEmptyString )
+ {
+ m_parentPanel->m_tuningProfiles->SetSelection( aPageIndex );
+
+ const wxString msg = _( "Tuning profile must have a name" );
+ PAGED_DIALOG::GetDialog( m_parentPanel )->SetError( msg, this, m_name );
+ return false;
+ }
+
+ std::set layerNames;
+
+ for( int i = 0; i < m_trackPropagationGrid->GetNumberRows(); ++i )
+ {
+ wxString layerName = m_trackPropagationGrid->GetCellValue( i, TRACK_GRID_SIGNAL_LAYER );
+
+ if( layerNames.contains( layerName ) )
+ {
+ m_parentPanel->m_tuningProfiles->SetSelection( aPageIndex );
+
+ const wxString msg = _( "Duplicated signal layer configuration in tuning profile" );
+ PAGED_DIALOG::GetDialog( m_parentPanel )
+ ->SetError( msg, m_parentPanel, m_trackPropagationGrid, i, TRACK_GRID_SIGNAL_LAYER );
+ return false;
+ }
+
+ layerNames.insert( layerName );
+ }
+
+ return true;
+}
+
+
+/*****************************************************************************************************************
+ * SIMULATION / ANALYSIS PLUMBING
+ ****************************************************************************************************************/
+
+std::pair PANEL_SETUP_TUNING_PROFILE_INFO::calculateSingleMicrostrip( const int aRow,
+ CalculationType aCalculationType )
+{
+ const EDA_IU_SCALE& iuScale = m_parentPanel->m_unitsProvider->GetIuScale();
+
+ // Get the target impedance
+ const double targetZ = getTargetImpedance();
+
+ if( targetZ <= 0 )
+ return { 0, 0 };
+
+ // Get the signal layer information from the stackup
+ BOARD_STACKUP stackup = m_parentPanel->m_board->GetStackupOrDefault();
+ const std::vector& stackupLayerList = stackup.GetList();
+
+ const wxString signalLayerName = m_trackPropagationGrid->GetCellValue( aRow, TRACK_GRID_SIGNAL_LAYER );
+
+ if( !m_parentPanel->m_layerNamesToIDs.contains( signalLayerName ) )
+ return { 0, 0 };
+
+ const PCB_LAYER_ID signalLayer = m_parentPanel->m_layerNamesToIDs[signalLayerName];
+
+ // Microstrip can only be on an outer copper layer
+ if( signalLayer != F_Cu && signalLayer != B_Cu )
+ return { 0, 0 };
+
+ const int signalLayerStackupId = getStackupLayerId( stackupLayerList, signalLayer );
+
+ if( signalLayerStackupId == -1 )
+ return { 0, 0 };
+
+ const double signalLayerThickness =
+ iuScale.IUTomm( stackupLayerList.at( signalLayerStackupId )->GetThickness() ) / 1000.0;
+
+ // Get reference layer
+ wxString referenceLayerName;
+
+ if( signalLayer == F_Cu )
+ referenceLayerName = m_trackPropagationGrid->GetCellValue( aRow, TRACK_GRID_BOTTOM_REFERENCE );
+ else
+ referenceLayerName = m_trackPropagationGrid->GetCellValue( aRow, TRACK_GRID_TOP_REFERENCE );
+
+ if( !m_parentPanel->m_layerNamesToIDs.contains( referenceLayerName ) )
+ return { 0, 0 };
+
+ const PCB_LAYER_ID referenceLayer = m_parentPanel->m_layerNamesToIDs[referenceLayerName];
+ const int referenceLayerStackupId = getStackupLayerId( stackupLayerList, referenceLayer );
+
+ if( signalLayerStackupId == referenceLayerStackupId )
+ return { 0, 0 };
+
+ // Get the dielectric layers between signal and reference layers
+ std::vector dielectricLayerStackupIds;
+ double dielectricLayerHeight = 0;
+ getDielectricDetails( stackupLayerList, signalLayerStackupId, referenceLayerStackupId, dielectricLayerStackupIds,
+ dielectricLayerHeight );
+
+ if( dielectricLayerHeight <= 0.0 )
+ return { 0, 0 };
+
+ // Calculate geometric average of the dielectric materials
+ const auto [e_r, tan_d] =
+ calculateAverageDielectricConstants( stackupLayerList, dielectricLayerStackupIds, iuScale );
+
+ if( aCalculationType == CalculationType::WIDTH )
+ {
+ m_microstripCalc.SetParameter( TRANSLINE_PARAMETERS::PHYS_WIDTH, 0.001 );
+ }
+ else if( aCalculationType == CalculationType::DELAY )
+ {
+ const int widthInt = m_trackPropagationGrid->GetUnitValue( aRow, TRACK_GRID_TRACK_WIDTH );
+
+ const double width = iuScale.IUTomm( widthInt ) / 1000.0;
+ m_microstripCalc.SetParameter( TRANSLINE_PARAMETERS::PHYS_WIDTH, width );
+ }
+
+ // Run the synthesis or analysis
+ m_microstripCalc.SetParameter( TRANSLINE_PARAMETERS::SIGMA, 1.0 / RHO );
+ m_microstripCalc.SetParameter( TRANSLINE_PARAMETERS::EPSILON_EFF, 1.0 );
+ m_microstripCalc.SetParameter( TRANSLINE_PARAMETERS::SKIN_DEPTH, calculateSkinDepth( 1.0, 1.0, 1.0 / RHO ) );
+ m_microstripCalc.SetParameter( TRANSLINE_PARAMETERS::EPSILONR, e_r );
+ m_microstripCalc.SetParameter( TRANSLINE_PARAMETERS::H_T, 1e+20 );
+ m_microstripCalc.SetParameter( TRANSLINE_PARAMETERS::H, dielectricLayerHeight );
+ m_microstripCalc.SetParameter( TRANSLINE_PARAMETERS::T, signalLayerThickness );
+ m_microstripCalc.SetParameter( TRANSLINE_PARAMETERS::Z0, targetZ );
+ m_microstripCalc.SetParameter( TRANSLINE_PARAMETERS::FREQUENCY, 1000000000.0 );
+ m_microstripCalc.SetParameter( TRANSLINE_PARAMETERS::ROUGH, 0 );
+ m_microstripCalc.SetParameter( TRANSLINE_PARAMETERS::TAND, tan_d );
+ m_microstripCalc.SetParameter( TRANSLINE_PARAMETERS::PHYS_LEN, 10 );
+ m_microstripCalc.SetParameter( TRANSLINE_PARAMETERS::MUR, 1 );
+ m_microstripCalc.SetParameter( TRANSLINE_PARAMETERS::MURC, 1 );
+ m_microstripCalc.SetParameter( TRANSLINE_PARAMETERS::ANG_L, 1 );
+
+ if( aCalculationType == CalculationType::WIDTH )
+ m_microstripCalc.Synthesize( SYNTHESIZE_OPTS::DEFAULT );
+ else
+ m_microstripCalc.Analyse();
+
+ std::unordered_map>& results =
+ [this, aCalculationType]() -> decltype( m_microstripCalc.GetSynthesisResults() )
+ {
+ if( aCalculationType == CalculationType::WIDTH )
+ return m_microstripCalc.GetSynthesisResults();
+
+ return m_microstripCalc.GetAnalysisResults();
+ }();
+
+ if( results[TRANSLINE_PARAMETERS::PHYS_WIDTH].second != TRANSLINE_STATUS::OK )
+ return { 0, 0 };
+
+ if( results[TRANSLINE_PARAMETERS::UNIT_PROP_DELAY].second != TRANSLINE_STATUS::OK )
+ return { 0, 0 };
+
+ int width = static_cast( EDA_UNIT_UTILS::UI::FromUserUnit(
+ iuScale, EDA_UNITS::MM, results[TRANSLINE_PARAMETERS::PHYS_WIDTH].first * 1000.0 ) );
+ int propDelay = static_cast( EDA_UNIT_UTILS::UI::FromUserUnit(
+ iuScale, EDA_UNITS::PS_PER_CM, results[TRANSLINE_PARAMETERS::UNIT_PROP_DELAY].first ) );
+
+ return { width, propDelay };
+}
+
+
+std::pair PANEL_SETUP_TUNING_PROFILE_INFO::calculateSingleStripline( const int aRow,
+ CalculationType aCalculationType )
+{
+ const EDA_IU_SCALE& iuScale = m_parentPanel->m_unitsProvider->GetIuScale();
+
+ // Get the target impedance
+ const double targetZ = getTargetImpedance();
+
+ if( targetZ <= 0 )
+ return { 0, 0 };
+
+ // Get the signal layer information from the stackup
+ BOARD_STACKUP stackup = m_parentPanel->m_board->GetStackupOrDefault();
+ const std::vector& stackupLayerList = stackup.GetList();
+
+ const wxString signalLayerName = m_trackPropagationGrid->GetCellValue( aRow, TRACK_GRID_SIGNAL_LAYER );
+
+ if( !m_parentPanel->m_layerNamesToIDs.contains( signalLayerName ) )
+ return { 0, 0 };
+
+ const PCB_LAYER_ID signalLayer = m_parentPanel->m_layerNamesToIDs[signalLayerName];
+ const int signalLayerStackupId = getStackupLayerId( stackupLayerList, signalLayer );
+
+ if( signalLayerStackupId == -1 )
+ return { 0, 0 };
+
+ const double signalLayerThickness =
+ iuScale.IUTomm( stackupLayerList.at( signalLayerStackupId )->GetThickness() ) / 1000.0;
+
+ // Get top reference layer
+ const wxString topReferenceLayerName = m_trackPropagationGrid->GetCellValue( aRow, TRACK_GRID_TOP_REFERENCE );
+
+ if( !m_parentPanel->m_layerNamesToIDs.contains( topReferenceLayerName ) )
+ return { 0, 0 };
+
+ const PCB_LAYER_ID topReferenceLayer = m_parentPanel->m_layerNamesToIDs[topReferenceLayerName];
+ const int topReferenceLayerStackupId = getStackupLayerId( stackupLayerList, topReferenceLayer );
+
+ if( !IsCopperLayerLowerThan( signalLayer, topReferenceLayer ) )
+ return { 0, 0 };
+
+ // Get bottom reference layer
+ wxString bottomReferenceLayerName = m_trackPropagationGrid->GetCellValue( aRow, TRACK_GRID_BOTTOM_REFERENCE );
+
+ if( !m_parentPanel->m_layerNamesToIDs.contains( bottomReferenceLayerName ) )
+ return { 0, 0 };
+
+ const PCB_LAYER_ID bottomReferenceLayer = m_parentPanel->m_layerNamesToIDs[bottomReferenceLayerName];
+ const int bottomReferenceLayerStackupId = getStackupLayerId( stackupLayerList, bottomReferenceLayer );
+
+ if( !IsCopperLayerLowerThan( bottomReferenceLayer, signalLayer ) )
+ return { 0, 0 };
+
+ // Get the dielectric layers between signal and reference layers
+ std::vector topDielectricLayerStackupIds, bottomDielectricLayerStackupIds;
+ double topDielectricLayerHeight = 0.0;
+ double bottomDielectricLayerHeight = 0.0;
+
+ getDielectricDetails( stackupLayerList, signalLayerStackupId, topReferenceLayerStackupId,
+ topDielectricLayerStackupIds, topDielectricLayerHeight );
+ getDielectricDetails( stackupLayerList, signalLayerStackupId, bottomReferenceLayerStackupId,
+ bottomDielectricLayerStackupIds, bottomDielectricLayerHeight );
+
+ if( topDielectricLayerHeight <= 0.0 || bottomDielectricLayerHeight <= 0.0 )
+ return { 0, 0 };
+
+ // Calculate geometric average of the dielectric materials
+ std::vector allDielectricLayerStackupIds( topDielectricLayerStackupIds );
+ allDielectricLayerStackupIds.insert( allDielectricLayerStackupIds.end(), bottomDielectricLayerStackupIds.begin(),
+ bottomDielectricLayerStackupIds.end() );
+ const auto [e_r, tan_d] =
+ calculateAverageDielectricConstants( stackupLayerList, allDielectricLayerStackupIds, iuScale );
+
+ if( aCalculationType == CalculationType::WIDTH )
+ {
+ m_striplineCalc.SetParameter( TRANSLINE_PARAMETERS::PHYS_WIDTH, 0.001 );
+ }
+ else if( aCalculationType == CalculationType::DELAY )
+ {
+ const int widthInt = m_trackPropagationGrid->GetUnitValue( aRow, TRACK_GRID_TRACK_WIDTH );
+
+ const double width = iuScale.IUTomm( widthInt ) / 1000.0;
+ m_striplineCalc.SetParameter( TRANSLINE_PARAMETERS::PHYS_WIDTH, width );
+ }
+
+ // Run the synthesis
+ m_striplineCalc.SetParameter( TRANSLINE_PARAMETERS::SKIN_DEPTH, calculateSkinDepth( 1.0, 1.0, 1.0 / RHO ) );
+ m_striplineCalc.SetParameter( TRANSLINE_PARAMETERS::EPSILONR, e_r );
+ m_striplineCalc.SetParameter( TRANSLINE_PARAMETERS::T, signalLayerThickness );
+ m_striplineCalc.SetParameter( TRANSLINE_PARAMETERS::STRIPLINE_A, topDielectricLayerHeight );
+ m_striplineCalc.SetParameter( TRANSLINE_PARAMETERS::H,
+ topDielectricLayerHeight + signalLayerThickness + bottomDielectricLayerHeight );
+ m_striplineCalc.SetParameter( TRANSLINE_PARAMETERS::Z0, targetZ );
+ m_striplineCalc.SetParameter( TRANSLINE_PARAMETERS::PHYS_LEN, 1.0 );
+ m_striplineCalc.SetParameter( TRANSLINE_PARAMETERS::FREQUENCY, 1000000000.0 );
+ m_striplineCalc.SetParameter( TRANSLINE_PARAMETERS::TAND, tan_d );
+ m_striplineCalc.SetParameter( TRANSLINE_PARAMETERS::ANG_L, 1.0 );
+ m_striplineCalc.SetParameter( TRANSLINE_PARAMETERS::SIGMA, 1.0 / RHO );
+ m_striplineCalc.SetParameter( TRANSLINE_PARAMETERS::MURC, 1 );
+
+ if( aCalculationType == CalculationType::WIDTH )
+ m_striplineCalc.Synthesize( SYNTHESIZE_OPTS::DEFAULT );
+ else
+ m_striplineCalc.Analyse();
+
+ std::unordered_map>& results =
+ [this, aCalculationType]() -> decltype( m_striplineCalc.GetSynthesisResults() )
+ {
+ if( aCalculationType == CalculationType::WIDTH )
+ return m_striplineCalc.GetSynthesisResults();
+
+ return m_striplineCalc.GetAnalysisResults();
+ }();
+
+ if( results[TRANSLINE_PARAMETERS::PHYS_WIDTH].second != TRANSLINE_STATUS::OK )
+ return { 0, 0 };
+
+ if( results[TRANSLINE_PARAMETERS::UNIT_PROP_DELAY].second != TRANSLINE_STATUS::OK )
+ return { 0, 0 };
+
+ int width = static_cast( EDA_UNIT_UTILS::UI::FromUserUnit(
+ iuScale, EDA_UNITS::MM, results[TRANSLINE_PARAMETERS::PHYS_WIDTH].first * 1000.0 ) );
+ int propDelay = static_cast( EDA_UNIT_UTILS::UI::FromUserUnit(
+ iuScale, EDA_UNITS::PS_PER_CM, results[TRANSLINE_PARAMETERS::UNIT_PROP_DELAY].first ) );
+
+ return { width, propDelay };
+}
+
+
+std::tuple
+PANEL_SETUP_TUNING_PROFILE_INFO::calculateDifferentialMicrostrip( const int aRow, CalculationType aCalculationType )
+{
+ const EDA_IU_SCALE& iuScale = m_parentPanel->m_unitsProvider->GetIuScale();
+
+ // Get the target impedance
+ const double targetZ = getTargetImpedance();
+
+ if( targetZ <= 0 )
+ return { 0, 0, 0 };
+
+ // Get the signal layer information from the stackup
+ BOARD_STACKUP stackup = m_parentPanel->m_board->GetStackupOrDefault();
+ const std::vector& stackupLayerList = stackup.GetList();
+
+ const wxString signalLayerName = m_trackPropagationGrid->GetCellValue( aRow, TRACK_GRID_SIGNAL_LAYER );
+
+ if( !m_parentPanel->m_layerNamesToIDs.contains( signalLayerName ) )
+ return { 0, 0, 0 };
+
+ const PCB_LAYER_ID signalLayer = m_parentPanel->m_layerNamesToIDs[signalLayerName];
+
+ // Microstrip can only be on an outer copper layer
+ if( signalLayer != F_Cu && signalLayer != B_Cu )
+ return { 0, 0, 0 };
+
+ const int signalLayerStackupId = getStackupLayerId( stackupLayerList, signalLayer );
+
+ if( signalLayerStackupId == -1 )
+ return { 0, 0, 0 };
+
+ const double signalLayerThickness =
+ iuScale.IUTomm( stackupLayerList.at( signalLayerStackupId )->GetThickness() ) / 1000.0;
+
+ // Get reference layer
+ wxString referenceLayerName;
+
+ if( signalLayer == F_Cu )
+ referenceLayerName = m_trackPropagationGrid->GetCellValue( aRow, TRACK_GRID_BOTTOM_REFERENCE );
+ else
+ referenceLayerName = m_trackPropagationGrid->GetCellValue( aRow, TRACK_GRID_TOP_REFERENCE );
+
+ if( !m_parentPanel->m_layerNamesToIDs.contains( referenceLayerName ) )
+ return { 0, 0, 0 };
+
+ const PCB_LAYER_ID referenceLayer = m_parentPanel->m_layerNamesToIDs[referenceLayerName];
+ const int referenceLayerStackupId = getStackupLayerId( stackupLayerList, referenceLayer );
+
+ if( signalLayerStackupId == referenceLayerStackupId )
+ return { 0, 0, 0 };
+
+ // Get the dielectric layers between signal and reference layers
+ std::vector dielectricLayerStackupIds;
+ double dielectricLayerHeight = 0;
+ getDielectricDetails( stackupLayerList, signalLayerStackupId, referenceLayerStackupId, dielectricLayerStackupIds,
+ dielectricLayerHeight );
+
+ if( dielectricLayerHeight <= 0.0 )
+ return { 0, 0, 0 };
+
+ // Calculate geometric average of the dielectric materials
+ const auto [e_r, tan_d] =
+ calculateAverageDielectricConstants( stackupLayerList, dielectricLayerStackupIds, iuScale );
+
+ // Get tuning parameters
+ double width = 0.0;
+ double gap = 0.0;
+
+ const std::optional widthOpt = m_trackPropagationGrid->GetOptionalUnitValue( aRow, TRACK_GRID_TRACK_WIDTH );
+ const std::optional gapOpt = m_trackPropagationGrid->GetOptionalUnitValue( aRow, TRACK_GRID_TRACK_GAP );
+
+ if( aCalculationType == CalculationType::WIDTH )
+ {
+ if( !gapOpt )
+ return { 0, 0, 0 };
+
+ gap = iuScale.IUTomm( gapOpt.value() ) / 1000.0;
+ }
+ else if( aCalculationType == CalculationType::GAP )
+ {
+ if( !widthOpt )
+ return { 0, 0, 0 };
+
+ width = iuScale.IUTomm( widthOpt.value() ) / 1000.0;
+ }
+ else if( aCalculationType == CalculationType::DELAY )
+ {
+ if( !widthOpt || !gapOpt )
+ return { 0, 0, 0 };
+
+ width = iuScale.IUTomm( widthOpt.value() ) / 1000.0;
+ gap = iuScale.IUTomm( gapOpt.value() ) / 1000.0;
+ }
+
+ // Run the synthesis
+ m_coupledMicrostripCalc.SetParameter( TRANSLINE_PARAMETERS::Z0_E, targetZ / 2.0 );
+ m_coupledMicrostripCalc.SetParameter( TRANSLINE_PARAMETERS::Z0_O, targetZ / 2.0 );
+ m_coupledMicrostripCalc.SetParameter( TRANSLINE_PARAMETERS::Z_DIFF, targetZ );
+ m_coupledMicrostripCalc.SetParameter( TRANSLINE_PARAMETERS::PHYS_WIDTH, width );
+ m_coupledMicrostripCalc.SetParameter( TRANSLINE_PARAMETERS::PHYS_S, gap );
+ m_coupledMicrostripCalc.SetParameter( TRANSLINE_PARAMETERS::EPSILONR, e_r );
+ m_coupledMicrostripCalc.SetParameter( TRANSLINE_PARAMETERS::PHYS_LEN, 10 );
+ m_coupledMicrostripCalc.SetParameter( TRANSLINE_PARAMETERS::H, dielectricLayerHeight );
+ m_coupledMicrostripCalc.SetParameter( TRANSLINE_PARAMETERS::T, signalLayerThickness );
+ m_coupledMicrostripCalc.SetParameter( TRANSLINE_PARAMETERS::H_T, 1e+20 );
+ m_coupledMicrostripCalc.SetParameter( TRANSLINE_PARAMETERS::FREQUENCY, 1000000000.0 );
+ m_coupledMicrostripCalc.SetParameter( TRANSLINE_PARAMETERS::MURC, 1 );
+ m_coupledMicrostripCalc.SetParameter( TRANSLINE_PARAMETERS::SKIN_DEPTH, calculateSkinDepth( 1.0, 1.0, 1.0 / RHO ) );
+ m_coupledMicrostripCalc.SetParameter( TRANSLINE_PARAMETERS::SIGMA, 1.0 / RHO );
+ m_coupledMicrostripCalc.SetParameter( TRANSLINE_PARAMETERS::ROUGH, 0 );
+ m_coupledMicrostripCalc.SetParameter( TRANSLINE_PARAMETERS::TAND, tan_d );
+ m_coupledMicrostripCalc.SetParameter( TRANSLINE_PARAMETERS::ANG_L, 1 );
+
+ switch( aCalculationType )
+ {
+ case CalculationType::WIDTH: m_coupledMicrostripCalc.Synthesize( SYNTHESIZE_OPTS::FIX_SPACING ); break;
+ case CalculationType::GAP: m_coupledMicrostripCalc.Synthesize( SYNTHESIZE_OPTS::FIX_WIDTH ); break;
+ case CalculationType::DELAY: m_coupledMicrostripCalc.Analyse(); break;
+ }
+
+ std::unordered_map>& results =
+ [this, aCalculationType]() -> decltype( m_microstripCalc.GetSynthesisResults() )
+ {
+ if( aCalculationType == CalculationType::WIDTH || aCalculationType == CalculationType::GAP )
+ return m_coupledMicrostripCalc.GetSynthesisResults();
+
+ return m_coupledMicrostripCalc.GetAnalysisResults();
+ }();
+
+ if( results[TRANSLINE_PARAMETERS::PHYS_WIDTH].second != TRANSLINE_STATUS::OK )
+ return { 0, 0, 0 };
+
+ if( results[TRANSLINE_PARAMETERS::PHYS_S].second != TRANSLINE_STATUS::OK )
+ return { 0, 0, 0 };
+
+ if( results[TRANSLINE_PARAMETERS::UNIT_PROP_DELAY_ODD].second != TRANSLINE_STATUS::OK )
+ return { 0, 0, 0 };
+
+ int calcWidth = static_cast( EDA_UNIT_UTILS::UI::FromUserUnit(
+ iuScale, EDA_UNITS::MM, results[TRANSLINE_PARAMETERS::PHYS_WIDTH].first * 1000.0 ) );
+ int calcGap = static_cast( EDA_UNIT_UTILS::UI::FromUserUnit(
+ iuScale, EDA_UNITS::MM, results[TRANSLINE_PARAMETERS::PHYS_S].first * 1000.0 ) );
+ int propDelay = static_cast( EDA_UNIT_UTILS::UI::FromUserUnit(
+ iuScale, EDA_UNITS::PS_PER_CM, results[TRANSLINE_PARAMETERS::UNIT_PROP_DELAY_ODD].first ) );
+
+ return { calcWidth, calcGap, propDelay };
+}
+
+
+std::tuple
+PANEL_SETUP_TUNING_PROFILE_INFO::calculateDifferentialStripline( const int aRow, CalculationType aCalculationType )
+{
+ const EDA_IU_SCALE& iuScale = m_parentPanel->m_unitsProvider->GetIuScale();
+
+ // Get the target impedance
+ const double targetZ = getTargetImpedance();
+
+ if( targetZ <= 0 )
+ return { 0, 0, 0 };
+
+ // Get the signal layer information from the stackup
+ BOARD_STACKUP stackup = m_parentPanel->m_board->GetStackupOrDefault();
+ const std::vector& stackupLayerList = stackup.GetList();
+
+ const wxString signalLayerName = m_trackPropagationGrid->GetCellValue( aRow, TRACK_GRID_SIGNAL_LAYER );
+
+ if( !m_parentPanel->m_layerNamesToIDs.contains( signalLayerName ) )
+ return { 0, 0, 0 };
+
+ const PCB_LAYER_ID signalLayer = m_parentPanel->m_layerNamesToIDs[signalLayerName];
+ const int signalLayerStackupId = getStackupLayerId( stackupLayerList, signalLayer );
+
+ if( signalLayerStackupId == -1 )
+ return { 0, 0, 0 };
+
+ const double signalLayerThickness =
+ iuScale.IUTomm( stackupLayerList.at( signalLayerStackupId )->GetThickness() ) / 1000.0;
+
+ // Get top reference layer
+ const wxString topReferenceLayerName = m_trackPropagationGrid->GetCellValue( aRow, TRACK_GRID_TOP_REFERENCE );
+
+ if( !m_parentPanel->m_layerNamesToIDs.contains( topReferenceLayerName ) )
+ return { 0, 0, 0 };
+
+ const PCB_LAYER_ID topReferenceLayer = m_parentPanel->m_layerNamesToIDs[topReferenceLayerName];
+ const int topReferenceLayerStackupId = getStackupLayerId( stackupLayerList, topReferenceLayer );
+
+ if( !IsCopperLayerLowerThan( signalLayer, topReferenceLayer ) )
+ return { 0, 0, 0 };
+
+ // Get bottom reference layer
+ wxString bottomReferenceLayerName = m_trackPropagationGrid->GetCellValue( aRow, TRACK_GRID_BOTTOM_REFERENCE );
+
+ if( !m_parentPanel->m_layerNamesToIDs.contains( bottomReferenceLayerName ) )
+ return { 0, 0, 0 };
+
+ const PCB_LAYER_ID bottomReferenceLayer = m_parentPanel->m_layerNamesToIDs[bottomReferenceLayerName];
+ const int bottomReferenceLayerStackupId = getStackupLayerId( stackupLayerList, bottomReferenceLayer );
+
+ if( !IsCopperLayerLowerThan( bottomReferenceLayer, signalLayer ) )
+ return { 0, 0, 0 };
+
+ // Get the dielectric layers between signal and reference layers
+ std::vector topDielectricLayerStackupIds, bottomDielectricLayerStackupIds;
+ double topDielectricLayerHeight = 0.0;
+ double bottomDielectricLayerHeight = 0.0;
+
+ getDielectricDetails( stackupLayerList, signalLayerStackupId, topReferenceLayerStackupId,
+ topDielectricLayerStackupIds, topDielectricLayerHeight );
+ getDielectricDetails( stackupLayerList, signalLayerStackupId, bottomReferenceLayerStackupId,
+ bottomDielectricLayerStackupIds, bottomDielectricLayerHeight );
+
+ if( topDielectricLayerHeight <= 0.0 || bottomDielectricLayerHeight <= 0.0 )
+ return { 0, 0, 0 };
+
+ // Calculate geometric average of the dielectric materials
+ std::vector allDielectricLayerStackupIds( topDielectricLayerStackupIds );
+ allDielectricLayerStackupIds.insert( allDielectricLayerStackupIds.end(), bottomDielectricLayerStackupIds.begin(),
+ bottomDielectricLayerStackupIds.end() );
+ const auto [e_r, tan_d] =
+ calculateAverageDielectricConstants( stackupLayerList, allDielectricLayerStackupIds, iuScale );
+
+ // Get tuning parameters
+ double width = 0.0;
+ double gap = 0.0;
+
+ const std::optional widthOpt = m_trackPropagationGrid->GetOptionalUnitValue( aRow, TRACK_GRID_TRACK_WIDTH );
+ const std::optional gapOpt = m_trackPropagationGrid->GetOptionalUnitValue( aRow, TRACK_GRID_TRACK_GAP );
+
+ if( aCalculationType == CalculationType::WIDTH )
+ {
+ if( !gapOpt )
+ return { 0, 0, 0 };
+
+ gap = iuScale.IUTomm( gapOpt.value() ) / 1000.0;
+ }
+ else if( aCalculationType == CalculationType::GAP )
+ {
+ if( !widthOpt )
+ return { 0, 0, 0 };
+
+ width = iuScale.IUTomm( widthOpt.value() ) / 1000.0;
+ }
+ else if( aCalculationType == CalculationType::DELAY )
+ {
+ if( !widthOpt || !gapOpt )
+ return { 0, 0, 0 };
+
+ width = iuScale.IUTomm( widthOpt.value() ) / 1000.0;
+ gap = iuScale.IUTomm( gapOpt.value() ) / 1000.0;
+ }
+
+ // Run the synthesis
+ m_coupledStriplineCalc.SetParameter( TRANSLINE_PARAMETERS::Z0_E, targetZ / 2.0 );
+ m_coupledStriplineCalc.SetParameter( TRANSLINE_PARAMETERS::Z0_O, targetZ / 2.0 );
+ m_coupledStriplineCalc.SetParameter( TRANSLINE_PARAMETERS::Z_DIFF, targetZ );
+ m_coupledStriplineCalc.SetParameter( TRANSLINE_PARAMETERS::PHYS_WIDTH, width );
+ m_coupledStriplineCalc.SetParameter( TRANSLINE_PARAMETERS::PHYS_S, gap );
+ m_coupledStriplineCalc.SetParameter( TRANSLINE_PARAMETERS::T, signalLayerThickness );
+ m_coupledStriplineCalc.SetParameter( TRANSLINE_PARAMETERS::H, topDielectricLayerHeight + signalLayerThickness
+ + bottomDielectricLayerHeight );
+ m_coupledStriplineCalc.SetParameter( TRANSLINE_PARAMETERS::EPSILONR, e_r );
+ m_coupledStriplineCalc.SetParameter( TRANSLINE_PARAMETERS::SKIN_DEPTH, calculateSkinDepth( 1.0, 1.0, 1.0 / RHO ) );
+ m_coupledStriplineCalc.SetParameter( TRANSLINE_PARAMETERS::PHYS_LEN, 1.0 );
+ m_coupledStriplineCalc.SetParameter( TRANSLINE_PARAMETERS::FREQUENCY, 1000000000.0 );
+ m_coupledStriplineCalc.SetParameter( TRANSLINE_PARAMETERS::ANG_L, 1.0 );
+ m_coupledStriplineCalc.SetParameter( TRANSLINE_PARAMETERS::SIGMA, 1.0 / RHO );
+ m_coupledStriplineCalc.SetParameter( TRANSLINE_PARAMETERS::MURC, 1 );
+
+ switch( aCalculationType )
+ {
+ case CalculationType::WIDTH: m_coupledStriplineCalc.Synthesize( SYNTHESIZE_OPTS::FIX_SPACING ); break;
+ case CalculationType::GAP: m_coupledStriplineCalc.Synthesize( SYNTHESIZE_OPTS::FIX_WIDTH ); break;
+ case CalculationType::DELAY: m_coupledStriplineCalc.Analyse(); break;
+ }
+
+ std::unordered_map>& results =
+ [this, aCalculationType]() -> decltype( m_coupledStriplineCalc.GetSynthesisResults() )
+ {
+ if( aCalculationType == CalculationType::WIDTH || aCalculationType == CalculationType::GAP )
+ return m_coupledStriplineCalc.GetSynthesisResults();
+
+ return m_coupledStriplineCalc.GetAnalysisResults();
+ }();
+
+ if( results[TRANSLINE_PARAMETERS::PHYS_WIDTH].second != TRANSLINE_STATUS::OK )
+ return { 0, 0, 0 };
+
+ if( results[TRANSLINE_PARAMETERS::PHYS_S].second != TRANSLINE_STATUS::OK )
+ return { 0, 0, 0 };
+
+ if( results[TRANSLINE_PARAMETERS::UNIT_PROP_DELAY_ODD].second != TRANSLINE_STATUS::OK )
+ return { 0, 0, 0 };
+
+ int calcWidth = static_cast( EDA_UNIT_UTILS::UI::FromUserUnit(
+ iuScale, EDA_UNITS::MM, results[TRANSLINE_PARAMETERS::PHYS_WIDTH].first * 1000.0 ) );
+ int calcGap = static_cast( EDA_UNIT_UTILS::UI::FromUserUnit(
+ iuScale, EDA_UNITS::MM, results[TRANSLINE_PARAMETERS::PHYS_S].first * 1000.0 ) );
+ int propDelay = static_cast( EDA_UNIT_UTILS::UI::FromUserUnit(
+ iuScale, EDA_UNITS::PS_PER_CM, results[TRANSLINE_PARAMETERS::UNIT_PROP_DELAY_ODD].first ) );
+
+ return { calcWidth, calcGap, propDelay };
+}
diff --git a/pcbnew/dialogs/panel_setup_tuning_profile_info.h b/pcbnew/dialogs/panel_setup_tuning_profile_info.h
new file mode 100644
index 0000000000..e06809da98
--- /dev/null
+++ b/pcbnew/dialogs/panel_setup_tuning_profile_info.h
@@ -0,0 +1,184 @@
+/*
+* This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef PANEL_SETUP_TUNING_PROFILE_INFO_H
+#define PANEL_SETUP_TUNING_PROFILE_INFO_H
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+class PANEL_SETUP_TUNING_PROFILES;
+
+class PANEL_SETUP_TUNING_PROFILE_INFO : public PANEL_SETUP_TUNING_PROFILE_INFO_BASE
+{
+public:
+ PANEL_SETUP_TUNING_PROFILE_INFO( wxWindow* aParentWindow, PANEL_SETUP_TUNING_PROFILES* parentPanel );
+
+ ~PANEL_SETUP_TUNING_PROFILE_INFO() override;
+
+ /// Updates the displayed layer names in all grids
+ void UpdateLayerNames();
+
+ /// Loads the given profile in to the panel
+ void LoadProfile( const TUNING_PROFILE& aProfile );
+
+ /// Saves the panel to the given profile
+ TUNING_PROFILE GetProfile() const;
+
+ /// Updates the parent notebook control
+ void OnProfileNameChanged( wxCommandEvent& event ) override;
+
+ /// Changes between Single and Differential profiles
+ void OnChangeProfileType( wxCommandEvent& event ) override;
+
+ /// Adds a row to the track propagation grid
+ void OnAddTrackRow( wxCommandEvent& event ) override;
+
+ /// Removes a row from the track propagation grid
+ void OnRemoveTrackRow( wxCommandEvent& event ) override;
+
+ /// Adds a via override row
+ void OnAddViaOverride( wxCommandEvent& event ) override;
+
+ /// Removes a via override row
+ void OnRemoveViaOverride( wxCommandEvent& event ) override;
+
+ /// Gets the name of this profile
+ wxString GetProfileName() const;
+
+ /// Validate this panel's data
+ bool ValidateProfile( size_t aPageIndex );
+
+private:
+ enum TRACK_GRID_COLS
+ {
+ TRACK_GRID_SIGNAL_LAYER = 0,
+ TRACK_GRID_TOP_REFERENCE,
+ TRACK_GRID_BOTTOM_REFERENCE,
+ TRACK_GRID_TRACK_WIDTH,
+ TRACK_GRID_TRACK_GAP,
+ TRACK_GRID_DELAY
+ };
+
+ enum VIA_GRID_COLS
+ {
+ VIA_GRID_SIGNAL_LAYER_FROM = 0,
+ VIA_GRID_SIGNAL_LAYER_TO,
+ VIA_GRID_VIA_LAYER_FROM,
+ VIA_GRID_VIA_LAYER_TO,
+ VIA_GRID_DELAY
+ };
+
+ enum class CalculationType
+ {
+ WIDTH,
+ GAP,
+ DELAY
+ };
+
+ /// Initialises all controls on the panel
+ void initPanel();
+
+ /// Set up the widths of all grid columns
+ void setColumnWidths();
+
+ /// Calculates the track width or delay for the given propagation grid row
+ /// @returns pair of (width, unit propagation delay) in IU
+ std::pair calculateSingleMicrostrip( const int aRow, CalculationType aCalculationType );
+
+ /// Calculates the track width or delay for the given propagation grid row
+ /// @returns pair of (width, unit propagation delay) in IU
+ std::pair calculateSingleStripline( const int aRow, CalculationType aCalculationType );
+
+ /// Calculates the track width, pair gap, or delay for the given propagation grid row
+ /// @returns tuple of (width, diff pair gap, unit propagation delay) in IU
+ std::tuple calculateDifferentialMicrostrip( int aRow, CalculationType aCalculationType );
+
+ /// Calculates the track width, pair gap, or delay for the given propagation grid row
+ /// @returns tuple of (width, diff pair gap, unit propagation delay) in IU
+ std::tuple calculateDifferentialStripline( int aRow, CalculationType aCalculationType );
+
+ /// Calculate the effective skin depth for the given parameters
+ static double calculateSkinDepth( double aFreq, double aMurc, double aSigma );
+
+ /// Gets the index in to the layer list for the given layer.
+ /// @returns -1 if not found
+ static int getStackupLayerId( const std::vector& aLayerList, PCB_LAYER_ID aPcbLayerId );
+
+ /**
+ * Calculates the geometric average of the dielectric material properties. Note: This is a poor approximation as the
+ * electric field distribution is not equal across the dielectrics. However, it will do as an approximation before
+ * we have a field solver integrated.
+ *
+ * @returns (E_r, LossTangent) pair
+ */
+ static std::pair
+ calculateAverageDielectricConstants( const std::vector& aStackupLayerList,
+ const std::vector& dielectricLayerStackupIds,
+ const EDA_IU_SCALE& aIuScale );
+
+ /// Gets the dielectric layers and heights for dielectrics between the two given copper layer IDs
+ void getDielectricDetails( const std::vector& aStackupLayerList, int aSignalLayerId,
+ int aReferenceLayerId, std::vector& aDielectricLayerStackupIds,
+ double& aDielectricLayerHeight );
+
+ /// Gets the target impedance for the profile
+ double getTargetImpedance() const;
+
+ /// Calculates the required track parameters for the given track parameters grid row and col
+ void calculateTrackParametersForCell( int aRow, int aCol );
+
+ /// Sets the panel display for the given tuning type
+ void onChangeProfileType( TUNING_PROFILE::PROFILE_TYPE aType ) const;
+
+ /// The parent setup panel
+ PANEL_SETUP_TUNING_PROFILES* m_parentPanel;
+
+ /// Units for global via propagation unit delay
+ UNIT_BINDER m_viaPropagationUnits;
+
+ /// Calculator for single microstrip parameters
+ MICROSTRIP m_microstripCalc;
+
+ /// Calculator for single stripline parameters
+ STRIPLINE m_striplineCalc;
+
+ /// Calculator for coupled (differential) microstrip parameters
+ COUPLED_MICROSTRIP m_coupledMicrostripCalc;
+
+ /// Calculator for coupled (differential) stripline parameters
+ COUPLED_STRIPLINE m_coupledStriplineCalc;
+
+ // Electrical resistivity or specific electrical resistance of copper (ohm*meter)
+ static constexpr double RHO = 1.72e-8;
+};
+
+
+#endif //PANEL_SETUP_TUNING_PROFILE_INFO_H
diff --git a/pcbnew/dialogs/panel_setup_tuning_profile_info_base.cpp b/pcbnew/dialogs/panel_setup_tuning_profile_info_base.cpp
new file mode 100644
index 0000000000..61be0c75c7
--- /dev/null
+++ b/pcbnew/dialogs/panel_setup_tuning_profile_info_base.cpp
@@ -0,0 +1,270 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version 4.2.1-0-g80c4cb6)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO *NOT* EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#include "widgets/std_bitmap_button.h"
+#include "widgets/wx_grid.h"
+
+#include "panel_setup_tuning_profile_info_base.h"
+
+///////////////////////////////////////////////////////////////////////////
+
+PANEL_SETUP_TUNING_PROFILE_INFO_BASE::PANEL_SETUP_TUNING_PROFILE_INFO_BASE( wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style, const wxString& name ) : wxPanel( parent, id, pos, size, style, name )
+{
+ wxFlexGridSizer* fgSizer1;
+ fgSizer1 = new wxFlexGridSizer( 3, 1, 0, 0 );
+ fgSizer1->AddGrowableCol( 0 );
+ fgSizer1->AddGrowableRow( 2 );
+ fgSizer1->SetFlexibleDirection( wxBOTH );
+ fgSizer1->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_ALL );
+
+ wxFlexGridSizer* fgSizer2;
+ fgSizer2 = new wxFlexGridSizer( 1, 9, 0, 0 );
+ fgSizer2->AddGrowableCol( 2 );
+ fgSizer2->AddGrowableCol( 5 );
+ fgSizer2->SetFlexibleDirection( wxHORIZONTAL );
+ fgSizer2->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_ALL );
+
+ m_nameLabel = new wxStaticText( this, wxID_ANY, _("Name:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_nameLabel->Wrap( -1 );
+ fgSizer2->Add( m_nameLabel, 0, wxALL, 5 );
+
+ m_name = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ fgSizer2->Add( m_name, 0, wxALL|wxEXPAND, 5 );
+
+
+ fgSizer2->Add( 0, 0, 1, wxEXPAND, 5 );
+
+ m_typeLabel = new wxStaticText( this, wxID_ANY, _("Type:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_typeLabel->Wrap( -1 );
+ fgSizer2->Add( m_typeLabel, 0, wxALL, 5 );
+
+ wxString m_typeChoices[] = { _("Single"), _("Differential") };
+ int m_typeNChoices = sizeof( m_typeChoices ) / sizeof( wxString );
+ m_type = new wxChoice( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_typeNChoices, m_typeChoices, 0 );
+ m_type->SetSelection( 0 );
+ fgSizer2->Add( m_type, 0, wxALL, 5 );
+
+
+ fgSizer2->Add( 0, 0, 1, wxEXPAND, 5 );
+
+ m_targetImpedanceLabel = new wxStaticText( this, wxID_ANY, _("Target Impedance:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_targetImpedanceLabel->Wrap( -1 );
+ fgSizer2->Add( m_targetImpedanceLabel, 0, wxALL, 5 );
+
+ m_targetImpedance = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ #ifdef __WXGTK__
+ if ( !m_targetImpedance->HasFlag( wxTE_MULTILINE ) )
+ {
+ m_targetImpedance->SetMaxLength( 15 );
+ }
+ #else
+ m_targetImpedance->SetMaxLength( 15 );
+ #endif
+ fgSizer2->Add( m_targetImpedance, 0, wxALL|wxEXPAND, 5 );
+
+ m_ohmsLabel = new wxStaticText( this, wxID_ANY, _("ohms"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_ohmsLabel->Wrap( -1 );
+ fgSizer2->Add( m_ohmsLabel, 0, wxALL|wxRIGHT, 5 );
+
+
+ fgSizer1->Add( fgSizer2, 1, wxEXPAND, 5 );
+
+ wxGridBagSizer* gbSizer1;
+ gbSizer1 = new wxGridBagSizer( 0, 0 );
+ gbSizer1->SetFlexibleDirection( wxBOTH );
+ gbSizer1->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
+
+ m_enableDrcGeneration = new wxCheckBox( this, wxID_ANY, _("Generate Net Class DRC Rules"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_enableDrcGeneration->SetValue(true);
+ gbSizer1->Add( m_enableDrcGeneration, wxGBPosition( 0, 0 ), wxGBSpan( 1, 1 ), wxALL, 5 );
+
+ m_enableDelayTuning = new wxCheckBox( this, wxID_ANY, _("Enable Time Domain Tuning"), wxDefaultPosition, wxDefaultSize, 0 );
+ gbSizer1->Add( m_enableDelayTuning, wxGBPosition( 0, 1 ), wxGBSpan( 1, 1 ), wxALL, 5 );
+
+ m_staticline1 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
+ gbSizer1->Add( m_staticline1, wxGBPosition( 1, 0 ), wxGBSpan( 1, 2 ), wxEXPAND | wxALL, 5 );
+
+
+ gbSizer1->AddGrowableCol( 0 );
+
+ fgSizer1->Add( gbSizer1, 1, wxEXPAND, 5 );
+
+ m_splitter1 = new wxSplitterWindow( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSP_3DSASH );
+ m_splitter1->Connect( wxEVT_IDLE, wxIdleEventHandler( PANEL_SETUP_TUNING_PROFILE_INFO_BASE::m_splitter1OnIdle ), NULL, this );
+
+ m_panel3 = new wxPanel( m_splitter1, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
+ wxStaticBoxSizer* sbSizer2;
+ sbSizer2 = new wxStaticBoxSizer( new wxStaticBox( m_panel3, wxID_ANY, _("Track Propagation") ), wxVERTICAL );
+
+ wxFlexGridSizer* fgSizer4;
+ fgSizer4 = new wxFlexGridSizer( 0, 1, 0, 0 );
+ fgSizer4->AddGrowableCol( 0 );
+ fgSizer4->AddGrowableRow( 0 );
+ fgSizer4->SetFlexibleDirection( wxBOTH );
+ fgSizer4->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
+
+ m_trackPropagationGrid = new WX_GRID( sbSizer2->GetStaticBox(), wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 );
+
+ // Grid
+ m_trackPropagationGrid->CreateGrid( 0, 6 );
+ m_trackPropagationGrid->EnableEditing( true );
+ m_trackPropagationGrid->EnableGridLines( true );
+ m_trackPropagationGrid->EnableDragGridSize( false );
+ m_trackPropagationGrid->SetMargins( 0, 0 );
+
+ // Columns
+ m_trackPropagationGrid->AutoSizeColumns();
+ m_trackPropagationGrid->EnableDragColMove( false );
+ m_trackPropagationGrid->EnableDragColSize( true );
+ m_trackPropagationGrid->SetColLabelValue( 0, _("Signal Layer") );
+ m_trackPropagationGrid->SetColLabelValue( 1, _("Top Reference") );
+ m_trackPropagationGrid->SetColLabelValue( 2, _("Bottom Reference") );
+ m_trackPropagationGrid->SetColLabelValue( 3, _("Track Width") );
+ m_trackPropagationGrid->SetColLabelValue( 4, _("Diff Pair Gap") );
+ m_trackPropagationGrid->SetColLabelValue( 5, _("Unit Delay") );
+ m_trackPropagationGrid->SetColLabelAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
+
+ // Rows
+ m_trackPropagationGrid->EnableDragRowSize( true );
+ m_trackPropagationGrid->SetRowLabelSize( 0 );
+ m_trackPropagationGrid->SetRowLabelAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
+
+ // Label Appearance
+
+ // Cell Defaults
+ m_trackPropagationGrid->SetDefaultCellAlignment( wxALIGN_LEFT, wxALIGN_TOP );
+ fgSizer4->Add( m_trackPropagationGrid, 0, wxALL|wxEXPAND, 5 );
+
+ wxBoxSizer* bSizer9;
+ bSizer9 = new wxBoxSizer( wxHORIZONTAL );
+
+ m_addTrackPropogationLayer = new STD_BITMAP_BUTTON( sbSizer2->GetStaticBox(), wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW|0 );
+ bSizer9->Add( m_addTrackPropogationLayer, 0, wxBOTTOM|wxLEFT|wxTOP, 5 );
+
+
+ bSizer9->Add( 20, 0, 1, 0, 5 );
+
+ m_deleteTrackPropogationLayer = new STD_BITMAP_BUTTON( sbSizer2->GetStaticBox(), wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW|0 );
+ bSizer9->Add( m_deleteTrackPropogationLayer, 0, wxBOTTOM|wxLEFT|wxTOP, 5 );
+
+
+ fgSizer4->Add( bSizer9, 1, 0, 5 );
+
+
+ sbSizer2->Add( fgSizer4, 1, wxEXPAND, 5 );
+
+
+ m_panel3->SetSizer( sbSizer2 );
+ m_panel3->Layout();
+ sbSizer2->Fit( m_panel3 );
+ m_panel4 = new wxPanel( m_splitter1, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
+ wxStaticBoxSizer* sbSizer3;
+ sbSizer3 = new wxStaticBoxSizer( new wxStaticBox( m_panel4, wxID_ANY, _("Via Propagation") ), wxVERTICAL );
+
+ wxFlexGridSizer* fgSizer3;
+ fgSizer3 = new wxFlexGridSizer( 3, 1, 0, 0 );
+ fgSizer3->AddGrowableCol( 0 );
+ fgSizer3->AddGrowableRow( 1 );
+ fgSizer3->SetFlexibleDirection( wxBOTH );
+ fgSizer3->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
+
+ wxBoxSizer* bSizer8;
+ bSizer8 = new wxBoxSizer( wxHORIZONTAL );
+
+ m_viaPropagationSpeedLabel = new wxStaticText( sbSizer3->GetStaticBox(), wxID_ANY, _("Via Propagation Speed:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_viaPropagationSpeedLabel->Wrap( -1 );
+ bSizer8->Add( m_viaPropagationSpeedLabel, 0, wxALL, 5 );
+
+ m_viaPropagationSpeed = new wxTextCtrl( sbSizer3->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ bSizer8->Add( m_viaPropagationSpeed, 0, wxALL, 5 );
+
+ m_viaPropSpeedUnits = new wxStaticText( sbSizer3->GetStaticBox(), wxID_ANY, _("ps/cm"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_viaPropSpeedUnits->Wrap( -1 );
+ bSizer8->Add( m_viaPropSpeedUnits, 0, wxALL, 5 );
+
+
+ bSizer8->Add( 50, 0, 1, wxEXPAND, 5 );
+
+ m_viaDelayOverridesLabel = new wxStaticText( sbSizer3->GetStaticBox(), wxID_ANY, _("Via Delay Overrides:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_viaDelayOverridesLabel->Wrap( -1 );
+ bSizer8->Add( m_viaDelayOverridesLabel, 0, wxALL, 5 );
+
+
+ fgSizer3->Add( bSizer8, 1, 0, 5 );
+
+ m_viaOverrides = new WX_GRID( sbSizer3->GetStaticBox(), wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 );
+
+ // Grid
+ m_viaOverrides->CreateGrid( 0, 5 );
+ m_viaOverrides->EnableEditing( true );
+ m_viaOverrides->EnableGridLines( true );
+ m_viaOverrides->EnableDragGridSize( false );
+ m_viaOverrides->SetMargins( 0, 0 );
+
+ // Columns
+ m_viaOverrides->AutoSizeColumns();
+ m_viaOverrides->EnableDragColMove( false );
+ m_viaOverrides->EnableDragColSize( true );
+ m_viaOverrides->SetColLabelValue( 0, _("Signal Layer From") );
+ m_viaOverrides->SetColLabelValue( 1, _("Signal Layer To") );
+ m_viaOverrides->SetColLabelValue( 2, _("Via Layer From") );
+ m_viaOverrides->SetColLabelValue( 3, _("Via Layer To") );
+ m_viaOverrides->SetColLabelValue( 4, _("Delay") );
+ m_viaOverrides->SetColLabelAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
+
+ // Rows
+ m_viaOverrides->EnableDragRowSize( true );
+ m_viaOverrides->SetRowLabelSize( 0 );
+ m_viaOverrides->SetRowLabelAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
+
+ // Label Appearance
+
+ // Cell Defaults
+ m_viaOverrides->SetDefaultCellAlignment( wxALIGN_LEFT, wxALIGN_TOP );
+ fgSizer3->Add( m_viaOverrides, 0, wxALL|wxEXPAND, 5 );
+
+ wxBoxSizer* bSizer91;
+ bSizer91 = new wxBoxSizer( wxHORIZONTAL );
+
+ m_addViaPropagationOverride = new STD_BITMAP_BUTTON( sbSizer3->GetStaticBox(), wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW|0 );
+ bSizer91->Add( m_addViaPropagationOverride, 0, wxBOTTOM|wxLEFT, 5 );
+
+
+ bSizer91->Add( 20, 0, 1, wxEXPAND, 5 );
+
+ m_removeViaPropagationOverride = new STD_BITMAP_BUTTON( sbSizer3->GetStaticBox(), wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW|0 );
+ bSizer91->Add( m_removeViaPropagationOverride, 0, wxBOTTOM|wxLEFT, 5 );
+
+
+ fgSizer3->Add( bSizer91, 1, 0, 5 );
+
+
+ sbSizer3->Add( fgSizer3, 1, wxEXPAND, 5 );
+
+
+ m_panel4->SetSizer( sbSizer3 );
+ m_panel4->Layout();
+ sbSizer3->Fit( m_panel4 );
+ m_splitter1->SplitHorizontally( m_panel3, m_panel4, 0 );
+ fgSizer1->Add( m_splitter1, 1, wxEXPAND, 5 );
+
+
+ this->SetSizer( fgSizer1 );
+ this->Layout();
+
+ // Connect Events
+ m_name->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( PANEL_SETUP_TUNING_PROFILE_INFO_BASE::OnProfileNameChanged ), NULL, this );
+ m_type->Connect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( PANEL_SETUP_TUNING_PROFILE_INFO_BASE::OnChangeProfileType ), NULL, this );
+ m_addTrackPropogationLayer->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_SETUP_TUNING_PROFILE_INFO_BASE::OnAddTrackRow ), NULL, this );
+ m_deleteTrackPropogationLayer->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_SETUP_TUNING_PROFILE_INFO_BASE::OnRemoveTrackRow ), NULL, this );
+ m_addViaPropagationOverride->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_SETUP_TUNING_PROFILE_INFO_BASE::OnAddViaOverride ), NULL, this );
+ m_removeViaPropagationOverride->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_SETUP_TUNING_PROFILE_INFO_BASE::OnRemoveViaOverride ), NULL, this );
+}
+
+PANEL_SETUP_TUNING_PROFILE_INFO_BASE::~PANEL_SETUP_TUNING_PROFILE_INFO_BASE()
+{
+}
diff --git a/pcbnew/dialogs/panel_setup_tuning_profile_info_base.fbp b/pcbnew/dialogs/panel_setup_tuning_profile_info_base.fbp
new file mode 100644
index 0000000000..b6aab0116f
--- /dev/null
+++ b/pcbnew/dialogs/panel_setup_tuning_profile_info_base.fbp
@@ -0,0 +1,1791 @@
+
+
+
+
+ C++
+ ;
+ 0
+ connect
+ none
+
+
+ 0
+ 1
+ res
+ UTF-8
+ panel_setup_tuning_profile_info_base
+ 6000
+ 1
+ 1
+ UI
+ PANEL_SETUP_TUNING_PROFILE_INFO_BASE
+ .
+ 0
+ source_name
+ 1
+ 0
+ source_name
+
+ 1
+ 1
+ 1
+ 0
+ 0
+
+ 0
+ wxAUI_MGR_DEFAULT
+
+
+ 1
+ 0
+ 1
+ impl_virtual
+
+
+ 0
+ wxID_ANY
+
+
+ PANEL_SETUP_TUNING_PROFILE_INFO_BASE
+
+ 719,506
+ ; ; forward_declare
+
+ 0
+
+
+ wxTAB_TRAVERSAL
+
+ 1
+ wxBOTH
+ 0
+ 2
+ 0
+
+ fgSizer1
+ wxFLEX_GROWMODE_ALL
+ none
+ 3
+ 0
+
+ 5
+ wxEXPAND
+ 1
+
+ 9
+ wxHORIZONTAL
+ 2,5
+
+ 0
+
+ fgSizer2
+ wxFLEX_GROWMODE_ALL
+ none
+ 1
+ 0
+
+ 5
+ wxALL
+ 0
+
+ 1
+ 1
+ 1
+ 1
+ 0
+
+ 0
+ 0
+
+
+
+ 1
+ 0
+ 1
+
+ 1
+ 0
+ Dock
+ 0
+ Left
+ 0
+ 1
+
+ 1
+
+ 0
+ 0
+ wxID_ANY
+ Name:
+ 0
+
+ 0
+
+
+ 0
+
+ 1
+ m_nameLabel
+ 1
+
+
+ protected
+ 1
+
+ Resizable
+ 1
+
+
+ ; ; forward_declare
+ 0
+
+
+
+
+ -1
+
+
+
+ 5
+ wxALL|wxEXPAND
+ 0
+
+ 1
+ 1
+ 1
+ 1
+ 0
+
+ 0
+ 0
+
+
+
+ 1
+ 0
+ 1
+
+ 1
+ 0
+ Dock
+ 0
+ Left
+ 0
+ 1
+
+ 1
+
+ 0
+ 0
+ wxID_ANY
+
+ 0
+
+ 0
+
+ 0
+
+ 1
+ m_name
+ 1
+
+
+ protected
+ 1
+
+ Resizable
+ 1
+
+
+ ; ; forward_declare
+ 0
+
+
+ wxFILTER_NONE
+ wxDefaultValidator
+
+
+
+
+
+ OnProfileNameChanged
+
+
+
+ 5
+ wxEXPAND
+ 1
+
+ 0
+ protected
+ 0
+
+
+
+ 5
+ wxALL
+ 0
+
+ 1
+ 1
+ 1
+ 1
+ 0
+
+ 0
+ 0
+
+
+
+ 1
+ 0
+ 1
+
+ 1
+ 0
+ Dock
+ 0
+ Left
+ 0
+ 1
+
+ 1
+
+ 0
+ 0
+ wxID_ANY
+ Type:
+ 0
+
+ 0
+
+
+ 0
+
+ 1
+ m_typeLabel
+ 1
+
+
+ protected
+ 1
+
+ Resizable
+ 1
+
+
+ ; ; forward_declare
+ 0
+
+
+
+
+ -1
+
+
+
+ 5
+ wxALL
+ 0
+
+ 1
+ 1
+ 1
+ 1
+ 0
+
+ 0
+ 0
+
+
+
+ 1
+ 0
+ "Single" "Differential"
+ 1
+
+ 1
+ 0
+ Dock
+ 0
+ Left
+ 0
+ 1
+
+ 1
+
+ 0
+ 0
+ wxID_ANY
+
+ 0
+
+
+ 0
+
+ 1
+ m_type
+ 1
+
+
+ protected
+ 1
+
+ Resizable
+ 0
+ 1
+
+
+ ; ; forward_declare
+ 0
+
+
+ wxFILTER_NONE
+ wxDefaultValidator
+
+
+
+
+ OnChangeProfileType
+
+
+
+ 5
+ wxEXPAND
+ 1
+
+ 0
+ protected
+ 0
+
+
+
+ 5
+ wxALL
+ 0
+
+ 1
+ 1
+ 1
+ 1
+ 0
+
+ 0
+ 0
+
+
+
+ 1
+ 0
+ 1
+
+ 1
+ 0
+ Dock
+ 0
+ Left
+ 0
+ 1
+
+ 1
+
+ 0
+ 0
+ wxID_ANY
+ Target Impedance:
+ 0
+
+ 0
+
+
+ 0
+
+ 1
+ m_targetImpedanceLabel
+ 1
+
+
+ protected
+ 1
+
+ Resizable
+ 1
+
+
+ ; ; forward_declare
+ 0
+
+
+
+
+ -1
+
+
+
+ 5
+ wxALL|wxEXPAND
+ 0
+
+ 1
+ 1
+ 1
+ 1
+ 0
+
+ 0
+ 0
+
+
+
+ 1
+ 0
+ 1
+
+ 1
+ 0
+ Dock
+ 0
+ Left
+ 0
+ 1
+
+ 1
+
+ 0
+ 0
+ wxID_ANY
+
+ 0
+
+ 15
+
+ 0
+
+ 1
+ m_targetImpedance
+ 1
+
+
+ protected
+ 1
+
+ Resizable
+ 1
+
+
+ ; ; forward_declare
+ 0
+
+
+ wxFILTER_NONE
+ wxDefaultValidator
+
+
+
+
+
+
+
+
+ 5
+ wxALL|wxRIGHT
+ 0
+
+ 1
+ 1
+ 1
+ 1
+ 0
+
+ 0
+ 0
+
+
+
+ 1
+ 0
+ 1
+
+ 1
+ 0
+ Dock
+ 0
+ Left
+ 0
+ 1
+
+ 1
+
+ 0
+ 0
+ wxID_ANY
+ ohms
+ 0
+
+ 0
+
+
+ 0
+
+ 1
+ m_ohmsLabel
+ 1
+
+
+ protected
+ 1
+
+ Resizable
+ 1
+
+
+ ; ; forward_declare
+ 0
+
+
+
+
+ -1
+
+
+
+
+
+ 5
+ wxEXPAND
+ 1
+
+
+ wxBOTH
+ 0
+
+ 0
+
+ gbSizer1
+ wxFLEX_GROWMODE_SPECIFIED
+ none
+ 0
+
+ 5
+ 1
+ 0
+ wxALL
+ 0
+ 1
+
+ 1
+ 1
+ 1
+ 1
+ 0
+
+ 0
+ 0
+
+
+
+ 1
+ 0
+ 1
+ 1
+
+ 1
+ 0
+ Dock
+ 0
+ Left
+ 0
+ 1
+
+ 1
+
+ 0
+ 0
+ wxID_ANY
+ Generate Net Class DRC Rules
+
+ 0
+
+
+ 0
+
+ 1
+ m_enableDrcGeneration
+ 1
+
+
+ protected
+ 1
+
+ Resizable
+ 1
+
+
+ ; ; forward_declare
+ 0
+
+
+ wxFILTER_NONE
+ wxDefaultValidator
+
+
+
+
+
+
+
+ 5
+ 1
+ 1
+ wxALL
+ 0
+ 1
+
+ 1
+ 1
+ 1
+ 1
+ 0
+
+ 0
+ 0
+
+
+
+ 1
+ 0
+ 0
+ 1
+
+ 1
+ 0
+ Dock
+ 0
+ Left
+ 0
+ 1
+
+ 1
+
+ 0
+ 0
+ wxID_ANY
+ Enable Time Domain Tuning
+
+ 0
+
+
+ 0
+
+ 1
+ m_enableDelayTuning
+ 1
+
+
+ protected
+ 1
+
+ Resizable
+ 1
+
+
+ ; ; forward_declare
+ 0
+
+
+ wxFILTER_NONE
+ wxDefaultValidator
+
+
+
+
+
+
+
+ 5
+ 2
+ 0
+ wxEXPAND | wxALL
+ 1
+ 1
+
+ 1
+ 1
+ 1
+ 1
+ 0
+
+ 0
+ 0
+
+
+
+ 1
+ 0
+ 1
+
+ 1
+ 0
+ Dock
+ 0
+ Left
+ 0
+ 1
+
+ 1
+
+ 0
+ 0
+ wxID_ANY
+
+ 0
+
+
+ 0
+
+ 1
+ m_staticline1
+ 1
+
+
+ protected
+ 1
+
+ Resizable
+ 1
+
+ wxLI_HORIZONTAL
+ ; ; forward_declare
+ 0
+
+
+
+
+
+
+
+
+
+ 5
+ wxEXPAND
+ 1
+
+ 1
+ 1
+ 1
+ 1
+ 0
+
+ 0
+ 0
+
+
+
+ 1
+ 0
+ 1
+
+ 1
+ 0
+ Dock
+ 0
+ Left
+ 0
+ 1
+
+ 1
+
+ 0
+ 0
+ wxID_ANY
+
+ 0
+
+ 0
+
+ 0
+
+ 1
+ m_splitter1
+ 1
+
+
+ protected
+ 1
+
+ Resizable
+ 0.0
+ 0
+ -1
+ 1
+
+ wxSPLIT_HORIZONTAL
+ wxSP_3DSASH
+ ; ; forward_declare
+ 0
+
+
+
+
+
+
+ 1
+ 1
+ 1
+ 1
+ 0
+
+ 0
+ 0
+
+
+
+ 1
+ 0
+ 1
+
+ 1
+ 0
+ Dock
+ 0
+ Left
+ 0
+ 1
+
+ 1
+
+ 0
+ 0
+ wxID_ANY
+
+ 0
+
+
+ 0
+
+ 1
+ m_panel3
+ 1
+
+
+ protected
+ 1
+
+ Resizable
+ 1
+
+ ; ; forward_declare
+ 0
+
+
+
+ wxTAB_TRAVERSAL
+
+ wxID_ANY
+ Track Propagation
+
+ sbSizer2
+ wxVERTICAL
+ 1
+ none
+
+ 5
+ wxEXPAND
+ 1
+
+ 1
+ wxBOTH
+ 0
+ 0
+ 0
+
+ fgSizer4
+ wxFLEX_GROWMODE_SPECIFIED
+ none
+ 0
+ 0
+
+ 5
+ wxALL|wxEXPAND
+ 0
+
+ 1
+ 1
+ 1
+ 1
+ 0
+
+ 0
+ 0
+ 1
+ 0
+
+
+
+ 1
+
+
+ wxALIGN_LEFT
+
+ wxALIGN_TOP
+ 0
+ 1
+ wxALIGN_CENTER
+
+ "Signal Layer" "Top Reference" "Bottom Reference" "Track Width" "Diff Pair Gap" "Unit Delay"
+ wxALIGN_CENTER
+ 6
+
+
+ 0
+ 0
+ Dock
+ 0
+ Left
+ 0
+ 0
+ 1
+ 0
+ 1
+ 1
+ 1
+
+ 1
+
+
+ 1
+ 0
+ 0
+ wxID_ANY
+
+
+
+ 0
+ 0
+
+ 0
+
+
+ 0
+
+ 1
+ m_trackPropagationGrid
+ 1
+
+
+ protected
+ 1
+
+ Resizable
+ wxALIGN_CENTER
+ 0
+
+ wxALIGN_CENTER
+
+ 0
+ 1
+
+ WX_GRID; widgets/wx_grid.h; forward_declare
+ 0
+
+
+
+
+
+
+
+ 5
+
+ 1
+
+
+ bSizer9
+ wxHORIZONTAL
+ none
+
+ 5
+ wxBOTTOM|wxLEFT|wxTOP
+ 0
+
+ 1
+ 1
+ 1
+ 1
+ 0
+
+ 0
+ 0
+ 0
+
+
+
+
+ 1
+ 0
+ 1
+
+ 1
+
+ 0
+ 0
+
+ Dock
+ 0
+ Left
+ 0
+ 1
+
+ 1
+
+
+ 0
+ 0
+ wxID_ANY
+ MyButton
+
+ 0
+
+ 0
+
+
+ 0
+
+ 1
+ m_addTrackPropogationLayer
+ 1
+
+
+ protected
+ 1
+
+
+
+ Resizable
+ 1
+
+
+ STD_BITMAP_BUTTON; widgets/std_bitmap_button.h; forward_declare
+ 0
+
+
+ wxFILTER_NONE
+ wxDefaultValidator
+
+
+
+
+ OnAddTrackRow
+
+
+
+ 5
+
+ 1
+
+ 0
+ protected
+ 20
+
+
+
+ 5
+ wxBOTTOM|wxLEFT|wxTOP
+ 0
+
+ 1
+ 1
+ 1
+ 1
+ 0
+
+ 0
+ 0
+ 0
+
+
+
+
+ 1
+ 0
+ 1
+
+ 1
+
+ 0
+ 0
+
+ Dock
+ 0
+ Left
+ 0
+ 1
+
+ 1
+
+
+ 0
+ 0
+ wxID_ANY
+ MyButton
+
+ 0
+
+ 0
+
+
+ 0
+
+ 1
+ m_deleteTrackPropogationLayer
+ 1
+
+
+ protected
+ 1
+
+
+
+ Resizable
+ 1
+
+
+ STD_BITMAP_BUTTON; widgets/std_bitmap_button.h; forward_declare
+ 0
+
+
+ wxFILTER_NONE
+ wxDefaultValidator
+
+
+
+
+ OnRemoveTrackRow
+
+
+
+
+
+
+
+
+
+
+
+ 1
+ 1
+ 1
+ 1
+ 0
+
+ 0
+ 0
+
+
+
+ 1
+ 0
+ 1
+
+ 1
+ 0
+ Dock
+ 0
+ Left
+ 0
+ 1
+
+ 1
+
+ 0
+ 0
+ wxID_ANY
+
+ 0
+
+
+ 0
+
+ 1
+ m_panel4
+ 1
+
+
+ protected
+ 1
+
+ Resizable
+ 1
+
+ ; ; forward_declare
+ 0
+
+
+
+ wxTAB_TRAVERSAL
+
+ wxID_ANY
+ Via Propagation
+
+ sbSizer3
+ wxVERTICAL
+ 1
+ none
+
+ 5
+ wxEXPAND
+ 1
+
+ 1
+ wxBOTH
+ 0
+ 1
+ 0
+
+ fgSizer3
+ wxFLEX_GROWMODE_SPECIFIED
+ none
+ 3
+ 0
+
+ 5
+
+ 1
+
+
+ bSizer8
+ wxHORIZONTAL
+ none
+
+ 5
+ wxALL
+ 0
+
+ 1
+ 1
+ 1
+ 1
+ 0
+
+ 0
+ 0
+
+
+
+ 1
+ 0
+ 1
+
+ 1
+ 0
+ Dock
+ 0
+ Left
+ 0
+ 1
+
+ 1
+
+ 0
+ 0
+ wxID_ANY
+ Via Propagation Speed:
+ 0
+
+ 0
+
+
+ 0
+
+ 1
+ m_viaPropagationSpeedLabel
+ 1
+
+
+ protected
+ 1
+
+ Resizable
+ 1
+
+
+ ; ; forward_declare
+ 0
+
+
+
+
+ -1
+
+
+
+ 5
+ wxALL
+ 0
+
+ 1
+ 1
+ 1
+ 1
+ 0
+
+ 0
+ 0
+
+
+
+ 1
+ 0
+ 1
+
+ 1
+ 0
+ Dock
+ 0
+ Left
+ 0
+ 1
+
+ 1
+
+ 0
+ 0
+ wxID_ANY
+
+ 0
+
+ 0
+
+ 0
+
+ 1
+ m_viaPropagationSpeed
+ 1
+
+
+ protected
+ 1
+
+ Resizable
+ 1
+
+
+ ; ; forward_declare
+ 0
+
+
+ wxFILTER_NONE
+ wxDefaultValidator
+
+
+
+
+
+
+
+
+ 5
+ wxALL
+ 0
+
+ 1
+ 1
+ 1
+ 1
+ 0
+
+ 0
+ 0
+
+
+
+ 1
+ 0
+ 1
+
+ 1
+ 0
+ Dock
+ 0
+ Left
+ 0
+ 1
+
+ 1
+
+ 0
+ 0
+ wxID_ANY
+ ps/cm
+ 0
+
+ 0
+
+
+ 0
+
+ 1
+ m_viaPropSpeedUnits
+ 1
+
+
+ protected
+ 1
+
+ Resizable
+ 1
+
+
+ ; ; forward_declare
+ 0
+
+
+
+
+ -1
+
+
+
+ 5
+ wxEXPAND
+ 1
+
+ 0
+ protected
+ 50
+
+
+
+ 5
+ wxALL
+ 0
+
+ 1
+ 1
+ 1
+ 1
+ 0
+
+ 0
+ 0
+
+
+
+ 1
+ 0
+ 1
+
+ 1
+ 0
+ Dock
+ 0
+ Left
+ 0
+ 1
+
+ 1
+
+ 0
+ 0
+ wxID_ANY
+ Via Delay Overrides:
+ 0
+
+ 0
+
+
+ 0
+
+ 1
+ m_viaDelayOverridesLabel
+ 1
+
+
+ protected
+ 1
+
+ Resizable
+ 1
+
+
+ ; ; forward_declare
+ 0
+
+
+
+
+ -1
+
+
+
+
+
+ 5
+ wxALL|wxEXPAND
+ 0
+
+ 1
+ 1
+ 1
+ 1
+ 0
+
+ 0
+ 0
+ 1
+ 0
+
+
+
+ 1
+
+
+ wxALIGN_LEFT
+
+ wxALIGN_TOP
+ 0
+ 1
+ wxALIGN_CENTER
+
+ "Signal Layer From" "Signal Layer To" "Via Layer From" "Via Layer To" "Delay"
+ wxALIGN_CENTER
+ 5
+
+
+ 1
+ 0
+ Dock
+ 0
+ Left
+ 0
+ 0
+ 1
+ 0
+ 1
+ 1
+ 1
+
+ 1
+
+
+ 1
+ 0
+ 0
+ wxID_ANY
+
+
+
+ 0
+ 0
+
+ 0
+
+
+ 0
+
+ 1
+ m_viaOverrides
+ 1
+
+
+ protected
+ 1
+
+ Resizable
+ wxALIGN_CENTER
+ 0
+
+ wxALIGN_CENTER
+
+ 0
+ 1
+
+ WX_GRID; widgets/wx_grid.h; forward_declare
+ 0
+
+
+
+
+
+
+
+ 5
+
+ 1
+
+
+ bSizer91
+ wxHORIZONTAL
+ none
+
+ 5
+ wxBOTTOM|wxLEFT
+ 0
+
+ 1
+ 1
+ 1
+ 1
+ 0
+
+ 0
+ 0
+ 0
+
+
+
+
+ 1
+ 0
+ 1
+
+ 1
+
+ 0
+ 0
+
+ Dock
+ 0
+ Left
+ 0
+ 1
+
+ 1
+
+
+ 0
+ 0
+ wxID_ANY
+ MyButton
+
+ 0
+
+ 0
+
+
+ 0
+
+ 1
+ m_addViaPropagationOverride
+ 1
+
+
+ protected
+ 1
+
+
+
+ Resizable
+ 1
+
+
+ STD_BITMAP_BUTTON; widgets/std_bitmap_button.h; forward_declare
+ 0
+
+
+ wxFILTER_NONE
+ wxDefaultValidator
+
+
+
+
+ OnAddViaOverride
+
+
+
+ 5
+ wxEXPAND
+ 1
+
+ 0
+ protected
+ 20
+
+
+
+ 5
+ wxBOTTOM|wxLEFT
+ 0
+
+ 1
+ 1
+ 1
+ 1
+ 0
+
+ 0
+ 0
+ 0
+
+
+
+
+ 1
+ 0
+ 1
+
+ 1
+
+ 0
+ 0
+
+ Dock
+ 0
+ Left
+ 0
+ 1
+
+ 1
+
+
+ 0
+ 0
+ wxID_ANY
+ MyButton
+
+ 0
+
+ 0
+
+
+ 0
+
+ 1
+ m_removeViaPropagationOverride
+ 1
+
+
+ protected
+ 1
+
+
+
+ Resizable
+ 1
+
+
+ STD_BITMAP_BUTTON; widgets/std_bitmap_button.h; forward_declare
+ 0
+
+
+ wxFILTER_NONE
+ wxDefaultValidator
+
+
+
+
+ OnRemoveViaOverride
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/pcbnew/dialogs/panel_setup_tuning_profile_info_base.h b/pcbnew/dialogs/panel_setup_tuning_profile_info_base.h
new file mode 100644
index 0000000000..5a10f3dd29
--- /dev/null
+++ b/pcbnew/dialogs/panel_setup_tuning_profile_info_base.h
@@ -0,0 +1,94 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version 4.2.1-0-g80c4cb6)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO *NOT* EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#pragma once
+
+#include
+#include
+#include
+class STD_BITMAP_BUTTON;
+class WX_GRID;
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+///////////////////////////////////////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////////////////
+/// Class PANEL_SETUP_TUNING_PROFILE_INFO_BASE
+///////////////////////////////////////////////////////////////////////////////
+class PANEL_SETUP_TUNING_PROFILE_INFO_BASE : public wxPanel
+{
+ private:
+
+ protected:
+ wxStaticText* m_nameLabel;
+ wxTextCtrl* m_name;
+ wxStaticText* m_typeLabel;
+ wxChoice* m_type;
+ wxStaticText* m_targetImpedanceLabel;
+ wxTextCtrl* m_targetImpedance;
+ wxStaticText* m_ohmsLabel;
+ wxCheckBox* m_enableDrcGeneration;
+ wxCheckBox* m_enableDelayTuning;
+ wxStaticLine* m_staticline1;
+ wxSplitterWindow* m_splitter1;
+ wxPanel* m_panel3;
+ WX_GRID* m_trackPropagationGrid;
+ STD_BITMAP_BUTTON* m_addTrackPropogationLayer;
+ STD_BITMAP_BUTTON* m_deleteTrackPropogationLayer;
+ wxPanel* m_panel4;
+ wxStaticText* m_viaPropagationSpeedLabel;
+ wxTextCtrl* m_viaPropagationSpeed;
+ wxStaticText* m_viaPropSpeedUnits;
+ wxStaticText* m_viaDelayOverridesLabel;
+ WX_GRID* m_viaOverrides;
+ STD_BITMAP_BUTTON* m_addViaPropagationOverride;
+ STD_BITMAP_BUTTON* m_removeViaPropagationOverride;
+
+ // Virtual event handlers, override them in your derived class
+ virtual void OnProfileNameChanged( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnChangeProfileType( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnAddTrackRow( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnRemoveTrackRow( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnAddViaOverride( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnRemoveViaOverride( wxCommandEvent& event ) { event.Skip(); }
+
+
+ public:
+
+ PANEL_SETUP_TUNING_PROFILE_INFO_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 719,506 ), long style = wxTAB_TRAVERSAL, const wxString& name = wxEmptyString );
+
+ ~PANEL_SETUP_TUNING_PROFILE_INFO_BASE();
+
+ void m_splitter1OnIdle( wxIdleEvent& )
+ {
+ m_splitter1->SetSashPosition( 0 );
+ m_splitter1->Disconnect( wxEVT_IDLE, wxIdleEventHandler( PANEL_SETUP_TUNING_PROFILE_INFO_BASE::m_splitter1OnIdle ), NULL, this );
+ }
+
+};
+
diff --git a/pcbnew/dialogs/panel_setup_tuning_profiles.cpp b/pcbnew/dialogs/panel_setup_tuning_profiles.cpp
new file mode 100644
index 0000000000..dacd5c9d89
--- /dev/null
+++ b/pcbnew/dialogs/panel_setup_tuning_profiles.cpp
@@ -0,0 +1,200 @@
+/*
+* This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include