29                                                    const std::string& aPath ) :
 
   35            "sheet_component_classes",
 
   36            [&]() -> nlohmann::json
 
   38                nlohmann::json ret = {};
 
   44            [&]( 
const nlohmann::json& aJson )
 
   46                if( !aJson.is_object() )
 
   49                if( !aJson.contains( 
"enabled" ) )
 
   58            [&]() -> nlohmann::json
 
   60                nlohmann::json ret = nlohmann::json::array();
 
   70            [&]( 
const nlohmann::json& aJson )
 
   72                if( !aJson.is_array() )
 
   77                for( 
const auto& assignmentJson : aJson )
 
 
   92        m_parent->ReleaseNestedSettings( 
this );
 
 
  103    const wxString matchOperator =
 
  110    ret[
"conditions_operator"] = matchOperator.ToUTF8();
 
  112    nlohmann::json conditionsJson;
 
  114    for( 
const auto& [conditionType, conditionData] : aAssignment.
GetConditions() )
 
  116        nlohmann::json conditionJson;
 
  118        if( !conditionData.first.empty() )
 
  119            conditionJson[
"primary"] = conditionData.first;
 
  121        if( !conditionData.second.empty() )
 
  122            conditionJson[
"secondary"] = conditionData.second;
 
  124        const wxString conditionName =
 
  126        conditionsJson[conditionName] = conditionJson;
 
  129    ret[
"conditions"] = conditionsJson;
 
 
  141            wxString( aJson[
"component_class"].get<std::string>().c_str(), wxConvUTF8 ) );
 
  143    const wxString matchOperator( aJson[
"conditions_operator"].get<std::string>().c_str(),
 
  146    if( matchOperator == wxT( 
"ALL" ) )
 
  157    for( 
const auto& [conditionTypeStr, conditionData] : aJson[
"conditions"].items() )
 
  159        wxString                                        primary, secondary;
 
  163        if( conditionData.contains( 
"primary" ) )
 
  164            primary = wxString( conditionData[
"primary"].get<std::string>().c_str(), wxConvUTF8 );
 
  166        if( conditionData.contains( 
"secondary" ) )
 
  168                    wxString( conditionData[
"secondary"].get<std::string>().c_str(), wxConvUTF8 );
 
  170        assignment.
SetCondition( conditionType, primary, secondary );
 
 
  204    wxASSERT_MSG( 
false, 
"Invalid condition type" );
 
  206    return wxEmptyString;
 
 
  213    if( aCondition == wxT( 
"REFERENCE" ) )
 
  215    if( aCondition == wxT( 
"FOOTPRINT" ) )
 
  217    if( aCondition == wxT( 
"SIDE" ) )
 
  219    if( aCondition == wxT( 
"ROTATION" ) )
 
  221    if( aCondition == wxT( 
"FOOTPRINT_FIELD" ) )
 
  223    if( aCondition == wxT( 
"CUSTOM" ) )
 
  225    if( aCondition == wxT( 
"SHEET_NAME" ) )
 
  228    wxASSERT_MSG( 
false, 
"Invalid condition type" );
 
 
  237        return wxEmptyString;
 
  242        return wxString::Format( wxT( 
"(version 1) (assign_component_class \"%s\")" ),
 
  247    auto getRefExpr = []( wxString aRefs ) -> wxString
 
  249        aRefs.Trim( 
true ).Trim( 
false );
 
  251        wxArrayString refs = wxSplit( aRefs, 
',' );
 
  254            return wxEmptyString;
 
  256        std::ranges::transform( refs, refs.begin(),
 
  257                                []( 
const wxString& aRef )
 
  259                                    return wxString::Format( wxT( 
"A.Reference == '%s'" ), aRef );
 
  262        wxString refsExpr = refs[0];
 
  264        if( refs.size() > 1 )
 
  266            for( 
auto itr = refs.begin() + 1; itr != refs.end(); ++itr )
 
  267                refsExpr = refsExpr + wxT( 
" || " ) + *itr;
 
  270        return wxString::Format( wxT( 
"( %s )" ), refsExpr );
 
  274    auto getFootprintExpr = []( wxString aFootprint ) -> wxString
 
  276        aFootprint.Trim( 
true ).Trim( 
false );
 
  278        if( aFootprint.empty() )
 
  279            return wxEmptyString;
 
  281        return wxString::Format( wxT( 
"( A.Library_Link == '%s' )" ), aFootprint );
 
  285    auto getSideExpr = []( 
const wxString& aSide ) -> wxString
 
  287        if( aSide == wxT( 
"Any" ) )
 
  288            return wxEmptyString;
 
  290        return wxString::Format( wxT( 
"( A.Layer == '%s' )" ),
 
  291                                 aSide == wxT( 
"Front" ) ? wxT( 
"F.Cu" ) : wxT( 
"B.Cu" ) );
 
  295    auto getRotationExpr = []( wxString aRotation ) -> wxString
 
  297        aRotation.Trim( 
true ).Trim( 
false );
 
  301        if( aRotation.empty() || aRotation == wxT( 
"Any" ) || !aRotation.ToInt( &
dummy ) )
 
  302            return wxEmptyString;
 
  304        return wxString::Format( wxT( 
"( A.Orientation == %s deg )" ), aRotation );
 
  309    auto getFootprintFieldExpr = []( wxString aFieldName, wxString aFieldMatch ) -> wxString
 
  311        aFieldName.Trim( 
true ).Trim( 
false );
 
  312        aFieldMatch.Trim( 
true ).Trim( 
false );
 
  314        if( aFieldName.empty() || aFieldMatch.empty() )
 
  315            return wxEmptyString;
 
  317        return wxString::Format( wxT( 
"( A.getField('%s') == '%s' )" ), aFieldName, aFieldMatch );
 
  321    auto getCustomFieldExpr = []( wxString aExpr ) -> wxString
 
  323        aExpr.Trim( 
true ).Trim( 
false );
 
  326            return wxEmptyString;
 
  328        return wxString::Format( wxT( 
"( %s )" ), aExpr );
 
  332    auto getSheetNameExpr = []( wxString aSheetName ) -> wxString
 
  334        aSheetName.Trim( 
true ).Trim( 
false );
 
  336        if( aSheetName.empty() )
 
  337            return wxEmptyString;
 
  339        return wxString::Format( wxT( 
"( A.memberOfSheet('%s') )" ), aSheetName );
 
  342    std::vector<wxString> conditionsExprs;
 
  344    for( 
auto& [conditionType, conditionData] : 
m_conditions )
 
  346        wxString conditionExpr;
 
  348        switch( conditionType )
 
  352            conditionExpr = getFootprintExpr( conditionData.first );
 
  356            conditionExpr = getRotationExpr( conditionData.first );
 
  359            conditionExpr = getFootprintFieldExpr( conditionData.first, conditionData.second );
 
  362            conditionExpr = getCustomFieldExpr( conditionData.first );
 
  365            conditionExpr = getSheetNameExpr( conditionData.first );
 
  369        if( !conditionExpr.empty() )
 
  370            conditionsExprs.push_back( conditionExpr );
 
  373    if( conditionsExprs.empty() )
 
  374        return wxString::Format( wxT( 
"(version 1) (assign_component_class \"%s\")" ),
 
  377    wxString allConditionsExpr = conditionsExprs[0];
 
  379    if( conditionsExprs.size() > 1 )
 
  381        wxString operatorExpr =
 
  384        for( 
auto itr = conditionsExprs.begin() + 1; itr != conditionsExprs.end(); ++itr )
 
  386            allConditionsExpr = allConditionsExpr + operatorExpr + *itr;
 
  390    return wxString::Format(
 
  391            wxT( 
"(version 1) (assign_component_class \"%s\" (condition \"%s\" ) )" ),
 
 
wxString GetAssignmentInDRCLanguage() const
Returns the DRC rules language for this component class assignment.
 
wxString m_componentClass
The name of the component class for this assignment rule.
 
static CONDITION_TYPE GetConditionType(const wxString &aCondition)
Maps a descriptive string to a CONDITION_TYPE.
 
void SetConditionsOperation(const CONDITIONS_OPERATOR aOperator)
Sets the boolean operation in use for all conditions.
 
CONDITION_TYPE
A condition match type.
 
static wxString GetConditionName(const CONDITION_TYPE aCondition)
Maps a CONDITION_TYPE to a descriptive string.
 
const std::unordered_map< CONDITION_TYPE, std::pair< wxString, wxString > > & GetConditions() const
Gets all conditions.
 
std::unordered_map< CONDITION_TYPE, std::pair< wxString, wxString > > m_conditions
Map of condition types to primary and secondary data fields for the condition.
 
void SetCondition(const CONDITION_TYPE aCondition, const wxString &aPrimaryData, const wxString &aSecondaryData)
Sets the given condition type with the assocated match data.
 
CONDITIONS_OPERATOR m_conditionsOperator
Whether conditions are applied with AND or OR logic Defaults to ALL.
 
void SetComponentClass(const wxString &aComponentClass)
Sets the resulting component class for matching footprints.
 
CONDITIONS_OPERATOR GetConditionsOperator() const
Gets the boolean operation in use for all conditions.
 
const wxString & GetComponentClass() const
Gets the resulting component class for matching footprints.
 
COMPONENT_CLASS_SETTINGS(JSON_SETTINGS *aParent, const std::string &aPath)
 
bool operator==(const COMPONENT_CLASS_SETTINGS &aOther) const
 
static nlohmann::json saveAssignment(const COMPONENT_CLASS_ASSIGNMENT_DATA &aAssignment)
Saves a dynamic component class assignment to JSON.
 
virtual ~COMPONENT_CLASS_SETTINGS()
 
void ClearComponentClassAssignments()
Clear all dynamic component class assignments.
 
std::vector< COMPONENT_CLASS_ASSIGNMENT_DATA > m_componentClassAssignments
All dynamic component class assignment rules.
 
static COMPONENT_CLASS_ASSIGNMENT_DATA loadAssignment(const nlohmann::json &aJson)
Loads a dynamic component class assignment from JSON.
 
bool m_enableSheetComponentClasses
Toggle generation of component classes for hierarchical sheets.
 
std::vector< PARAM_BASE * > m_params
The list of parameters (owned by this object)
 
JSON_SETTINGS(const wxString &aFilename, SETTINGS_LOC aLocation, int aSchemaVersion)
 
JSON_SETTINGS * m_parent
A pointer to the parent object to load and store from.
 
NESTED_SETTINGS(const std::string &aName, int aSchemaVersion, JSON_SETTINGS *aParent, const std::string &aPath, bool aLoadFromFile=true)
 
Like a normal param, but with custom getter and setter functions.
 
constexpr int componentClassSettingsSchemaVersion
 
std::vector< FAB_LAYER_COLOR > dummy