26#include <drc_rules_lexer.h>
42#include <unordered_map>
44using CODE_MAP = std::unordered_map<DRC_RULE_EDITOR_CONSTRAINT_NAME, const char*>;
45using REVERSE_CODE_MAP = std::unordered_map<wxString, DRC_RULE_EDITOR_CONSTRAINT_NAME, wxStringHash, wxStringEqual>;
57 {
HOLE_SIZE, DRC_RULES_LEXER::TokenName( DRCRULE_T::T_hole_size ) },
69 {
ROUTING_WIDTH, DRC_RULES_LEXER::TokenName( DRCRULE_T::T_track_width ) },
79 for(
const auto& [type, code] :
sCodeMap )
80 map.emplace( wxString::FromUTF8( code ), type );
86 static std::vector<DRC_RULE_EDITOR_UTILS::RuleConverter> converters;
123 case LENGTH_CONSTRAINT:
return DRC_RULES_LEXER::TokenName( DRCRULE_T::T_length );
124 case SKEW_CONSTRAINT:
return DRC_RULES_LEXER::TokenName( DRCRULE_T::T_skew );
139 static bool initialized =
false;
146 [](
const std::shared_ptr<DRC_RULE>& aRule ) -> std::shared_ptr<DRC_RE_BASE_CONSTRAINT_DATA>
148 if( aRule->m_Constraints.empty() )
return nullptr;
150 const auto& constraint = aRule->m_Constraints[0];
153 if( code.IsEmpty() )
return nullptr;
161 double val = constraint.GetValue().Min() / 1000000.0;
163 data->SetRuleName( aRule->m_Name );
164 data->SetNumericInputValue( val );
165 data->SetConstraintCode( code );
170 auto data = std::make_shared<DRC_RE_BOOL_INPUT_CONSTRAINT_DATA>( 0, 0,
true, aRule->m_Name );
171 data->SetConstraintCode( code );
174 else if( code ==
"track_width" )
176 double minW = constraint.GetValue().Min() / 1000000.0;
177 double optW = constraint.GetValue().Opt() / 1000000.0;
178 double maxW = constraint.GetValue().Max() / 1000000.0;
182 tol = std::max( optW - minW, maxW - optW );
185 std::make_shared<DRC_RE_ROUTING_WIDTH_CONSTRAINT_DATA>( 0, 0, aRule->m_Name, optW, tol );
186 data->SetConstraintCode( code );
195 [](
const std::shared_ptr<DRC_RULE>& aRule ) -> std::shared_ptr<DRC_RE_BASE_CONSTRAINT_DATA>
200 if( diaConstraint && holeConstraint )
202 double minDia = diaConstraint->GetValue().Min() / 1000000.0;
203 double maxDia = diaConstraint->GetValue().Max() / 1000000.0;
205 double minDrill = holeConstraint->GetValue().Min() / 1000000.0;
206 double maxDrill = holeConstraint->GetValue().Max() / 1000000.0;
210 if( aRule->m_Condition )
212 wxString expr = aRule->m_Condition->GetExpression();
214 if( expr.Contains( wxS(
"'Micro'" ) ) )
216 else if( expr.Contains( wxS(
"'Through'" ) ) )
218 else if( expr.Contains( wxS(
"'Blind'" ) ) )
220 else if( expr.Contains( wxS(
"'Buried'" ) ) )
224 auto data = std::make_shared<DRC_RE_VIA_STYLE_CONSTRAINT_DATA>( 0, 0, aRule->m_Name, minDia, maxDia,
225 minDrill, maxDrill, viaType );
226 data->SetConstraintCode(
"via_style" );
236 auto it =
sCodeMap.find( aConstraintType );
238 return wxString::FromUTF8( it->second );
279 switch( aConstraintType )
281 default:
return false;
288 switch( aConstraintType )
318 int* aErrorCount, wxString* aValidationMessage )
321 aTextCtrl->SetValidator( validator );
323 if( !aTextCtrl->Validate() )
332 *aValidationMessage +=
334 wxString::Format(
_(
"%s should not be empty." ), aLabel ) );
341 *aErrorCount, wxString::Format(
_(
"The value of %s must be a valid number." ), aLabel ) );
348 *aErrorCount, wxString::Format(
_(
"The value of %s must be greater than 0." ), aLabel ) );
360 int* aErrorCount, wxString* aValidationMessage )
363 aTextCtrl->SetValidator( validator );
365 if( !aTextCtrl->Validate() )
374 *aValidationMessage +=
376 wxString::Format(
_(
"%s should not be empty." ), aLabel ) );
383 *aErrorCount, wxString::Format(
_(
"The value of %s must be a valid integer." ), aLabel ) );
390 *aErrorCount, wxString::Format(
_(
"The value of %s must be greater than 0." ), aLabel ) );
402 wxString* aValidationMessage )
405 aComboBox->SetValidator( cmbCtrlValidator );
407 if( !aComboBox->Validate() )
417 wxString::Format(
_(
"Please choose %s." ), aLabel ) );
429 const wxString& aMinLabel,
const wxString& aMaxLabel,
430 int* aErrorCount, wxString* aValidationMessage )
432 aMinTextCtrl->SetName(
"min" );
433 aMaxTextCtrl->SetName(
"max" );
437 if( !aMinTextCtrl->Validate() )
447 *aErrorCount, wxString::Format(
_(
"%s value cannot be greater than %s value." ),
448 aMinLabel, aMaxLabel ) );
455 aMinTextCtrl->SetName(
"text" );
456 aMaxTextCtrl->SetName(
"text" );
463 wxTextCtrl* aMaxTextCtrl,
const wxString& aMinLabel,
464 const wxString& aPreferredLabel,
const wxString& aMaxLabel,
465 int* aErrorCount, wxString* aValidationMessage )
467 aMinTextCtrl->SetName(
"min" );
468 aPreferredTextCtrl->SetName(
"preferred" );
469 aMaxTextCtrl->SetName(
"max" );
473 if( !aMinTextCtrl->Validate() )
484 *aErrorCount, wxString::Format(
_(
"%s value cannot be greater than %s value." ),
485 aMinLabel, aPreferredLabel ) );
492 *aErrorCount, wxString::Format(
_(
"%s value cannot be greater than %s value." ),
493 aPreferredLabel, aMaxLabel ) );
500 *aErrorCount, wxString::Format(
_(
"%s value cannot be greater than %s value." ),
501 aMinLabel, aMaxLabel ) );
508 aMinTextCtrl->SetName(
"text" );
509 aPreferredTextCtrl->SetName(
"text" );
510 aMaxTextCtrl->SetName(
"text" );
517 int* aErrorCount, wxString* aValidationMessage )
521 aCheckboxes[0]->SetValidator( validator );
523 if( !aCheckboxes[0]->Validate() )
533 *aErrorCount, wxString::Format(
_(
"Please select at least one option from %s list." ), aLabel ));
546 return wxString::Format( wxS(
"%d. %s\n" ), aErrorCount, aErrorMessage );
555 if( !aCanBeZero && aValue <= 0.0 )
557 aResult->
AddError( wxString::Format(
_(
"The value of %s must be greater than 0." ), aLabel ) );
566 bool aIntegerOnly,
const wxString& aLabel,
569 if( aValueStr.IsEmpty() )
571 aResult->
AddError( wxString::Format(
_(
"%s should not be empty." ), aLabel ) );
579 std::string stdStr = aValueStr.ToStdString();
581 long intVal = std::stol( stdStr, &pos );
583 if( pos != stdStr.length() )
585 aResult->
AddError( wxString::Format(
_(
"The value of %s must be a valid integer." ), aLabel ) );
589 if( !aCanBeZero && intVal <= 0 )
591 aResult->
AddError( wxString::Format(
_(
"The value of %s must be greater than 0." ), aLabel ) );
597 std::string stdStr = aValueStr.ToStdString();
599 double floatVal = std::stod( stdStr, &pos );
601 if( pos != stdStr.length() )
603 aResult->
AddError( wxString::Format(
_(
"The value of %s must be a valid number." ), aLabel ) );
607 if( !aCanBeZero && floatVal <= 0.0 )
609 aResult->
AddError( wxString::Format(
_(
"The value of %s must be greater than 0." ), aLabel ) );
614 catch(
const std::exception& )
617 aResult->
AddError( wxString::Format(
_(
"The value of %s must be a valid integer." ), aLabel ) );
619 aResult->
AddError( wxString::Format(
_(
"The value of %s must be a valid number." ), aLabel ) );
633 aResult->
AddError( wxString::Format(
_(
"%s value cannot be greater than %s value." ), aMinLabel, aMaxLabel ));
642 const wxString& aMinLabel,
643 const wxString& aPrefLabel,
644 const wxString& aMaxLabel,
649 if( aMin > aPreferred )
651 aResult->
AddError( wxString::Format(
_(
"%s value cannot be greater than %s value." ), aMinLabel, aPrefLabel ));
655 if( aPreferred > aMax )
657 aResult->
AddError( wxString::Format(
_(
"%s value cannot be greater than %s value." ), aPrefLabel, aMaxLabel ));
663 aResult->
AddError( wxString::Format(
_(
"%s value cannot be greater than %s value." ), aMinLabel, aMaxLabel ));
672 const wxString& aLabel,
675 for(
bool selected : aSelected )
681 aResult->
AddError( wxString::Format(
_(
"Please select at least one option from %s list." ), aLabel ) );
689 if( aSelectionIndex < 0 )
691 aResult->
AddError( wxString::Format(
_(
"Please choose %s." ), aLabel ) );
703 std::vector<std::shared_ptr<DRC_RE_BASE_CONSTRAINT_DATA>> rules;
704 std::vector<std::shared_ptr<DRC_RULE>> parsedRules;
706 wxString rulesText = aRules;
707 if( !rulesText.Contains(
"(version" ) )
708 rulesText.Prepend(
"(version 2)\n" );
713 parser.
Parse( parsedRules,
nullptr );
719 for(
const auto& rule : parsedRules )
721 std::shared_ptr<DRC_RE_BASE_CONSTRAINT_DATA> data;
725 data = converter( rule );
732 auto customData = std::make_shared<DRC_RE_CUSTOM_RULE_CONSTRAINT_DATA>( 0, 0, rule->m_Name );
733 customData->SetRuleText( wxString::Format(
"(rule \"%s\" ...)", rule->m_Name ) );
737 if( rule->m_Condition )
738 data->SetRuleCondition( rule->m_Condition->GetExpression() );
740 rules.push_back( data );
747 const std::vector<std::shared_ptr<DRC_RE_BASE_CONSTRAINT_DATA>>& aRules,
748 const BOARD* aBoard )
750 wxString content = wxT(
"(version 2)\n" );
752 for(
const auto& data : aRules )
759 ctx.
comment = data->GetComment();
763 std::vector<PCB_LAYER_ID> layers = data->GetLayers();
765 if( !layers.empty() && aBoard )
767 wxString layerStr =
"(layer";
770 layerStr +=
" \"" + aBoard->
GetLayerName( layer ) +
"\"";
776 content += data->GenerateRule( ctx ) + wxT(
"\n" );
779 std::string utf8 = std::string( content.mb_str( wxConvUTF8 ) );
789 switch( aConstraintType )
850 switch( aConstraintType )
853 return wxString::Format( wxS(
"(layer \"%s\")" ),
854 aIsTop ? wxS(
"F.CrtYd" ) : wxS(
"B.CrtYd" ) );
858 return wxString::Format( wxS(
"(condition \"A.Layer == '%s' && B.Layer == '%s'\")" ),
859 aIsTop ? wxS(
"F.SilkS" ) : wxS(
"B.SilkS" ),
860 aIsTop ? wxS(
"F.Mask" ) : wxS(
"B.Mask" ) );
864 return wxString::Format( wxS(
"(layer \"%s\")" ), aIsTop ? wxS(
"F.Cu" ) : wxS(
"B.Cu" ) );
867 return wxEmptyString;
872std::shared_ptr<DRC_RE_NUMERIC_INPUT_CONSTRAINT_DATA>
879 case COURTYARD_CLEARANCE:
return std::make_shared<DRC_RE_COURTYARD_CLEARANCE_CONSTRAINT_DATA>();
880 case PHYSICAL_CLEARANCE:
return std::make_shared<DRC_RE_PHYSICAL_CLEARANCE_CONSTRAINT_DATA>();
881 case CREEPAGE_DISTANCE:
return std::make_shared<DRC_RE_CREEPAGE_DISTANCE_CONSTRAINT_DATA>();
882 case HOLE_SIZE:
return std::make_shared<DRC_RE_HOLE_SIZE_CONSTRAINT_DATA>();
884 case MAXIMUM_VIA_COUNT:
return std::make_shared<DRC_RE_MAXIMUM_VIA_COUNT_CONSTRAINT_DATA>();
886 case MINIMUM_CLEARANCE:
return std::make_shared<DRC_RE_MINIMUM_CLEARANCE_CONSTRAINT_DATA>();
890 case MINIMUM_DRILL_SIZE:
return std::make_shared<DRC_RE_MINIMUM_DRILL_SIZE_CONSTRAINT_DATA>();
891 case MINIMUM_VIA_DIAMETER:
return std::make_shared<DRC_RE_MINIMUM_VIA_DIAMETER_CONSTRAINT_DATA>();
894 case SOLDERMASK_EXPANSION:
return std::make_shared<DRC_RE_SOLDERMASK_EXPANSION_CONSTRAINT_DATA>();
896 default:
return std::make_shared<DRC_RE_NUMERIC_INPUT_CONSTRAINT_DATA>();
901std::shared_ptr<DRC_RE_NUMERIC_INPUT_CONSTRAINT_DATA>
909 case COURTYARD_CLEARANCE:
return std::make_shared<DRC_RE_COURTYARD_CLEARANCE_CONSTRAINT_DATA>( aBase );
910 case PHYSICAL_CLEARANCE:
return std::make_shared<DRC_RE_PHYSICAL_CLEARANCE_CONSTRAINT_DATA>( aBase );
911 case CREEPAGE_DISTANCE:
return std::make_shared<DRC_RE_CREEPAGE_DISTANCE_CONSTRAINT_DATA>( aBase );
912 case HOLE_SIZE:
return std::make_shared<DRC_RE_HOLE_SIZE_CONSTRAINT_DATA>( aBase );
913 case HOLE_TO_HOLE_DISTANCE:
return std::make_shared<DRC_RE_HOLE_TO_HOLE_DISTANCE_CONSTRAINT_DATA>( aBase );
914 case MAXIMUM_VIA_COUNT:
return std::make_shared<DRC_RE_MAXIMUM_VIA_COUNT_CONSTRAINT_DATA>( aBase );
915 case MINIMUM_ANNULAR_WIDTH:
return std::make_shared<DRC_RE_MINIMUM_ANNULAR_WIDTH_CONSTRAINT_DATA>( aBase );
916 case MINIMUM_CLEARANCE:
return std::make_shared<DRC_RE_MINIMUM_CLEARANCE_CONSTRAINT_DATA>( aBase );
920 case MINIMUM_DRILL_SIZE:
return std::make_shared<DRC_RE_MINIMUM_DRILL_SIZE_CONSTRAINT_DATA>( aBase );
921 case MINIMUM_VIA_DIAMETER:
return std::make_shared<DRC_RE_MINIMUM_VIA_DIAMETER_CONSTRAINT_DATA>( aBase );
922 case SILK_TO_SILK_CLEARANCE:
return std::make_shared<DRC_RE_SILK_TO_SILK_CLEARANCE_CONSTRAINT_DATA>( aBase );
924 case SOLDERMASK_EXPANSION:
return std::make_shared<DRC_RE_SOLDERMASK_EXPANSION_CONSTRAINT_DATA>( aBase );
925 case SOLDERPASTE_EXPANSION:
return std::make_shared<DRC_RE_SOLDERPASTE_EXPANSION_CONSTRAINT_DATA>( aBase );
926 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)