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 );
198 wxASSERT_MSG(
false,
"Invalid condition type" );
200 return wxEmptyString;
207 if( aCondition == wxT(
"REFERENCE" ) )
209 if( aCondition == wxT(
"FOOTPRINT" ) )
211 if( aCondition == wxT(
"SIDE" ) )
213 if( aCondition == wxT(
"ROTATION" ) )
215 if( aCondition == wxT(
"FOOTPRINT_FIELD" ) )
217 if( aCondition == wxT(
"CUSTOM" ) )
219 if( aCondition == wxT(
"SHEET_NAME" ) )
222 wxASSERT_MSG(
false,
"Invalid condition type" );
231 return wxEmptyString;
236 return wxString::Format( wxT(
"(version 1) (assign_component_class \"%s\")" ),
m_componentClass );
241 []( wxString aRefs ) -> wxString
243 aRefs.Trim(
true ).Trim(
false );
245 wxArrayString refs = wxSplit( aRefs,
',' );
248 return wxEmptyString;
250 std::ranges::transform( refs, refs.begin(),
251 [](
const wxString& aRef )
253 return wxString::Format( wxT(
"A.Reference == '%s'" ), aRef );
256 wxString refsExpr = refs[0];
258 if( refs.size() > 1 )
260 for(
auto itr = refs.begin() + 1; itr != refs.end(); ++itr )
261 refsExpr = refsExpr + wxT(
" || " ) + *itr;
264 return wxString::Format( wxT(
"( %s )" ), refsExpr );
268 auto getFootprintExpr =
269 []( wxString aFootprint ) -> wxString
271 aFootprint.Trim(
true ).Trim(
false );
273 if( aFootprint.empty() )
274 return wxEmptyString;
276 return wxString::Format( wxT(
"( A.Library_Link == '%s' )" ), aFootprint );
281 [](
const wxString& aSide ) -> wxString
283 if( aSide == wxT(
"Any" ) )
284 return wxEmptyString;
286 return wxString::Format( wxT(
"( A.Layer == '%s' )" ),
287 aSide == wxT(
"Front" ) ? wxT(
"F.Cu" ) : wxT(
"B.Cu" ) );
291 auto getRotationExpr =
292 []( wxString aRotation ) -> wxString
294 aRotation.Trim(
true ).Trim(
false );
298 if( aRotation.empty() || aRotation == wxT(
"Any" ) || !aRotation.ToInt( &
dummy ) )
299 return wxEmptyString;
301 return wxString::Format( wxT(
"( A.Orientation == %s deg )" ), aRotation );
306 auto getFootprintFieldExpr =
307 []( wxString aFieldName, wxString aFieldMatch ) -> wxString
309 aFieldName.Trim(
true ).Trim(
false );
310 aFieldMatch.Trim(
true ).Trim(
false );
312 if( aFieldName.empty() || aFieldMatch.empty() )
313 return wxEmptyString;
315 return wxString::Format( wxT(
"( A.getField('%s') == '%s' )" ), aFieldName, aFieldMatch );
319 auto getCustomFieldExpr =
320 []( wxString aExpr ) -> wxString
322 aExpr.Trim(
true ).Trim(
false );
325 return wxEmptyString;
327 return wxString::Format( wxT(
"( %s )" ), aExpr );
331 auto getSheetNameExpr =
332 []( 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, primaryData, secondaryData] :
m_conditions )
346 wxString conditionExpr;
348 switch( conditionType )
351 conditionExpr = getRefExpr( primaryData );
354 conditionExpr = getFootprintExpr( primaryData );
357 conditionExpr = getSideExpr( primaryData );
360 conditionExpr = getRotationExpr( primaryData );
363 conditionExpr = getFootprintFieldExpr( primaryData, secondaryData );
366 conditionExpr = getCustomFieldExpr( primaryData );
369 conditionExpr = getSheetNameExpr( primaryData );
373 if( !conditionExpr.empty() )
374 conditionsExprs.push_back( conditionExpr );
377 if( conditionsExprs.empty() )
378 return wxString::Format( wxT(
"(version 1) (assign_component_class \"%s\")" ),
m_componentClass );
380 wxString allConditionsExpr = conditionsExprs[0];
382 if( conditionsExprs.size() > 1 )
386 for(
auto itr = conditionsExprs.begin() + 1; itr != conditionsExprs.end(); ++itr )
387 allConditionsExpr = allConditionsExpr + operatorExpr + *itr;
390 return wxString::Format( wxT(
"(version 1) (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