30#include <drc_rules_lexer.h>
46#include <unordered_map>
48using CODE_MAP = std::unordered_map<DRC_RULE_EDITOR_CONSTRAINT_NAME, const char*>;
49using REVERSE_CODE_MAP = std::unordered_map<wxString, DRC_RULE_EDITOR_CONSTRAINT_NAME, wxStringHash, wxStringEqual>;
61 {
HOLE_SIZE, DRC_RULES_LEXER::TokenName( DRCRULE_T::T_hole_size ) },
73 {
ROUTING_WIDTH, DRC_RULES_LEXER::TokenName( DRCRULE_T::T_track_width ) },
83 for(
const auto& [type, code] :
sCodeMap )
84 map.emplace( wxString::FromUTF8( code ), type );
90 static std::vector<DRC_RULE_EDITOR_UTILS::RuleConverter> converters;
127 case LENGTH_CONSTRAINT:
return DRC_RULES_LEXER::TokenName( DRCRULE_T::T_length );
128 case SKEW_CONSTRAINT:
return DRC_RULES_LEXER::TokenName( DRCRULE_T::T_skew );
143 static bool initialized =
false;
150 [](
const std::shared_ptr<DRC_RULE>& aRule ) -> std::shared_ptr<DRC_RE_BASE_CONSTRAINT_DATA>
152 if( aRule->m_Constraints.empty() )
return nullptr;
154 const auto& constraint = aRule->m_Constraints[0];
157 if( code.IsEmpty() )
return nullptr;
165 double val = constraint.GetValue().Min() / 1000000.0;
167 data->SetRuleName( aRule->m_Name );
168 data->SetNumericInputValue( val );
169 data->SetConstraintCode( code );
174 auto data = std::make_shared<DRC_RE_BOOL_INPUT_CONSTRAINT_DATA>( 0, 0,
true, aRule->m_Name );
175 data->SetConstraintCode( code );
178 else if( code ==
"track_width" )
180 double minW = constraint.GetValue().Min() / 1000000.0;
181 double optW = constraint.GetValue().Opt() / 1000000.0;
182 double maxW = constraint.GetValue().Max() / 1000000.0;
186 tol = std::max( optW - minW, maxW - optW );
189 std::make_shared<DRC_RE_ROUTING_WIDTH_CONSTRAINT_DATA>( 0, 0, aRule->m_Name, optW, tol );
190 data->SetConstraintCode( code );
199 [](
const std::shared_ptr<DRC_RULE>& aRule ) -> std::shared_ptr<DRC_RE_BASE_CONSTRAINT_DATA>
204 if( diaConstraint && holeConstraint )
206 double minDia = diaConstraint->GetValue().Min() / 1000000.0;
207 double maxDia = diaConstraint->GetValue().Max() / 1000000.0;
209 double minDrill = holeConstraint->GetValue().Min() / 1000000.0;
210 double maxDrill = holeConstraint->GetValue().Max() / 1000000.0;
214 if( aRule->m_Condition )
216 wxString expr = aRule->m_Condition->GetExpression();
218 if( expr.Contains( wxS(
"'Micro'" ) ) )
220 else if( expr.Contains( wxS(
"'Through'" ) ) )
222 else if( expr.Contains( wxS(
"'Blind'" ) ) )
224 else if( expr.Contains( wxS(
"'Buried'" ) ) )
228 auto data = std::make_shared<DRC_RE_VIA_STYLE_CONSTRAINT_DATA>( 0, 0, aRule->m_Name, minDia, maxDia,
229 minDrill, maxDrill, viaType );
230 data->SetConstraintCode(
"via_style" );
240 auto it =
sCodeMap.find( aConstraintType );
242 return wxString::FromUTF8( it->second );
283 switch( aConstraintType )
285 default:
return false;
292 switch( aConstraintType )
322 int* aErrorCount, wxString* aValidationMessage )
325 aTextCtrl->SetValidator( validator );
327 if( !aTextCtrl->Validate() )
336 *aValidationMessage +=
338 wxString::Format(
_(
"%s should not be empty." ), aLabel ) );
345 *aErrorCount, wxString::Format(
_(
"The value of %s must be a valid number." ), aLabel ) );
352 *aErrorCount, wxString::Format(
_(
"The value of %s must be greater than 0." ), aLabel ) );
364 int* aErrorCount, wxString* aValidationMessage )
367 aTextCtrl->SetValidator( validator );
369 if( !aTextCtrl->Validate() )
378 *aValidationMessage +=
380 wxString::Format(
_(
"%s should not be empty." ), aLabel ) );
387 *aErrorCount, wxString::Format(
_(
"The value of %s must be a valid integer." ), aLabel ) );
394 *aErrorCount, wxString::Format(
_(
"The value of %s must be greater than 0." ), aLabel ) );
406 wxString* aValidationMessage )
409 aComboBox->SetValidator( cmbCtrlValidator );
411 if( !aComboBox->Validate() )
421 wxString::Format(
_(
"Please choose %s." ), aLabel ) );
433 const wxString& aMinLabel,
const wxString& aMaxLabel,
434 int* aErrorCount, wxString* aValidationMessage )
436 aMinTextCtrl->SetName(
"min" );
437 aMaxTextCtrl->SetName(
"max" );
441 if( !aMinTextCtrl->Validate() )
451 *aErrorCount, wxString::Format(
_(
"%s value cannot be greater than %s value." ),
452 aMinLabel, aMaxLabel ) );
459 aMinTextCtrl->SetName(
"text" );
460 aMaxTextCtrl->SetName(
"text" );
467 wxTextCtrl* aMaxTextCtrl,
const wxString& aMinLabel,
468 const wxString& aPreferredLabel,
const wxString& aMaxLabel,
469 int* aErrorCount, wxString* aValidationMessage )
471 aMinTextCtrl->SetName(
"min" );
472 aPreferredTextCtrl->SetName(
"preferred" );
473 aMaxTextCtrl->SetName(
"max" );
477 if( !aMinTextCtrl->Validate() )
488 *aErrorCount, wxString::Format(
_(
"%s value cannot be greater than %s value." ),
489 aMinLabel, aPreferredLabel ) );
496 *aErrorCount, wxString::Format(
_(
"%s value cannot be greater than %s value." ),
497 aPreferredLabel, aMaxLabel ) );
504 *aErrorCount, wxString::Format(
_(
"%s value cannot be greater than %s value." ),
505 aMinLabel, aMaxLabel ) );
512 aMinTextCtrl->SetName(
"text" );
513 aPreferredTextCtrl->SetName(
"text" );
514 aMaxTextCtrl->SetName(
"text" );
521 int* aErrorCount, wxString* aValidationMessage )
525 aCheckboxes[0]->SetValidator( validator );
527 if( !aCheckboxes[0]->Validate() )
537 *aErrorCount, wxString::Format(
_(
"Please select at least one option from %s list." ), aLabel ));
550 return wxString::Format( wxS(
"%d. %s\n" ), aErrorCount, aErrorMessage );
559 if( !aCanBeZero && aValue <= 0.0 )
561 aResult->
AddError( wxString::Format(
_(
"The value of %s must be greater than 0." ), aLabel ) );
570 bool aIntegerOnly,
const wxString& aLabel,
573 if( aValueStr.IsEmpty() )
575 aResult->
AddError( wxString::Format(
_(
"%s should not be empty." ), aLabel ) );
583 std::string stdStr = aValueStr.ToStdString();
585 long intVal = std::stol( stdStr, &pos );
587 if( pos != stdStr.length() )
589 aResult->
AddError( wxString::Format(
_(
"The value of %s must be a valid integer." ), aLabel ) );
593 if( !aCanBeZero && intVal <= 0 )
595 aResult->
AddError( wxString::Format(
_(
"The value of %s must be greater than 0." ), aLabel ) );
601 std::string stdStr = aValueStr.ToStdString();
603 double floatVal = std::stod( stdStr, &pos );
605 if( pos != stdStr.length() )
607 aResult->
AddError( wxString::Format(
_(
"The value of %s must be a valid number." ), aLabel ) );
611 if( !aCanBeZero && floatVal <= 0.0 )
613 aResult->
AddError( wxString::Format(
_(
"The value of %s must be greater than 0." ), aLabel ) );
618 catch(
const std::exception& )
621 aResult->
AddError( wxString::Format(
_(
"The value of %s must be a valid integer." ), aLabel ) );
623 aResult->
AddError( wxString::Format(
_(
"The value of %s must be a valid number." ), aLabel ) );
637 aResult->
AddError( wxString::Format(
_(
"%s value cannot be greater than %s value." ), aMinLabel, aMaxLabel ));
646 const wxString& aMinLabel,
647 const wxString& aPrefLabel,
648 const wxString& aMaxLabel,
653 if( aMin > aPreferred )
655 aResult->
AddError( wxString::Format(
_(
"%s value cannot be greater than %s value." ), aMinLabel, aPrefLabel ));
659 if( aPreferred > aMax )
661 aResult->
AddError( wxString::Format(
_(
"%s value cannot be greater than %s value." ), aPrefLabel, aMaxLabel ));
667 aResult->
AddError( wxString::Format(
_(
"%s value cannot be greater than %s value." ), aMinLabel, aMaxLabel ));
676 const wxString& aLabel,
679 for(
bool selected : aSelected )
685 aResult->
AddError( wxString::Format(
_(
"Please select at least one option from %s list." ), aLabel ) );
693 if( aSelectionIndex < 0 )
695 aResult->
AddError( wxString::Format(
_(
"Please choose %s." ), aLabel ) );
707 std::vector<std::shared_ptr<DRC_RE_BASE_CONSTRAINT_DATA>> rules;
708 std::vector<std::shared_ptr<DRC_RULE>> parsedRules;
710 wxString rulesText = aRules;
711 if( !rulesText.Contains(
"(version" ) )
712 rulesText.Prepend(
"(version 1)\n" );
717 parser.
Parse( parsedRules,
nullptr );
723 for(
const auto& rule : parsedRules )
725 std::shared_ptr<DRC_RE_BASE_CONSTRAINT_DATA> data;
729 data = converter( rule );
736 auto customData = std::make_shared<DRC_RE_CUSTOM_RULE_CONSTRAINT_DATA>( 0, 0, rule->m_Name );
737 customData->SetRuleText( wxString::Format(
"(rule \"%s\" ...)", rule->m_Name ) );
741 if( rule->m_Condition )
742 data->SetRuleCondition( rule->m_Condition->GetExpression() );
744 rules.push_back( data );
751 const std::vector<std::shared_ptr<DRC_RE_BASE_CONSTRAINT_DATA>>& aRules,
752 const BOARD* aBoard )
754 wxString content = wxT(
"(version 1)\n" );
756 for(
const auto& data : aRules )
763 ctx.
comment = data->GetComment();
767 std::vector<PCB_LAYER_ID> layers = data->GetLayers();
769 if( !layers.empty() && aBoard )
771 wxString layerStr =
"(layer";
774 layerStr +=
" \"" + aBoard->
GetLayerName( layer ) +
"\"";
780 content += data->GenerateRule( ctx ) + wxT(
"\n" );
783 std::string utf8 = std::string( content.mb_str( wxConvUTF8 ) );
793 switch( aConstraintType )
854 switch( aConstraintType )
857 return wxString::Format( wxS(
"(layer \"%s\")" ),
858 aIsTop ? wxS(
"F.CrtYd" ) : wxS(
"B.CrtYd" ) );
862 return wxString::Format( wxS(
"(condition \"A.Layer == '%s' && B.Layer == '%s'\")" ),
863 aIsTop ? wxS(
"F.SilkS" ) : wxS(
"B.SilkS" ),
864 aIsTop ? wxS(
"F.Mask" ) : wxS(
"B.Mask" ) );
868 return wxString::Format( wxS(
"(layer \"%s\")" ), aIsTop ? wxS(
"F.Cu" ) : wxS(
"B.Cu" ) );
871 return wxEmptyString;
876std::shared_ptr<DRC_RE_NUMERIC_INPUT_CONSTRAINT_DATA>
883 case COURTYARD_CLEARANCE:
return std::make_shared<DRC_RE_COURTYARD_CLEARANCE_CONSTRAINT_DATA>();
884 case PHYSICAL_CLEARANCE:
return std::make_shared<DRC_RE_PHYSICAL_CLEARANCE_CONSTRAINT_DATA>();
885 case CREEPAGE_DISTANCE:
return std::make_shared<DRC_RE_CREEPAGE_DISTANCE_CONSTRAINT_DATA>();
886 case HOLE_SIZE:
return std::make_shared<DRC_RE_HOLE_SIZE_CONSTRAINT_DATA>();
888 case MAXIMUM_VIA_COUNT:
return std::make_shared<DRC_RE_MAXIMUM_VIA_COUNT_CONSTRAINT_DATA>();
890 case MINIMUM_CLEARANCE:
return std::make_shared<DRC_RE_MINIMUM_CLEARANCE_CONSTRAINT_DATA>();
894 case MINIMUM_DRILL_SIZE:
return std::make_shared<DRC_RE_MINIMUM_DRILL_SIZE_CONSTRAINT_DATA>();
895 case MINIMUM_VIA_DIAMETER:
return std::make_shared<DRC_RE_MINIMUM_VIA_DIAMETER_CONSTRAINT_DATA>();
898 case SOLDERMASK_EXPANSION:
return std::make_shared<DRC_RE_SOLDERMASK_EXPANSION_CONSTRAINT_DATA>();
900 default:
return std::make_shared<DRC_RE_NUMERIC_INPUT_CONSTRAINT_DATA>();
905std::shared_ptr<DRC_RE_NUMERIC_INPUT_CONSTRAINT_DATA>
913 case COURTYARD_CLEARANCE:
return std::make_shared<DRC_RE_COURTYARD_CLEARANCE_CONSTRAINT_DATA>( aBase );
914 case PHYSICAL_CLEARANCE:
return std::make_shared<DRC_RE_PHYSICAL_CLEARANCE_CONSTRAINT_DATA>( aBase );
915 case CREEPAGE_DISTANCE:
return std::make_shared<DRC_RE_CREEPAGE_DISTANCE_CONSTRAINT_DATA>( aBase );
916 case HOLE_SIZE:
return std::make_shared<DRC_RE_HOLE_SIZE_CONSTRAINT_DATA>( aBase );
917 case HOLE_TO_HOLE_DISTANCE:
return std::make_shared<DRC_RE_HOLE_TO_HOLE_DISTANCE_CONSTRAINT_DATA>( aBase );
918 case MAXIMUM_VIA_COUNT:
return std::make_shared<DRC_RE_MAXIMUM_VIA_COUNT_CONSTRAINT_DATA>( aBase );
919 case MINIMUM_ANNULAR_WIDTH:
return std::make_shared<DRC_RE_MINIMUM_ANNULAR_WIDTH_CONSTRAINT_DATA>( aBase );
920 case MINIMUM_CLEARANCE:
return std::make_shared<DRC_RE_MINIMUM_CLEARANCE_CONSTRAINT_DATA>( aBase );
924 case MINIMUM_DRILL_SIZE:
return std::make_shared<DRC_RE_MINIMUM_DRILL_SIZE_CONSTRAINT_DATA>( aBase );
925 case MINIMUM_VIA_DIAMETER:
return std::make_shared<DRC_RE_MINIMUM_VIA_DIAMETER_CONSTRAINT_DATA>( aBase );
926 case SILK_TO_SILK_CLEARANCE:
return std::make_shared<DRC_RE_SILK_TO_SILK_CLEARANCE_CONSTRAINT_DATA>( aBase );
928 case SOLDERMASK_EXPANSION:
return std::make_shared<DRC_RE_SOLDERMASK_EXPANSION_CONSTRAINT_DATA>( aBase );
929 case SOLDERPASTE_EXPANSION:
return std::make_shared<DRC_RE_SOLDERPASTE_EXPANSION_CONSTRAINT_DATA>( aBase );
930 default:
return std::make_shared<DRC_RE_NUMERIC_INPUT_CONSTRAINT_DATA>( aBase );
Information pertinent to a Pcbnew printed circuit board.
const wxString GetLayerName(PCB_LAYER_ID aLayer) const
Return the name of a aLayer.
void SetConstraintCode(const wxString &aCode)
void Parse(std::vector< std::shared_ptr< DRC_RULE > > &aRules, REPORTER *aReporter)
static bool IsNumericInputType(const DRC_RULE_EDITOR_CONSTRAINT_NAME &aConstraintType)
static wxString ConstraintToKicadDrc(DRC_RULE_EDITOR_CONSTRAINT_NAME aType)
Convert a constraint type into the keyword used in a .kicad_drc file.
static bool ValidateNumericValue(double aValue, bool aCanBeZero, const wxString &aLabel, VALIDATION_RESULT *aResult)
Validates a numeric value.
static bool ValidateAtLeastOneSelected(const std::vector< bool > &aSelected, const wxString &aLabel, VALIDATION_RESULT *aResult)
Validates that at least one option is selected.
static bool ValidateSelection(int aSelectionIndex, const wxString &aLabel, VALIDATION_RESULT *aResult)
Validates that a selection has been made (index >= 0).
static wxString GetConstraintCode(DRC_RULE_EDITOR_CONSTRAINT_NAME aConstraintType)
Translate a rule tree node type into the keyword used by the rules file for that constraint.
static bool ValidateNumericCtrl(wxTextCtrl *aTextCtrl, const wxString &aLabel, bool aCanBeZero, int *aErrorCount, wxString *aValidationMessage)
Validates a numeric input control, checking if the value is valid, non-empty, and greater than zero.
static bool ValidateMinMax(double aMin, double aMax, const wxString &aMinLabel, const wxString &aMaxLabel, VALIDATION_RESULT *aResult)
Validates that min <= max.
static bool ConstraintFromKicadDrc(const wxString &aCode, DRC_RE_BASE_CONSTRAINT_DATA *aData)
Populate a constraint data object using a keyword from a .kicad_drc file.
static bool ValidateMinPreferredMaxCtrl(wxTextCtrl *aMinTextCtrl, wxTextCtrl *aPreferredTextCtrl, wxTextCtrl *aMaxTextCtrl, const wxString &aMinLabel, const wxString &aPreferredLabel, const wxString &aMaxLabel, int *aErrorCount, wxString *aValidationMessage)
Validates the minimum, preferred, and maximum value controls, ensuring that:
static wxString FormatErrorMessage(int aErrorCount, const wxString &aErrorMessage)
static std::optional< DRC_RULE_EDITOR_CONSTRAINT_NAME > GetConstraintTypeFromCode(const wxString &aCode)
Resolve a constraint keyword from a rules file into the corresponding rule tree enumeration value.
static bool ValidateComboCtrl(wxComboBox *aComboBox, const wxString &aLabel, int *aErrorCount, wxString *aValidationMessage)
Validates a combo box control, ensuring that a selection has been made.
static bool SaveRules(const wxString &aFilename, const std::vector< std::shared_ptr< DRC_RE_BASE_CONSTRAINT_DATA > > &aRules, const BOARD *aBoard)
static void RegisterRuleConverter(RuleConverter aConverter)
static wxString TranslateTopBottomLayer(DRC_RULE_EDITOR_CONSTRAINT_NAME aConstraintType, bool aIsTop)
Translate a top/bottom selection to the appropriate layer clause or condition.
static bool ValidateCheckBoxCtrls(const std::vector< wxCheckBox * > &aCheckboxes, const wxString &aLabel, int *aErrorCount, wxString *aValidationMessage)
Validates a list of checkboxes, ensuring that at least one option is selected.
static bool ValidateNumericString(const wxString &aValueStr, bool aCanBeZero, bool aIntegerOnly, const wxString &aLabel, VALIDATION_RESULT *aResult)
Validates that a string represents a valid numeric value.
static bool ValidateMinMaxCtrl(wxTextCtrl *aMinTextCtrl, wxTextCtrl *aMaxTextCtrl, const wxString &aMinLabel, const wxString &aMaxLabel, int *aErrorCount, wxString *aValidationMessage)
Validates the minimum and maximum value controls, ensuring that the minimum value is not greater than...
std::function< std::shared_ptr< DRC_RE_BASE_CONSTRAINT_DATA >(const std::shared_ptr< DRC_RULE > &)> RuleConverter
static std::shared_ptr< DRC_RE_NUMERIC_INPUT_CONSTRAINT_DATA > CreateNumericConstraintData(DRC_RULE_EDITOR_CONSTRAINT_NAME aType)
static DRC_LAYER_CATEGORY GetLayerCategoryForConstraint(DRC_RULE_EDITOR_CONSTRAINT_NAME aConstraintType)
Get the layer category for a constraint type.
static bool ValidateMinPreferredMax(double aMin, double aPreferred, double aMax, const wxString &aMinLabel, const wxString &aPrefLabel, const wxString &aMaxLabel, VALIDATION_RESULT *aResult)
Validates that min <= preferred <= max.
static bool ValidateIntegerCtrl(wxTextCtrl *aTextCtrl, const wxString &aLabel, bool aCanBeZero, int *aErrorCount, wxString *aValidationMessage)
Validates an integer input control, ensuring the value is a valid integer, non-empty,...
static bool IsBoolInputType(const DRC_RULE_EDITOR_CONSTRAINT_NAME &aConstraintType)
static std::vector< std::shared_ptr< DRC_RE_BASE_CONSTRAINT_DATA > > ParseRules(const wxString &aRules)
Hold an error message and may be used when throwing exceptions containing meaningful error messages.
VALIDATION_STATE GetValidationState() const
VALIDATION_STATE GetValidationState() const
VALIDATION_STATE GetValidationState() const
@ PreferredGreaterThanMax
@ MinGreaterThanPreferred
VALIDATION_STATE GetValidationState() const
VALIDATION_STATE GetValidationState() const
@ ANNULAR_WIDTH_CONSTRAINT
@ BRIDGED_MASK_CONSTRAINT
@ COURTYARD_CLEARANCE_CONSTRAINT
@ VIA_DIAMETER_CONSTRAINT
@ ZONE_CONNECTION_CONSTRAINT
@ DIFF_PAIR_GAP_CONSTRAINT
@ VIA_DANGLING_CONSTRAINT
@ SOLDER_MASK_SLIVER_CONSTRAINT
@ SILK_CLEARANCE_CONSTRAINT
@ EDGE_CLEARANCE_CONSTRAINT
@ MIN_RESOLVED_SPOKES_CONSTRAINT
@ TRACK_SEGMENT_LENGTH_CONSTRAINT
@ TEXT_THICKNESS_CONSTRAINT
@ PHYSICAL_HOLE_CLEARANCE_CONSTRAINT
@ THERMAL_SPOKE_WIDTH_CONSTRAINT
@ CONNECTION_WIDTH_CONSTRAINT
@ THERMAL_RELIEF_GAP_CONSTRAINT
@ MAX_UNCOUPLED_CONSTRAINT
@ HOLE_CLEARANCE_CONSTRAINT
@ SOLDER_PASTE_ABS_MARGIN_CONSTRAINT
@ SOLDER_MASK_EXPANSION_CONSTRAINT
@ PHYSICAL_CLEARANCE_CONSTRAINT
@ SOLDER_PASTE_REL_MARGIN_CONSTRAINT
@ HOLE_TO_HOLE_CONSTRAINT
DRC_RULE_EDITOR_CONSTRAINT_NAME
@ SILK_TO_SOLDERMASK_CLEARANCE
@ MINIMUM_CONNECTION_WIDTH
@ MINIMUM_THERMAL_RELIEF_SPOKE_COUNT
@ MINIMUM_TEXT_HEIGHT_AND_THICKNESS
@ COPPER_TO_HOLE_CLEARANCE
@ MATCHED_LENGTH_DIFF_PAIR
@ COPPER_TO_EDGE_CLEARANCE
@ MINIMUM_SOLDERMASK_SLIVER
DRC_LAYER_CATEGORY
Layer categories for filtering the layer selector dropdown.
@ NO_LAYER_SELECTOR
Hide layer selector entirely.
@ TOP_BOTTOM_ANY
Simplified top/bottom/any selector with custom translation.
@ SOLDERMASK_ONLY
F_Mask, B_Mask.
@ GENERAL_ANY_LAYER
All layers + inner/outer synthetic.
@ SOLDERPASTE_ONLY
F_Paste, B_Paste.
@ COPPER_ONLY
Copper layers + inner/outer synthetic.
@ SILKSCREEN_ONLY
F_SilkS, B_SilkS.
static wxString GetConstraintCodeFromType(DRC_CONSTRAINT_T aType)
std::unordered_map< DRC_RULE_EDITOR_CONSTRAINT_NAME, const char * > CODE_MAP
static void RegisterDefaultConverters()
static const CODE_MAP sCodeMap
static const REVERSE_CODE_MAP sCodeReverse
std::unordered_map< wxString, DRC_RULE_EDITOR_CONSTRAINT_NAME, wxStringHash, wxStringEqual > REVERSE_CODE_MAP
static std::vector< DRC_RULE_EDITOR_UTILS::RuleConverter > & GetRuleConverters()
PCB_LAYER_ID
A quick note on layer IDs:
wxString conditionExpression
Result of a validation operation.
void AddError(const wxString &aError)