33 "sheet_component_classes",
34 [&]() -> nlohmann::json
36 nlohmann::json ret = {};
42 [&](
const nlohmann::json& aJson )
44 if( !aJson.is_object() )
47 if( !aJson.contains(
"enabled" ) )
56 [&]() -> nlohmann::json
58 nlohmann::json ret = nlohmann::json::array();
65 [&](
const nlohmann::json& aJson )
67 if( !aJson.is_array() )
72 for(
const nlohmann::json& assignmentJson : aJson )
87 m_parent->ReleaseNestedSettings(
this );
98 const wxString matchOperator =
104 ret[
"conditions_operator"] = matchOperator.ToUTF8();
106 nlohmann::json conditionsJson;
108 for(
const auto& [conditionType, primaryData, secondaryData] : aAssignment.
GetConditions() )
110 nlohmann::json conditionJson;
112 if( !primaryData.empty() )
113 conditionJson[
"primary"] = primaryData;
115 if( !secondaryData.empty() )
116 conditionJson[
"secondary"] = secondaryData;
120 wxString uniqueName = conditionName;
122 while( conditionsJson.contains( uniqueName ) )
123 uniqueName = wxString::Format( wxT(
"%s-%d" ), conditionName, suffix++ );
125 conditionsJson[uniqueName] = conditionJson;
128 ret[
"conditions"] = conditionsJson;
139 assignment.
SetComponentClass( wxString( aJson[
"component_class"].get<std::string>().c_str(), wxConvUTF8 ) );
141 const wxString matchOperator( aJson[
"conditions_operator"].get<std::string>().c_str(), wxConvUTF8 );
143 if( matchOperator == wxT(
"ALL" ) )
148 for(
const auto& [conditionTypeStr, conditionData] : aJson[
"conditions"].items() )
150 wxString primary, secondary;
151 wxString typeStr( conditionTypeStr );
153 typeStr = typeStr.BeforeFirst(
'-' );
158 if( conditionData.contains(
"primary" ) )
159 primary = wxString( conditionData[
"primary"].get<std::string>().c_str(), wxConvUTF8 );
161 if( conditionData.contains(
"secondary" ) )
162 secondary = wxString( conditionData[
"secondary"].get<std::string>().c_str(), wxConvUTF8 );
164 assignment.
AddCondition( conditionType, primary, secondary );
197 wxASSERT_MSG(
false,
"Invalid condition type" );
199 return wxEmptyString;
206 if( aCondition == wxT(
"REFERENCE" ) )
208 if( aCondition == wxT(
"FOOTPRINT" ) )
210 if( aCondition == wxT(
"SIDE" ) )
212 if( aCondition == wxT(
"ROTATION" ) )
214 if( aCondition == wxT(
"FOOTPRINT_FIELD" ) )
216 if( aCondition == wxT(
"CUSTOM" ) )
218 if( aCondition == wxT(
"SHEET_NAME" ) )
221 wxASSERT_MSG(
false,
"Invalid condition type" );
230 return wxEmptyString;
235 return wxString::Format( wxT(
"(version 2) (assign_component_class \"%s\")" ),
m_componentClass );
240 []( wxString aRefs ) -> wxString
242 aRefs.Trim(
true ).Trim(
false );
244 wxArrayString refs = wxSplit( aRefs,
',' );
247 return wxEmptyString;
249 std::ranges::transform( refs, refs.begin(),
250 [](
const wxString& aRef )
252 return wxString::Format( wxT(
"A.Reference == '%s'" ), aRef );
255 wxString refsExpr = refs[0];
257 if( refs.size() > 1 )
259 for(
auto itr = refs.begin() + 1; itr != refs.end(); ++itr )
260 refsExpr = refsExpr + wxT(
" || " ) + *itr;
263 return wxString::Format( wxT(
"( %s )" ), refsExpr );
267 auto getFootprintExpr =
268 []( wxString aFootprint ) -> wxString
270 aFootprint.Trim(
true ).Trim(
false );
272 if( aFootprint.empty() )
273 return wxEmptyString;
275 return wxString::Format( wxT(
"( A.Library_Link == '%s' )" ), aFootprint );
280 [](
const wxString& aSide ) -> wxString
282 if( aSide == wxT(
"Any" ) )
283 return wxEmptyString;
285 return wxString::Format( wxT(
"( A.Layer == '%s' )" ),
286 aSide == wxT(
"Front" ) ? wxT(
"F.Cu" ) : wxT(
"B.Cu" ) );
290 auto getRotationExpr =
291 []( wxString aRotation ) -> wxString
293 aRotation.Trim(
true ).Trim(
false );
297 if( aRotation.empty() || aRotation == wxT(
"Any" ) || !aRotation.ToInt( &
dummy ) )
298 return wxEmptyString;
300 return wxString::Format( wxT(
"( A.Orientation == %s deg )" ), aRotation );
305 auto getFootprintFieldExpr =
306 []( wxString aFieldName, wxString aFieldMatch ) -> wxString
308 aFieldName.Trim(
true ).Trim(
false );
309 aFieldMatch.Trim(
true ).Trim(
false );
311 if( aFieldName.empty() || aFieldMatch.empty() )
312 return wxEmptyString;
314 return wxString::Format( wxT(
"( A.getField('%s') == '%s' )" ), aFieldName, aFieldMatch );
318 auto getCustomFieldExpr =
319 []( wxString aExpr ) -> wxString
321 aExpr.Trim(
true ).Trim(
false );
324 return wxEmptyString;
326 return wxString::Format( wxT(
"( %s )" ), aExpr );
330 auto getSheetNameExpr =
331 []( wxString aSheetName ) -> wxString
333 aSheetName.Trim(
true ).Trim(
false );
335 if( aSheetName.empty() )
336 return wxEmptyString;
338 return wxString::Format( wxT(
"( A.memberOfSheet('%s') )" ), aSheetName );
341 std::vector<wxString> conditionsExprs;
343 for(
auto& [conditionType, primaryData, secondaryData] :
m_conditions )
345 wxString conditionExpr;
347 switch( conditionType )
350 conditionExpr = getRefExpr( primaryData );
353 conditionExpr = getFootprintExpr( primaryData );
356 conditionExpr = getSideExpr( primaryData );
359 conditionExpr = getRotationExpr( primaryData );
362 conditionExpr = getFootprintFieldExpr( primaryData, secondaryData );
365 conditionExpr = getCustomFieldExpr( primaryData );
368 conditionExpr = getSheetNameExpr( primaryData );
372 if( !conditionExpr.empty() )
373 conditionsExprs.push_back( conditionExpr );
376 if( conditionsExprs.empty() )
377 return wxString::Format( wxT(
"(version 2) (assign_component_class \"%s\")" ),
m_componentClass );
379 wxString allConditionsExpr = conditionsExprs[0];
381 if( conditionsExprs.size() > 1 )
385 for(
auto itr = conditionsExprs.begin() + 1; itr != conditionsExprs.end(); ++itr )
386 allConditionsExpr = allConditionsExpr + operatorExpr + *itr;
389 return wxString::Format( wxT(
"(version 2) (assign_component_class \"%s\" (condition \"%s\" ) )" ),
void AddCondition(const CONDITION_TYPE aCondition, const wxString &aPrimaryData, const wxString &aSecondaryData)
Sets the given condition type with the assocated match data.
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.
std::vector< std::tuple< CONDITION_TYPE, wxString, wxString > > m_conditions
Set of conditions with type, primary and secondary data fields for the condition.
const std::vector< std::tuple< CONDITION_TYPE, wxString, wxString > > & GetConditions() const
Gets all conditions.
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