20#include <nlohmann/json.hpp>
29 const std::string& aPath ) :
32 m_enableSheetComponentClasses( false )
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 )
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 stores data for component classes, including rules for automatic generation ...
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)
void ReleaseNestedSettings(NESTED_SETTINGS *aSettings)
Saves and frees a nested settings object, if it exists within this one.
NESTED_SETTINGS is a JSON_SETTINGS that lives inside a JSON_SETTINGS.
JSON_SETTINGS * m_parent
A pointer to the parent object to load and store from.
Like a normal param, but with custom getter and setter functions.
constexpr int componentClassSettingsSchemaVersion
std::vector< FAB_LAYER_COLOR > dummy