56 changed files with 14037 additions and 1601 deletions
-
6common/CMakeLists.txt
-
1common/drc_rules.keywords
-
393common/project/component_class_settings.cpp
-
14common/project/project_file.cpp
-
434include/dialogs/panel_assign_component_classes.h
-
56include/dialogs/panel_generate_component_classes.h
-
160include/project/component_class_settings.h
-
10include/project/project_file.h
-
8pcbnew/CMakeLists.txt
-
29pcbnew/board.cpp
-
11pcbnew/board.h
-
36pcbnew/board_commit.cpp
-
210pcbnew/component_class_manager.cpp
-
140pcbnew/component_class_manager.h
-
100pcbnew/component_classes/component_class.cpp
-
106pcbnew/component_classes/component_class.h
-
38pcbnew/component_classes/component_class_assignment_rule.cpp
-
60pcbnew/component_classes/component_class_assignment_rule.h
-
48pcbnew/component_classes/component_class_cache_proxy.cpp
-
70pcbnew/component_classes/component_class_cache_proxy.h
-
507pcbnew/component_classes/component_class_manager.cpp
-
153pcbnew/component_classes/component_class_manager.h
-
22pcbnew/dialogs/dialog_board_setup.cpp
-
1pcbnew/dialogs/dialog_board_setup.h
-
3pcbnew/dialogs/dialog_import_settings.cpp
-
7pcbnew/dialogs/dialog_import_settings_base.cpp
-
2417pcbnew/dialogs/dialog_import_settings_base.fbp
-
3pcbnew/dialogs/dialog_import_settings_base.h
-
4pcbnew/dialogs/dialog_rule_area_properties.cpp
-
788pcbnew/dialogs/panel_assign_component_classes.cpp
-
471pcbnew/dialogs/panel_assign_component_classes_base.cpp
-
3121pcbnew/dialogs/panel_assign_component_classes_base.fbp
-
269pcbnew/dialogs/panel_assign_component_classes_base.h
-
3pcbnew/drc/drc_engine.cpp
-
150pcbnew/drc/drc_rule_parser.cpp
-
6pcbnew/drc/drc_rule_parser.h
-
11pcbnew/files.cpp
-
67pcbnew/footprint.cpp
-
29pcbnew/footprint.h
-
20pcbnew/netlist_reader/board_netlist_updater.cpp
-
7pcbnew/netlist_reader/netlist.cpp
-
11pcbnew/pcb_edit_frame.cpp
-
4pcbnew/pcb_io/kicad_sexpr/pcb_io_kicad_sexpr.cpp
-
8pcbnew/pcb_io/kicad_sexpr/pcb_io_kicad_sexpr.h
-
3pcbnew/pcb_io/kicad_sexpr/pcb_io_kicad_sexpr_parser.cpp
-
15pcbnew/pcbexpr_evaluator.cpp
-
1pcbnew/pcbexpr_functions.cpp
-
6pcbnew/tools/edit_tool.cpp
-
1pcbnew/tools/multichannel_tool.cpp
-
9pcbnew/undo_redo.cpp
-
3875qa/data/pcbnew/component_classes.kicad_pcb
-
761qa/data/pcbnew/component_classes.kicad_pro
-
784qa/data/pcbnew/component_classes.kicad_sch
-
11qa/pcbnew_utils/board_test_utils.cpp
-
1qa/tests/pcbnew/CMakeLists.txt
-
159qa/tests/pcbnew/test_component_classes.cpp
@ -0,0 +1,393 @@ |
|||
/*
|
|||
* This program source code file is part of KiCad, a free EDA CAD application. |
|||
* |
|||
* Copyright The KiCad Developers, see AUTHORS.txt for contributors. |
|||
* |
|||
* This program is free software: you can redistribute it and/or modify it |
|||
* under the terms of the GNU General Public License as published by the |
|||
* Free Software Foundation, either version 3 of the License, or (at your |
|||
* option) any later version. |
|||
* |
|||
* This program is distributed in the hope that it will be useful, but |
|||
* WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|||
* General Public License for more details. |
|||
* |
|||
* You should have received a copy of the GNU General Public License along |
|||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/ |
|||
|
|||
#include <nlohmann/json.hpp>
|
|||
|
|||
#include <project/component_class_settings.h>
|
|||
#include <settings/parameters.h>
|
|||
|
|||
constexpr int componentClassSettingsSchemaVersion = 0; |
|||
|
|||
|
|||
COMPONENT_CLASS_SETTINGS::COMPONENT_CLASS_SETTINGS( JSON_SETTINGS* aParent, |
|||
const std::string& aPath ) : |
|||
NESTED_SETTINGS( "component_class_settings", componentClassSettingsSchemaVersion, aParent, |
|||
aPath, false ), |
|||
m_enableSheetComponentClasses( false ) |
|||
{ |
|||
m_params.emplace_back( new PARAM_LAMBDA<nlohmann::json>( |
|||
"sheet_component_classes", |
|||
[&]() -> nlohmann::json |
|||
{ |
|||
nlohmann::json ret = {}; |
|||
|
|||
ret["enabled"] = m_enableSheetComponentClasses; |
|||
|
|||
return ret; |
|||
}, |
|||
[&]( const nlohmann::json& aJson ) |
|||
{ |
|||
if( !aJson.is_object() ) |
|||
return; |
|||
|
|||
if( !aJson.contains( "enabled" ) ) |
|||
return; |
|||
|
|||
m_enableSheetComponentClasses = aJson["enabled"].get<bool>(); |
|||
}, |
|||
{} ) ); |
|||
|
|||
m_params.emplace_back( new PARAM_LAMBDA<nlohmann::json>( |
|||
"assignments", |
|||
[&]() -> nlohmann::json |
|||
{ |
|||
nlohmann::json ret = nlohmann::json::array(); |
|||
|
|||
for( const COMPONENT_CLASS_ASSIGNMENT_DATA& assignment : |
|||
m_componentClassAssignments ) |
|||
{ |
|||
ret.push_back( saveAssignment( assignment ) ); |
|||
} |
|||
|
|||
return ret; |
|||
}, |
|||
[&]( const nlohmann::json& aJson ) |
|||
{ |
|||
if( !aJson.is_array() ) |
|||
return; |
|||
|
|||
ClearComponentClassAssignments(); |
|||
|
|||
for( const auto& assignmentJson : aJson ) |
|||
{ |
|||
COMPONENT_CLASS_ASSIGNMENT_DATA assignment = loadAssignment( assignmentJson ); |
|||
m_componentClassAssignments.push_back( assignment ); |
|||
} |
|||
}, |
|||
{} ) ); |
|||
} |
|||
|
|||
|
|||
COMPONENT_CLASS_SETTINGS::~COMPONENT_CLASS_SETTINGS() |
|||
{ |
|||
// Release early before destroying members
|
|||
if( m_parent ) |
|||
{ |
|||
m_parent->ReleaseNestedSettings( this ); |
|||
m_parent = nullptr; |
|||
} |
|||
} |
|||
|
|||
|
|||
nlohmann::json |
|||
COMPONENT_CLASS_SETTINGS::saveAssignment( const COMPONENT_CLASS_ASSIGNMENT_DATA& aAssignment ) |
|||
{ |
|||
nlohmann::json ret; |
|||
|
|||
const wxString matchOperator = |
|||
aAssignment.GetConditionsOperator() |
|||
== COMPONENT_CLASS_ASSIGNMENT_DATA::CONDITIONS_OPERATOR::ALL |
|||
? wxT( "ALL" ) |
|||
: wxT( "ANY" ); |
|||
|
|||
ret["component_class"] = aAssignment.GetComponentClass().ToUTF8(); |
|||
ret["conditions_operator"] = matchOperator.ToUTF8(); |
|||
|
|||
nlohmann::json conditionsJson; |
|||
|
|||
for( const auto& [conditionType, conditionData] : aAssignment.GetConditions() ) |
|||
{ |
|||
nlohmann::json conditionJson; |
|||
|
|||
if( !conditionData.first.empty() ) |
|||
conditionJson["primary"] = conditionData.first; |
|||
|
|||
if( !conditionData.second.empty() ) |
|||
conditionJson["secondary"] = conditionData.second; |
|||
|
|||
const wxString conditionName = |
|||
COMPONENT_CLASS_ASSIGNMENT_DATA::GetConditionName( conditionType ); |
|||
conditionsJson[conditionName] = conditionJson; |
|||
} |
|||
|
|||
ret["conditions"] = conditionsJson; |
|||
|
|||
return ret; |
|||
} |
|||
|
|||
|
|||
COMPONENT_CLASS_ASSIGNMENT_DATA |
|||
COMPONENT_CLASS_SETTINGS::loadAssignment( const nlohmann::json& aJson ) |
|||
{ |
|||
COMPONENT_CLASS_ASSIGNMENT_DATA assignment; |
|||
|
|||
assignment.SetComponentClass( |
|||
wxString( aJson["component_class"].get<std::string>().c_str(), wxConvUTF8 ) ); |
|||
|
|||
const wxString matchOperator( aJson["conditions_operator"].get<std::string>().c_str(), |
|||
wxConvUTF8 ); |
|||
|
|||
if( matchOperator == wxT( "ALL" ) ) |
|||
{ |
|||
assignment.SetConditionsOperation( |
|||
COMPONENT_CLASS_ASSIGNMENT_DATA::CONDITIONS_OPERATOR::ALL ); |
|||
} |
|||
else |
|||
{ |
|||
assignment.SetConditionsOperation( |
|||
COMPONENT_CLASS_ASSIGNMENT_DATA::CONDITIONS_OPERATOR::ANY ); |
|||
} |
|||
|
|||
for( const auto& [conditionTypeStr, conditionData] : aJson["conditions"].items() ) |
|||
{ |
|||
wxString primary, secondary; |
|||
COMPONENT_CLASS_ASSIGNMENT_DATA::CONDITION_TYPE conditionType = |
|||
COMPONENT_CLASS_ASSIGNMENT_DATA::GetConditionType( conditionTypeStr ); |
|||
|
|||
if( conditionData.contains( "primary" ) ) |
|||
primary = wxString( conditionData["primary"].get<std::string>().c_str(), wxConvUTF8 ); |
|||
|
|||
if( conditionData.contains( "secondary" ) ) |
|||
secondary = |
|||
wxString( conditionData["secondary"].get<std::string>().c_str(), wxConvUTF8 ); |
|||
|
|||
assignment.SetCondition( conditionType, primary, secondary ); |
|||
} |
|||
|
|||
return assignment; |
|||
} |
|||
|
|||
|
|||
bool COMPONENT_CLASS_SETTINGS::operator==( const COMPONENT_CLASS_SETTINGS& aOther ) const |
|||
{ |
|||
// TODO: Implement this
|
|||
throw; |
|||
//return true;
|
|||
} |
|||
|
|||
|
|||
/**************************************************************************************************
|
|||
* |
|||
* COMPONENT_CLASS_ASSIGNMENT_DATA implementation |
|||
* |
|||
*************************************************************************************************/ |
|||
|
|||
wxString COMPONENT_CLASS_ASSIGNMENT_DATA::GetConditionName( const CONDITION_TYPE aCondition ) |
|||
{ |
|||
switch( aCondition ) |
|||
{ |
|||
case CONDITION_TYPE::REFERENCE: return wxT( "REFERENCE" ); |
|||
case CONDITION_TYPE::FOOTPRINT: return wxT( "FOOTPRINT" ); |
|||
case CONDITION_TYPE::SIDE: return wxT( "SIDE" ); |
|||
case CONDITION_TYPE::ROTATION: return wxT( "ROTATION" ); |
|||
case CONDITION_TYPE::FOOTPRINT_FIELD: return wxT( "FOOTPRINT_FIELD" ); |
|||
case CONDITION_TYPE::CUSTOM: return wxT( "CUSTOM" ); |
|||
case CONDITION_TYPE::SHEET_NAME: return wxT( "SHEET_NAME" ); |
|||
} |
|||
|
|||
wxASSERT_MSG( false, "Invalid condition type" ); |
|||
|
|||
return wxEmptyString; |
|||
} |
|||
|
|||
|
|||
COMPONENT_CLASS_ASSIGNMENT_DATA::CONDITION_TYPE |
|||
COMPONENT_CLASS_ASSIGNMENT_DATA::GetConditionType( const wxString& aCondition ) |
|||
{ |
|||
if( aCondition == wxT( "REFERENCE" ) ) |
|||
return CONDITION_TYPE::REFERENCE; |
|||
if( aCondition == wxT( "FOOTPRINT" ) ) |
|||
return CONDITION_TYPE::FOOTPRINT; |
|||
if( aCondition == wxT( "SIDE" ) ) |
|||
return CONDITION_TYPE::SIDE; |
|||
if( aCondition == wxT( "ROTATION" ) ) |
|||
return CONDITION_TYPE::ROTATION; |
|||
if( aCondition == wxT( "FOOTPRINT_FIELD" ) ) |
|||
return CONDITION_TYPE::FOOTPRINT_FIELD; |
|||
if( aCondition == wxT( "CUSTOM" ) ) |
|||
return CONDITION_TYPE::CUSTOM; |
|||
if( aCondition == wxT( "SHEET_NAME" ) ) |
|||
return CONDITION_TYPE::SHEET_NAME; |
|||
|
|||
wxASSERT_MSG( false, "Invalid condition type" ); |
|||
|
|||
return CONDITION_TYPE::REFERENCE; |
|||
} |
|||
|
|||
|
|||
wxString COMPONENT_CLASS_ASSIGNMENT_DATA::GetAssignmentInDRCLanguage() const |
|||
{ |
|||
if( m_componentClass.empty() ) |
|||
return wxEmptyString; |
|||
|
|||
if( m_conditions.empty() ) |
|||
{ |
|||
// A condition which always applies the netclass
|
|||
return wxString::Format( wxT( "(version 1) (assign_component_class \"%s\")" ), |
|||
m_componentClass ); |
|||
} |
|||
|
|||
// Lambda to format a comma-separated list of references in to a DRC expression
|
|||
auto getRefExpr = []( wxString aRefs ) -> wxString |
|||
{ |
|||
aRefs.Trim( true ).Trim( false ); |
|||
|
|||
wxArrayString refs = wxSplit( aRefs, ',' ); |
|||
|
|||
if( refs.empty() ) |
|||
return wxEmptyString; |
|||
|
|||
std::ranges::transform( refs, refs.begin(), |
|||
[]( const wxString& aRef ) |
|||
{ |
|||
return wxString::Format( wxT( "A.Reference == '%s'" ), aRef ); |
|||
} ); |
|||
|
|||
wxString refsExpr = refs[0]; |
|||
|
|||
if( refs.size() > 1 ) |
|||
{ |
|||
for( auto itr = refs.begin() + 1; itr != refs.end(); ++itr ) |
|||
refsExpr = refsExpr + wxT( " || " ) + *itr; |
|||
} |
|||
|
|||
return wxString::Format( wxT( "( %s )" ), refsExpr ); |
|||
}; |
|||
|
|||
// Lambda to format a footprint match DRC expression
|
|||
auto getFootprintExpr = []( wxString aFootprint ) -> wxString |
|||
{ |
|||
aFootprint.Trim( true ).Trim( false ); |
|||
|
|||
if( aFootprint.empty() ) |
|||
return wxEmptyString; |
|||
|
|||
return wxString::Format( wxT( "( A.Library_Link == '%s' )" ), aFootprint ); |
|||
}; |
|||
|
|||
// Lambda to format a layer side DRC expression
|
|||
auto getSideExpr = []( const wxString& aSide ) -> wxString |
|||
{ |
|||
if( aSide == wxT( "Any" ) ) |
|||
return wxEmptyString; |
|||
|
|||
return wxString::Format( wxT( "( A.Layer == '%s' )" ), |
|||
aSide == wxT( "Front" ) ? wxT( "F.Cu" ) : wxT( "B.Cu" ) ); |
|||
}; |
|||
|
|||
// Lambda to format a rotation DRC expression
|
|||
auto getRotationExpr = []( wxString aRotation ) -> wxString |
|||
{ |
|||
aRotation.Trim( true ).Trim( false ); |
|||
|
|||
int dummy; |
|||
|
|||
if( aRotation.empty() || aRotation == wxT( "Any" ) || !aRotation.ToInt( &dummy ) ) |
|||
return wxEmptyString; |
|||
|
|||
return wxString::Format( wxT( "( A.Orientation == %s deg )" ), aRotation ); |
|||
}; |
|||
|
|||
|
|||
// Lambda to format a footprint field DRC expression
|
|||
auto getFootprintFieldExpr = []( wxString aFieldName, wxString aFieldMatch ) -> wxString |
|||
{ |
|||
aFieldName.Trim( true ).Trim( false ); |
|||
aFieldMatch.Trim( true ).Trim( false ); |
|||
|
|||
if( aFieldName.empty() || aFieldMatch.empty() ) |
|||
return wxEmptyString; |
|||
|
|||
return wxString::Format( wxT( "( A.getField('%s') == '%s' )" ), aFieldName, aFieldMatch ); |
|||
}; |
|||
|
|||
// Lambda to format a custom DRC expression
|
|||
auto getCustomFieldExpr = []( wxString aExpr ) -> wxString |
|||
{ |
|||
aExpr.Trim( true ).Trim( false ); |
|||
|
|||
if( aExpr.empty() ) |
|||
return wxEmptyString; |
|||
|
|||
return wxString::Format( wxT( "( %s )" ), aExpr ); |
|||
}; |
|||
|
|||
// Lambda to format a sheet name expression
|
|||
auto getSheetNameExpr = []( wxString aSheetName ) -> wxString |
|||
{ |
|||
aSheetName.Trim( true ).Trim( false ); |
|||
|
|||
if( aSheetName.empty() ) |
|||
return wxEmptyString; |
|||
|
|||
return wxString::Format( wxT( "( A.memberOfSheet('%s') )" ), aSheetName ); |
|||
}; |
|||
|
|||
std::vector<wxString> conditionsExprs; |
|||
|
|||
for( auto& [conditionType, conditionData] : m_conditions ) |
|||
{ |
|||
wxString conditionExpr; |
|||
|
|||
switch( conditionType ) |
|||
{ |
|||
case CONDITION_TYPE::REFERENCE: conditionExpr = getRefExpr( conditionData.first ); break; |
|||
case CONDITION_TYPE::FOOTPRINT: |
|||
conditionExpr = getFootprintExpr( conditionData.first ); |
|||
break; |
|||
case CONDITION_TYPE::SIDE: conditionExpr = getSideExpr( conditionData.first ); break; |
|||
case CONDITION_TYPE::ROTATION: |
|||
conditionExpr = getRotationExpr( conditionData.first ); |
|||
break; |
|||
case CONDITION_TYPE::FOOTPRINT_FIELD: |
|||
conditionExpr = getFootprintFieldExpr( conditionData.first, conditionData.second ); |
|||
break; |
|||
case CONDITION_TYPE::CUSTOM: |
|||
conditionExpr = getCustomFieldExpr( conditionData.first ); |
|||
break; |
|||
case CONDITION_TYPE::SHEET_NAME: |
|||
conditionExpr = getSheetNameExpr( conditionData.first ); |
|||
break; |
|||
} |
|||
|
|||
if( !conditionExpr.empty() ) |
|||
conditionsExprs.push_back( conditionExpr ); |
|||
} |
|||
|
|||
if( conditionsExprs.empty() ) |
|||
return wxString::Format( wxT( "(version 1) (assign_component_class \"%s\")" ), |
|||
m_componentClass ); |
|||
|
|||
wxString allConditionsExpr = conditionsExprs[0]; |
|||
|
|||
if( conditionsExprs.size() > 1 ) |
|||
{ |
|||
wxString operatorExpr = |
|||
m_conditionsOperator == CONDITIONS_OPERATOR::ALL ? wxT( " && " ) : wxT( " || " ); |
|||
|
|||
for( auto itr = conditionsExprs.begin() + 1; itr != conditionsExprs.end(); ++itr ) |
|||
{ |
|||
allConditionsExpr = allConditionsExpr + operatorExpr + *itr; |
|||
} |
|||
} |
|||
|
|||
return wxString::Format( |
|||
wxT( "(version 1) (assign_component_class \"%s\" (condition \"%s\" ) )" ), |
|||
m_componentClass, allConditionsExpr ); |
|||
} |
|||
@ -0,0 +1,434 @@ |
|||
/* |
|||
* This program source code file is part of KiCad, a free EDA CAD application. |
|||
* |
|||
* Copyright The KiCad Developers, see AUTHORS.txt for contributors. |
|||
* |
|||
* This program is free software; you can redistribute it and/or |
|||
* modify it under the terms of the GNU General Public License |
|||
* as published by the Free Software Foundation; either version 2 |
|||
* of the License, or (at your option) any later version. |
|||
* |
|||
* This program is distributed in the hope that it will be useful, |
|||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
* GNU General Public License for more details. |
|||
* |
|||
* You should have received a copy of the GNU General Public License |
|||
* along with this program; if not, you may find one here: |
|||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html |
|||
* or you may search the http://www.gnu.org website for the version 2 license, |
|||
* or you may write to the Free Software Foundation, Inc., |
|||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA |
|||
*/ |
|||
|
|||
|
|||
#ifndef PANEL_ASSIGN_COMPONENT_CLASSES_H |
|||
#define PANEL_ASSIGN_COMPONENT_CLASSES_H |
|||
|
|||
|
|||
#include <panel_assign_component_classes_base.h> |
|||
|
|||
#include <unordered_set> |
|||
#include <vector> |
|||
|
|||
#include <dialog_shim.h> |
|||
#include <pcb_edit_frame.h> |
|||
#include <project/component_class_settings.h> |
|||
|
|||
|
|||
/************************************************************************************************** |
|||
* |
|||
* PANEL_ASSIGN_COMPONENT_CLASSES |
|||
* |
|||
*************************************************************************************************/ |
|||
|
|||
/** |
|||
* Top-level panel for dynamic component class assignment configuration. Nests a |
|||
* PANEL_COMPONENT_CLASS_ASSIGNMENT panel for each set of component class assignment conditions |
|||
*/ |
|||
class PANEL_COMPONENT_CLASS_ASSIGNMENT; |
|||
|
|||
class PANEL_ASSIGN_COMPONENT_CLASSES : public PANEL_ASSIGN_COMPONENT_CLASSES_BASE |
|||
{ |
|||
public: |
|||
PANEL_ASSIGN_COMPONENT_CLASSES( wxWindow* aParentWindow, PCB_EDIT_FRAME* aFrame, |
|||
std::shared_ptr<COMPONENT_CLASS_SETTINGS> aSettings, |
|||
DIALOG_SHIM* aDlg ); |
|||
|
|||
~PANEL_ASSIGN_COMPONENT_CLASSES() override; |
|||
|
|||
/// Loads current component class assignments from the board settings |
|||
bool TransferDataToWindow() override; |
|||
|
|||
/// Saves the component class assignments to the board settings |
|||
bool TransferDataFromWindow() override; |
|||
|
|||
/// Loads component class assignments from the given settings object |
|||
void ImportSettingsFrom( const std::shared_ptr<COMPONENT_CLASS_SETTINGS>& aOtherSettings ); |
|||
|
|||
/// Adds a new component class assignment rule |
|||
void OnAddAssignmentClick( wxCommandEvent& event ) override; |
|||
|
|||
/// Removes a given component class assignment rule |
|||
void RemoveAssignment( PANEL_COMPONENT_CLASS_ASSIGNMENT* aPanel ); |
|||
|
|||
/// Returns references for all currently selected footprints |
|||
const std::vector<wxString>& GetSelectionRefs() const { return m_selectionRefs; } |
|||
|
|||
/// Returns names of all fields present in footprints |
|||
const std::vector<wxString>& GetFieldNames() const { return m_fieldNames; } |
|||
|
|||
/// Returns names of all sheets present in footprints |
|||
const std::vector<wxString>& GetSheetNames() const { return m_sheetNames; } |
|||
|
|||
/// Gets the active edit frame |
|||
PCB_EDIT_FRAME* GetFrame() const { return m_frame; } |
|||
|
|||
/// Validates that all assignment rules can compile successfully |
|||
bool Validate() override; |
|||
|
|||
private: |
|||
/// Adds a new component class assignment rule |
|||
PANEL_COMPONENT_CLASS_ASSIGNMENT* addAssignment(); |
|||
|
|||
/// Scrolls the panel to specified assignment rule |
|||
void scrollToAssignment( const PANEL_COMPONENT_CLASS_ASSIGNMENT* aAssignment ) const; |
|||
|
|||
/// The parent dialog |
|||
DIALOG_SHIM* m_dlg; |
|||
|
|||
/// The active edit frame |
|||
PCB_EDIT_FRAME* m_frame; |
|||
|
|||
/// Vector of all currently displayed assignment rules |
|||
std::vector<PANEL_COMPONENT_CLASS_ASSIGNMENT*> m_assignments; |
|||
|
|||
/// The active settings object |
|||
std::shared_ptr<COMPONENT_CLASS_SETTINGS> m_componentClassSettings; |
|||
|
|||
/// All currently selected footprint references |
|||
std::vector<wxString> m_selectionRefs; |
|||
|
|||
/// All footprint fields names present on the board |
|||
std::vector<wxString> m_fieldNames; |
|||
|
|||
/// All sheet names present on the board |
|||
std::vector<wxString> m_sheetNames; |
|||
|
|||
/// The list of all currently present component class assignments |
|||
wxBoxSizer* m_assignmentsList; |
|||
}; |
|||
|
|||
|
|||
/************************************************************************************************** |
|||
* |
|||
* CONDITION_DATA |
|||
* |
|||
*************************************************************************************************/ |
|||
|
|||
/** |
|||
* Class used to provide a unified interface from condition panels |
|||
* Handles determining the type of condition in use, and getting and settings the field data |
|||
*/ |
|||
class CONDITION_DATA |
|||
{ |
|||
public: |
|||
CONDITION_DATA( const COMPONENT_CLASS_ASSIGNMENT_DATA::CONDITION_TYPE aCondition, |
|||
wxTextEntry* aPrimary, wxTextEntry* aSecondary = nullptr ) : |
|||
m_conditionType( aCondition ), m_primaryCtrl( aPrimary ), m_secondaryCtrl( aSecondary ) |
|||
{ |
|||
} |
|||
|
|||
virtual ~CONDITION_DATA() {}; |
|||
|
|||
/// Gets the type of condition (e.g. Reference, Side) this data represents |
|||
virtual COMPONENT_CLASS_ASSIGNMENT_DATA::CONDITION_TYPE GetConditionType() const |
|||
{ |
|||
return m_conditionType; |
|||
} |
|||
|
|||
/// Gets the primary data member for the condition (e.g. Reference, Side) |
|||
virtual wxString GetPrimaryField() const; |
|||
|
|||
/// Sets the primary data member for the condition (e.g. Reference, Side) |
|||
virtual void SetPrimaryField( const wxString& aVal ); |
|||
|
|||
/// Gets the primary data member for the condition (e.g. FOOTPRITNT field value) |
|||
virtual wxString GetSecondaryField() const; |
|||
|
|||
/// Sets the primary data member for the condition (e.g. FOOTPRITNT field |
|||
/// value) |
|||
virtual void SetSecondaryField( const wxString& aVal ); |
|||
|
|||
private: |
|||
/// The type of condition being referenced |
|||
COMPONENT_CLASS_ASSIGNMENT_DATA::CONDITION_TYPE m_conditionType; |
|||
|
|||
/// The primary data field in the condition panel |
|||
wxTextEntry* m_primaryCtrl; |
|||
|
|||
/// The Secondary data field in the condition panel |
|||
wxTextEntry* m_secondaryCtrl; |
|||
}; |
|||
|
|||
|
|||
/************************************************************************************************** |
|||
* |
|||
* PANEL_COMPONENT_CLASS_ASSIGNMENT |
|||
* |
|||
*************************************************************************************************/ |
|||
|
|||
/** |
|||
* Panel which configures a set of conditions for a component class assignment rule |
|||
*/ |
|||
class PANEL_COMPONENT_CLASS_ASSIGNMENT : public PANEL_COMPONENT_CLASS_ASSIGNMENT_BASE |
|||
{ |
|||
public: |
|||
/// IDs for match type popup menu |
|||
enum ADD_MATCH_POPUP |
|||
{ |
|||
ID_REFERENCE = wxID_HIGHEST + 1, |
|||
ID_FOOTPRINT, |
|||
ID_SIDE, |
|||
ID_ROTATION, |
|||
ID_FOOTPRINT_FIELD, |
|||
ID_SHEET_NAME, |
|||
ID_CUSTOM |
|||
}; |
|||
|
|||
PANEL_COMPONENT_CLASS_ASSIGNMENT( wxWindow* aParent, |
|||
PANEL_ASSIGN_COMPONENT_CLASSES* aPanelParent, |
|||
DIALOG_SHIM* aDlg ); |
|||
~PANEL_COMPONENT_CLASS_ASSIGNMENT(); |
|||
|
|||
/// Deletes this component class assignment rule |
|||
void OnDeleteAssignmentClick( wxCommandEvent& event ) override; |
|||
|
|||
/// Adds a match condition to this component class assignment rule |
|||
void OnAddConditionClick( wxCommandEvent& event ) override; |
|||
|
|||
/// Highlights footprints matching this set of conditions |
|||
void OnHighlightItemsClick( wxCommandEvent& event ) override; |
|||
|
|||
/// Adds a condition to this component class assignment rule |
|||
CONDITION_DATA* AddCondition( COMPONENT_CLASS_ASSIGNMENT_DATA::CONDITION_TYPE aCondition ); |
|||
|
|||
/// Removes a given condition from this component class assignment rule (note: called from the child |
|||
/// condition panel) |
|||
void RemoveCondition( wxPanel* aMatch ); |
|||
|
|||
const std::vector<CONDITION_DATA*>& GetConditions() const { return m_matches; } |
|||
|
|||
/// Sets the resulting component class for this assignment |
|||
void SetComponentClass( const wxString& aComponentClass ) const; |
|||
|
|||
/// Gets the resulting component class for this assignment |
|||
const wxString GetComponentClass() const; |
|||
|
|||
/// Sets the boolean operator applied to all assignment conditions |
|||
void |
|||
SetConditionsOperator( COMPONENT_CLASS_ASSIGNMENT_DATA::CONDITIONS_OPERATOR aCondition ) const; |
|||
|
|||
/// Gets the boolean operator applied to all assignment conditions |
|||
COMPONENT_CLASS_ASSIGNMENT_DATA::CONDITIONS_OPERATOR GetConditionsOperator() const; |
|||
|
|||
/// Converts the UI representation in to the internal assignment data representation |
|||
COMPONENT_CLASS_ASSIGNMENT_DATA GenerateAssignmentData() const; |
|||
|
|||
protected: |
|||
/// Handles add match condition popup menu selections |
|||
void onMenu( wxCommandEvent& aEvent ); |
|||
|
|||
/// The top-level configuration panel which owns this assignment rule |
|||
PANEL_ASSIGN_COMPONENT_CLASSES* m_parentPanel; |
|||
|
|||
/// The sizer containing match condition panels |
|||
wxStaticBoxSizer* m_matchesList; |
|||
|
|||
/// Set containing all currently configured match condition types |
|||
std::unordered_set<COMPONENT_CLASS_ASSIGNMENT_DATA::CONDITION_TYPE> m_conditionTypes; |
|||
|
|||
/// The parent configuration dialog |
|||
DIALOG_SHIM* m_dlg; |
|||
|
|||
/// All match conditions for this component class assignment rule |
|||
std::vector<CONDITION_DATA*> m_matches; |
|||
}; |
|||
|
|||
|
|||
/************************************************************************************************** |
|||
* |
|||
* PANEL_COMPONENT_CLASS_CONDITION_REFERENCE |
|||
* |
|||
*************************************************************************************************/ |
|||
|
|||
/** |
|||
* Configures matching based on footprint reference |
|||
*/ |
|||
class PANEL_COMPONENT_CLASS_CONDITION_REFERENCE |
|||
: public PANEL_COMPONENT_CLASS_CONDITION_REFERENCE_BASE, |
|||
public CONDITION_DATA |
|||
{ |
|||
public: |
|||
/// IDs for match type popup menu |
|||
enum IMPORT_POPUP_IDS |
|||
{ |
|||
ID_IMPORT_REFS = wxID_HIGHEST + 1 |
|||
}; |
|||
|
|||
explicit PANEL_COMPONENT_CLASS_CONDITION_REFERENCE( wxWindow* aParent ); |
|||
|
|||
void OnDeleteConditionClick( wxCommandEvent& event ) override; |
|||
|
|||
void OnImportRefsClick( wxCommandEvent& event ) override; |
|||
void SetSelectionRefs( const std::vector<wxString>& aRefs ) { m_selectionRefs = aRefs; } |
|||
|
|||
protected: |
|||
/// Handles import references popup menu selections |
|||
void onMenu( wxCommandEvent& aEvent ); |
|||
|
|||
PANEL_COMPONENT_CLASS_ASSIGNMENT* m_panelParent; |
|||
std::vector<wxString> m_selectionRefs; |
|||
}; |
|||
|
|||
|
|||
/************************************************************************************************** |
|||
* |
|||
* PANEL_COMPONENT_CLASS_CONDITION_FOOTPRINT |
|||
* |
|||
*************************************************************************************************/ |
|||
|
|||
/** |
|||
* Configures matching based on footprint library identifier |
|||
*/ |
|||
class PANEL_COMPONENT_CLASS_CONDITION_FOOTPRINT |
|||
: public PANEL_COMPONENT_CLASS_CONDITION_FOOTPRINT_BASE, |
|||
public CONDITION_DATA |
|||
{ |
|||
public: |
|||
explicit PANEL_COMPONENT_CLASS_CONDITION_FOOTPRINT( wxWindow* aParent, DIALOG_SHIM* aDlg ); |
|||
|
|||
void OnDeleteConditionClick( wxCommandEvent& event ) override; |
|||
void OnShowLibraryClick( wxCommandEvent& event ) override; |
|||
|
|||
protected: |
|||
PANEL_COMPONENT_CLASS_ASSIGNMENT* m_panelParent; |
|||
DIALOG_SHIM* m_dlg; |
|||
}; |
|||
|
|||
|
|||
/************************************************************************************************** |
|||
* |
|||
* PANEL_COMPONENT_CLASS_CONDITION_SIDE |
|||
* |
|||
*************************************************************************************************/ |
|||
|
|||
/** |
|||
* Configures matching based on which side of the board a footprint is on |
|||
*/ |
|||
class PANEL_COMPONENT_CLASS_CONDITION_SIDE : public PANEL_COMPONENT_CLASS_CONDITION_SIDE_BASE, |
|||
public CONDITION_DATA |
|||
{ |
|||
public: |
|||
explicit PANEL_COMPONENT_CLASS_CONDITION_SIDE( wxWindow* aParent ); |
|||
|
|||
void OnDeleteConditionClick( wxCommandEvent& event ) override; |
|||
|
|||
protected: |
|||
PANEL_COMPONENT_CLASS_ASSIGNMENT* m_panelParent; |
|||
}; |
|||
|
|||
|
|||
/************************************************************************************************** |
|||
* |
|||
* PANEL_COMPONENT_CLASS_CONDITION_ROTATION |
|||
* |
|||
*************************************************************************************************/ |
|||
|
|||
/** |
|||
* Configures matching based on footprint rotation |
|||
*/ |
|||
class PANEL_COMPONENT_CLASS_CONDITION_ROTATION |
|||
: public PANEL_COMPONENT_CLASS_CONDITION_ROTATION_BASE, |
|||
public CONDITION_DATA |
|||
{ |
|||
public: |
|||
explicit PANEL_COMPONENT_CLASS_CONDITION_ROTATION( wxWindow* aParent ); |
|||
|
|||
void OnDeleteConditionClick( wxCommandEvent& event ) override; |
|||
|
|||
protected: |
|||
PANEL_COMPONENT_CLASS_ASSIGNMENT* m_panelParent; |
|||
}; |
|||
|
|||
|
|||
/************************************************************************************************** |
|||
* |
|||
* PANEL_COMPONENT_CLASS_CONDITION_FIELD |
|||
* |
|||
*************************************************************************************************/ |
|||
|
|||
/** |
|||
* Configures matching based on footprint field contents |
|||
*/ |
|||
class PANEL_COMPONENT_CLASS_CONDITION_FIELD : public PANEL_COMPONENT_CLASS_CONDITION_FIELD_BASE, |
|||
public CONDITION_DATA |
|||
{ |
|||
public: |
|||
explicit PANEL_COMPONENT_CLASS_CONDITION_FIELD( wxWindow* aParent ); |
|||
|
|||
void OnDeleteConditionClick( wxCommandEvent& event ) override; |
|||
|
|||
void SetFieldsList( const std::vector<wxString>& aFields ); |
|||
|
|||
protected: |
|||
PANEL_COMPONENT_CLASS_ASSIGNMENT* m_panelParent; |
|||
}; |
|||
|
|||
|
|||
/************************************************************************************************** |
|||
* |
|||
* PANEL_COMPONENT_CLASS_CONDITION_CUSTOM |
|||
* |
|||
*************************************************************************************************/ |
|||
|
|||
/** |
|||
* Configures matching based on a custom DRC expression |
|||
*/ |
|||
class PANEL_COMPONENT_CLASS_CONDITION_CUSTOM : public PANEL_COMPONENT_CLASS_CONDITION_CUSTOM_BASE, |
|||
public CONDITION_DATA |
|||
{ |
|||
public: |
|||
explicit PANEL_COMPONENT_CLASS_CONDITION_CUSTOM( wxWindow* aParent ); |
|||
|
|||
void OnDeleteConditionClick( wxCommandEvent& event ) override; |
|||
|
|||
protected: |
|||
PANEL_COMPONENT_CLASS_ASSIGNMENT* m_panelParent; |
|||
}; |
|||
|
|||
|
|||
/************************************************************************************************** |
|||
* |
|||
* PANEL_COMPONENT_CLASS_SHEET |
|||
* |
|||
*************************************************************************************************/ |
|||
|
|||
/** |
|||
* Configures matching based on a custom DRC expression |
|||
*/ |
|||
class PANEL_COMPONENT_CLASS_CONDITION_SHEET : public PANEL_COMPONENT_CLASS_CONDITION_SHEET_BASE, |
|||
public CONDITION_DATA |
|||
{ |
|||
public: |
|||
explicit PANEL_COMPONENT_CLASS_CONDITION_SHEET( wxWindow* aParent ); |
|||
|
|||
void OnDeleteConditionClick( wxCommandEvent& event ) override; |
|||
|
|||
void SetSheetsList( const std::vector<wxString>& aSheets ); |
|||
|
|||
protected: |
|||
PANEL_COMPONENT_CLASS_ASSIGNMENT* m_panelParent; |
|||
}; |
|||
|
|||
#endif //PANEL_ASSIGN_COMPONENT_CLASSES_H |
|||
@ -0,0 +1,56 @@ |
|||
/* |
|||
* This program source code file is part of KiCad, a free EDA CAD application. |
|||
* |
|||
* Copyright The KiCad Developers, see AUTHORS.txt for contributors. |
|||
* |
|||
* This program is free software; you can redistribute it and/or |
|||
* modify it under the terms of the GNU General Public License |
|||
* as published by the Free Software Foundation; either version 2 |
|||
* of the License, or (at your option) any later version. |
|||
* |
|||
* This program is distributed in the hope that it will be useful, |
|||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
* GNU General Public License for more details. |
|||
* |
|||
* You should have received a copy of the GNU General Public License |
|||
* along with this program; if not, you may find one here: |
|||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html |
|||
* or you may search the http://www.gnu.org website for the version 2 license, |
|||
* or you may write to the Free Software Foundation, Inc., |
|||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA |
|||
*/ |
|||
|
|||
|
|||
#ifndef PANEL_GENERATE_COMPONENT_CLASSES_H |
|||
#define PANEL_GENERATE_COMPONENT_CLASSES_H |
|||
|
|||
#include <panel_generate_component_classes_base.h> |
|||
|
|||
#include <eda_draw_frame.h> |
|||
#include <project/component_class_settings.h> |
|||
#include <vector> |
|||
|
|||
|
|||
class PANEL_GENERATE_COMPONENT_CLASSES : public PANEL_GENERATE_COMPONENT_CLASSES_BASE |
|||
{ |
|||
public: |
|||
PANEL_GENERATE_COMPONENT_CLASSES( wxWindow* aParentWindow, EDA_DRAW_FRAME* aFrame, |
|||
std::shared_ptr<COMPONENT_CLASS_SETTINGS> aSettings, |
|||
std::vector<wxString>& aSelectionRefs ); |
|||
|
|||
bool TransferDataToWindow() override; |
|||
bool TransferDataFromWindow() override; |
|||
|
|||
bool Validate() override; |
|||
|
|||
//void ImportSettingsFrom( const std::shared_ptr<NET_SETTINGS>& aNetSettings ); |
|||
|
|||
protected: |
|||
EDA_DRAW_FRAME* m_frame; |
|||
std::shared_ptr<COMPONENT_CLASS_SETTINGS> m_componentClassSettings; |
|||
|
|||
std::vector<wxString> m_selectionRefs; |
|||
}; |
|||
|
|||
#endif //PANEL_GENERATE_COMPONENT_CLASSES |
|||
@ -0,0 +1,160 @@ |
|||
/* |
|||
* This program source code file is part of KiCad, a free EDA CAD application. |
|||
* |
|||
* Copyright The KiCad Developers, see AUTHORS.txt for contributors. |
|||
* |
|||
* This program is free software: you can redistribute it and/or modify it |
|||
* under the terms of the GNU General Public License as published by the |
|||
* Free Software Foundation, either version 3 of the License, or (at your |
|||
* option) any later version. |
|||
* |
|||
* This program is distributed in the hope that it will be useful, but |
|||
* WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|||
* General Public License for more details. |
|||
* |
|||
* You should have received a copy of the GNU General Public License along |
|||
* with this program. If not, see <http://www.gnu.org/licenses/>. |
|||
*/ |
|||
|
|||
#ifndef PROJECT_COMPONENT_CLASS_SETTINGS_H |
|||
#define PROJECT_COMPONENT_CLASS_SETTINGS_H |
|||
|
|||
#include <vector> |
|||
#include <unordered_map> |
|||
|
|||
#include <settings/nested_settings.h> |
|||
|
|||
|
|||
class KICOMMON_API COMPONENT_CLASS_ASSIGNMENT_DATA |
|||
{ |
|||
public: |
|||
/// A condition match type |
|||
enum class CONDITION_TYPE |
|||
{ |
|||
REFERENCE, |
|||
FOOTPRINT, |
|||
SIDE, |
|||
ROTATION, |
|||
FOOTPRINT_FIELD, |
|||
CUSTOM, |
|||
SHEET_NAME |
|||
}; |
|||
|
|||
/// Whether conditions are applied with OR or AND logic |
|||
enum class CONDITIONS_OPERATOR |
|||
{ |
|||
ALL, |
|||
ANY |
|||
}; |
|||
|
|||
/// Sets the given condition type with the assocated match data |
|||
void SetCondition( const CONDITION_TYPE aCondition, const wxString& aPrimaryData, |
|||
const wxString& aSecondaryData ) |
|||
{ |
|||
m_conditions[aCondition] = { aPrimaryData, aSecondaryData }; |
|||
} |
|||
|
|||
/// Gets all conditions |
|||
const std::unordered_map<CONDITION_TYPE, std::pair<wxString, wxString>>& GetConditions() const |
|||
{ |
|||
return m_conditions; |
|||
} |
|||
|
|||
/// Sets the resulting component class for matching footprints |
|||
void SetComponentClass( const wxString& aComponentClass ) |
|||
{ |
|||
m_componentClass = aComponentClass; |
|||
} |
|||
|
|||
/// Gets the resulting component class for matching footprints |
|||
const wxString& GetComponentClass() const { return m_componentClass; } |
|||
|
|||
/// Sets the boolean operation in use for all conditions |
|||
void SetConditionsOperation( const CONDITIONS_OPERATOR aOperator ) |
|||
{ |
|||
m_conditionsOperator = aOperator; |
|||
} |
|||
|
|||
/// Gets the boolean operation in use for all conditions |
|||
CONDITIONS_OPERATOR GetConditionsOperator() const { return m_conditionsOperator; } |
|||
|
|||
/// Maps a CONDITION_TYPE to a descriptive string |
|||
static wxString GetConditionName( const CONDITION_TYPE aCondition ); |
|||
|
|||
/// Maps a descriptive string to a CONDITION_TYPE |
|||
static CONDITION_TYPE GetConditionType( const wxString& aCondition ); |
|||
|
|||
/// Returns the DRC rules language for this component class assignment |
|||
wxString GetAssignmentInDRCLanguage() const; |
|||
|
|||
protected: |
|||
/// The name of the component class for this assignment rule |
|||
wxString m_componentClass; |
|||
|
|||
/// Map of condition types to primary and secondary data fields for the condition |
|||
std::unordered_map<CONDITION_TYPE, std::pair<wxString, wxString>> m_conditions; |
|||
|
|||
/// Whether conditions are applied with AND or OR logic |
|||
/// Defaults to ALL |
|||
CONDITIONS_OPERATOR m_conditionsOperator{ CONDITIONS_OPERATOR::ALL }; |
|||
}; |
|||
|
|||
|
|||
/** |
|||
* COMPONENT_CLASS_SETTINGS stores data for component classes, including rules for automatic |
|||
* generation of component classes. |
|||
*/ |
|||
class KICOMMON_API COMPONENT_CLASS_SETTINGS : public NESTED_SETTINGS |
|||
{ |
|||
public: |
|||
COMPONENT_CLASS_SETTINGS( JSON_SETTINGS* aParent, const std::string& aPath ); |
|||
|
|||
virtual ~COMPONENT_CLASS_SETTINGS(); |
|||
|
|||
/// Sets whether component classes should be generated for components in hierarchical sheets |
|||
void SetEnableSheetComponentClasses( bool aEnabled ) |
|||
{ |
|||
m_enableSheetComponentClasses = aEnabled; |
|||
} |
|||
|
|||
/// Gets whether component classes should be generated for components in hierarchical sheets |
|||
bool GetEnableSheetComponentClasses() const { return m_enableSheetComponentClasses; } |
|||
|
|||
/// Clear all dynamic component class assignments |
|||
void ClearComponentClassAssignments() { m_componentClassAssignments.clear(); } |
|||
|
|||
/// Gets all dynamic component class assignments |
|||
const std::vector<COMPONENT_CLASS_ASSIGNMENT_DATA>& GetComponentClassAssignments() const |
|||
{ |
|||
return m_componentClassAssignments; |
|||
} |
|||
|
|||
// Adds a dynamic component class assignment |
|||
void AddComponentClassAssignment( const COMPONENT_CLASS_ASSIGNMENT_DATA& aAssignment ) |
|||
{ |
|||
m_componentClassAssignments.push_back( aAssignment ); |
|||
} |
|||
|
|||
bool operator==( const COMPONENT_CLASS_SETTINGS& aOther ) const; |
|||
|
|||
bool operator!=( const COMPONENT_CLASS_SETTINGS& aOther ) const |
|||
{ |
|||
return !operator==( aOther ); |
|||
} |
|||
|
|||
private: |
|||
/// Toggle generation of component classes for hierarchical sheets |
|||
bool m_enableSheetComponentClasses; |
|||
|
|||
/// All dynamic component class assignment rules |
|||
std::vector<COMPONENT_CLASS_ASSIGNMENT_DATA> m_componentClassAssignments; |
|||
|
|||
/// Saves a dynamic component class assignment to JSON |
|||
static nlohmann::json saveAssignment( const COMPONENT_CLASS_ASSIGNMENT_DATA& aAssignment ); |
|||
|
|||
/// Loads a dynamic component class assignment from JSON |
|||
static COMPONENT_CLASS_ASSIGNMENT_DATA loadAssignment( const nlohmann::json& aJson ); |
|||
}; |
|||
|
|||
#endif // PROJECT_COMPONENT_CLASS_SETTINGS_H |
|||
@ -1,210 +0,0 @@ |
|||
/*
|
|||
* This program source code file is part of KiCad, a free EDA CAD application. |
|||
* |
|||
* Copyright The KiCad Developers, see AUTHORS.txt for contributors. |
|||
* |
|||
* This program is free software: you can redistribute it and/or modify it |
|||
* under the terms of the GNU General Public License as published by the |
|||
* Free Software Foundation, either version 3 of the License, or (at your |
|||
* option) any later version. |
|||
* |
|||
* This program is distributed in the hope that it will be useful, but |
|||
* WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|||
* General Public License for more details. |
|||
* |
|||
* You should have received a copy of the GNU General Public License along |
|||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/ |
|||
|
|||
#include <utility>
|
|||
|
|||
#include <component_class_manager.h>
|
|||
|
|||
|
|||
void COMPONENT_CLASS::AddConstituentClass( COMPONENT_CLASS* componentClass ) |
|||
{ |
|||
m_constituentClasses.push_back( componentClass ); |
|||
} |
|||
|
|||
|
|||
bool COMPONENT_CLASS::ContainsClassName( const wxString& className ) const |
|||
{ |
|||
if( m_constituentClasses.size() == 0 ) |
|||
return false; |
|||
|
|||
if( m_constituentClasses.size() == 1 ) |
|||
return m_name == className; |
|||
|
|||
return std::any_of( m_constituentClasses.begin(), m_constituentClasses.end(), |
|||
[&className]( const COMPONENT_CLASS* testClass ) |
|||
{ |
|||
return testClass->GetFullName() == className; |
|||
} ); |
|||
} |
|||
|
|||
|
|||
wxString COMPONENT_CLASS::GetName() const |
|||
{ |
|||
if( m_constituentClasses.size() == 0 ) |
|||
return wxT( "<None>" ); |
|||
|
|||
if( m_constituentClasses.size() == 1 ) |
|||
return m_name; |
|||
|
|||
wxASSERT( m_constituentClasses.size() >= 2 ); |
|||
|
|||
wxString name; |
|||
|
|||
if( m_constituentClasses.size() == 2 ) |
|||
{ |
|||
name.Printf( _( "%s and %s" ), m_constituentClasses[0]->GetName(), |
|||
m_constituentClasses[1]->GetName() ); |
|||
} |
|||
else if( m_constituentClasses.size() == 3 ) |
|||
{ |
|||
name.Printf( _( "%s, %s and %s" ), m_constituentClasses[0]->GetName(), |
|||
m_constituentClasses[1]->GetName(), m_constituentClasses[2]->GetName() ); |
|||
} |
|||
else if( m_constituentClasses.size() > 3 ) |
|||
{ |
|||
name.Printf( _( "%s, %s and %d more" ), m_constituentClasses[0]->GetName(), |
|||
m_constituentClasses[1]->GetName(), |
|||
static_cast<int>( m_constituentClasses.size() - 2 ) ); |
|||
} |
|||
|
|||
return name; |
|||
} |
|||
|
|||
|
|||
bool COMPONENT_CLASS::IsEmpty() const |
|||
{ |
|||
return m_constituentClasses.size() == 0; |
|||
} |
|||
|
|||
|
|||
COMPONENT_CLASS_MANAGER::COMPONENT_CLASS_MANAGER() |
|||
{ |
|||
m_noneClass = std::make_unique<COMPONENT_CLASS>( wxEmptyString ); |
|||
} |
|||
|
|||
|
|||
COMPONENT_CLASS* COMPONENT_CLASS_MANAGER::GetEffectiveComponentClass( |
|||
const std::unordered_set<wxString>& classNames ) |
|||
{ |
|||
if( classNames.size() == 0 ) |
|||
return m_noneClass.get(); |
|||
|
|||
// Lambda to handle finding constituent component classes. This first checks the cache,
|
|||
// and if found moves the class to the primary classes map. If not found, it either returns
|
|||
// an existing class in the primary list or creates a new class.
|
|||
auto getOrCreateClass = [this]( const wxString& className ) |
|||
{ |
|||
if( m_classesCache.count( className ) ) |
|||
{ |
|||
auto existingClass = m_classesCache.extract( className ); |
|||
m_classes.insert( std::move( existingClass ) ); |
|||
} |
|||
else if( !m_classes.count( className ) ) |
|||
{ |
|||
std::unique_ptr<COMPONENT_CLASS> newClass = |
|||
std::make_unique<COMPONENT_CLASS>( className ); |
|||
newClass->AddConstituentClass( newClass.get() ); |
|||
m_classes[className] = std::move( newClass ); |
|||
} |
|||
|
|||
return m_classes[className].get(); |
|||
}; |
|||
|
|||
// Handle single-assignment component classes
|
|||
if( classNames.size() == 1 ) |
|||
return getOrCreateClass( *classNames.begin() ); |
|||
|
|||
// Handle composite component classes
|
|||
std::vector<wxString> sortedClassNames( classNames.begin(), classNames.end() ); |
|||
|
|||
std::sort( sortedClassNames.begin(), sortedClassNames.end(), |
|||
[]( const wxString& str1, const wxString& str2 ) |
|||
{ |
|||
return str1.Cmp( str2 ) < 0; |
|||
} ); |
|||
|
|||
wxString fullName = GetFullClassNameForConstituents( sortedClassNames ); |
|||
|
|||
if( m_effectiveClassesCache.count( fullName ) ) |
|||
{ |
|||
// The effective class was previously constructed - copy it across to the new live map
|
|||
auto existingClass = m_effectiveClassesCache.extract( fullName ); |
|||
COMPONENT_CLASS* effClass = existingClass.mapped().get(); |
|||
m_effectiveClasses.insert( std::move( existingClass ) ); |
|||
|
|||
// Ensure that all constituent component classes are copied to the live map
|
|||
for( COMPONENT_CLASS* constClass : effClass->GetConstituentClasses() ) |
|||
{ |
|||
if( m_classesCache.count( constClass->GetFullName() ) ) |
|||
{ |
|||
auto constClassNode = m_classesCache.extract( constClass->GetFullName() ); |
|||
m_classes.insert( std::move( constClassNode ) ); |
|||
} |
|||
} |
|||
} |
|||
else if( !m_effectiveClasses.count( fullName ) ) |
|||
{ |
|||
// The effective class was not previously constructed
|
|||
std::unique_ptr<COMPONENT_CLASS> effClass = std::make_unique<COMPONENT_CLASS>( fullName ); |
|||
|
|||
for( const wxString& className : sortedClassNames ) |
|||
effClass->AddConstituentClass( getOrCreateClass( className ) ); |
|||
|
|||
m_effectiveClasses[fullName] = std::move( effClass ); |
|||
} |
|||
|
|||
return m_effectiveClasses[fullName].get(); |
|||
} |
|||
|
|||
|
|||
void COMPONENT_CLASS_MANAGER::InitNetlistUpdate() |
|||
{ |
|||
m_classesCache = std::move( m_classes ); |
|||
m_effectiveClassesCache = std::move( m_effectiveClasses ); |
|||
} |
|||
|
|||
|
|||
void COMPONENT_CLASS_MANAGER::FinishNetlistUpdate() |
|||
{ |
|||
m_classesCache.clear(); |
|||
m_effectiveClassesCache.clear(); |
|||
} |
|||
|
|||
|
|||
wxString COMPONENT_CLASS_MANAGER::GetFullClassNameForConstituents( |
|||
const std::unordered_set<wxString>& classNames ) |
|||
{ |
|||
std::vector<wxString> sortedClassNames( classNames.begin(), classNames.end() ); |
|||
|
|||
std::sort( sortedClassNames.begin(), sortedClassNames.end(), |
|||
[]( const wxString& str1, const wxString& str2 ) |
|||
{ |
|||
return str1.Cmp( str2 ) < 0; |
|||
} ); |
|||
|
|||
return GetFullClassNameForConstituents( sortedClassNames ); |
|||
} |
|||
|
|||
|
|||
wxString |
|||
COMPONENT_CLASS_MANAGER::GetFullClassNameForConstituents( const std::vector<wxString>& classNames ) |
|||
{ |
|||
if( classNames.size() == 0 ) |
|||
return wxEmptyString; |
|||
|
|||
wxString fullName = classNames[0]; |
|||
|
|||
for( std::size_t i = 1; i < classNames.size(); ++i ) |
|||
{ |
|||
fullName += ","; |
|||
fullName += classNames[i]; |
|||
} |
|||
|
|||
return fullName; |
|||
} |
|||
@ -1,140 +0,0 @@ |
|||
/* |
|||
* This program source code file is part of KiCad, a free EDA CAD application. |
|||
* |
|||
* Copyright The KiCad Developers, see AUTHORS.txt for contributors. |
|||
* |
|||
* This program is free software: you can redistribute it and/or modify it |
|||
* under the terms of the GNU General Public License as published by the |
|||
* Free Software Foundation, either version 3 of the License, or (at your |
|||
* option) any later version. |
|||
* |
|||
* This program is distributed in the hope that it will be useful, but |
|||
* WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|||
* General Public License for more details. |
|||
* |
|||
* You should have received a copy of the GNU General Public License along |
|||
* with this program. If not, see <http://www.gnu.org/licenses/>. |
|||
*/ |
|||
|
|||
#ifndef PCBNEW_COMPONENT_CLASS_MANAGER_H |
|||
#define PCBNEW_COMPONENT_CLASS_MANAGER_H |
|||
|
|||
#include <memory> |
|||
#include <unordered_map> |
|||
#include <unordered_set> |
|||
#include <wx/string.h> |
|||
|
|||
#include <board_item.h> |
|||
|
|||
/* |
|||
* A lightweight representation of a component class. The membership within |
|||
* m_consituentClasses allows determination of the type of class this is: |
|||
* |
|||
* m_constituentClasses.size() == 0: This is a null class (no assigment). |
|||
* m_name is empty. |
|||
* m_constituentClasses.size() == 1: This is an atomic class. The constituent class |
|||
* pointer refers to itself. m_name contains the name of the atomic class |
|||
* m_constituentClasses.size() > 1: This is a composite class. The constituent class |
|||
* pointers refer to all atomic members. m_name contains a comma-delimited list of |
|||
* all atomic member class names. |
|||
*/ |
|||
class COMPONENT_CLASS |
|||
{ |
|||
public: |
|||
COMPONENT_CLASS( const wxString& name ) : m_name( name ) {} |
|||
|
|||
/// Fetches the display name of this component class |
|||
wxString GetName() const; |
|||
|
|||
/// Fetches the full name of this component class |
|||
const wxString& GetFullName() const { return m_name; } |
|||
|
|||
/// Adds a constituent component class to an effective component class |
|||
void AddConstituentClass( COMPONENT_CLASS* componentClass ); |
|||
|
|||
/// Determines if this (effective) component class contains a specific sub-class |
|||
bool ContainsClassName( const wxString& className ) const; |
|||
|
|||
/// Determines if this (effective) component class is empty (i.e. no classes defined) |
|||
bool IsEmpty() const; |
|||
|
|||
/// Fetches a vector of the constituent classes for this (effective) class |
|||
const std::vector<COMPONENT_CLASS*>& GetConstituentClasses() const |
|||
{ |
|||
return m_constituentClasses; |
|||
} |
|||
|
|||
private: |
|||
/// The full name of the component class |
|||
wxString m_name; |
|||
|
|||
/// The COMPONENT_CLASS objects contributing to this complete component class |
|||
std::vector<COMPONENT_CLASS*> m_constituentClasses; |
|||
}; |
|||
|
|||
/* |
|||
* A class to manage Component Classes in a board context |
|||
* |
|||
* This manager owns generated COMPONENT_CLASS objects, and guarantees that pointers to managed |
|||
* objects are valid for the duration of the board lifetime. Note that, in order to maintain this |
|||
* guarantee, there are two methods that must be called when updating the board from the netlist |
|||
* (InitNetlistUpdate and FinishNetlistUpdate). |
|||
*/ |
|||
class COMPONENT_CLASS_MANAGER |
|||
{ |
|||
public: |
|||
COMPONENT_CLASS_MANAGER(); |
|||
|
|||
/// @brief Gets the full effective class name for the given set of constituent classes |
|||
static wxString |
|||
GetFullClassNameForConstituents( const std::unordered_set<wxString>& classNames ); |
|||
|
|||
/// @brief Gets the full effective class name for the given set of constituent classes |
|||
/// @param classNames a sorted vector of consituent class names |
|||
static wxString GetFullClassNameForConstituents( const std::vector<wxString>& classNames ); |
|||
|
|||
/// @brief Gets an effective component class for the given constituent class names |
|||
/// @param classes The names of the constituent component classes |
|||
/// @return Effective COMPONENT_CLASS object |
|||
COMPONENT_CLASS* GetEffectiveComponentClass( const std::unordered_set<wxString>& classNames ); |
|||
|
|||
/// Returns the unassigned component class |
|||
const COMPONENT_CLASS* GetNoneComponentClass() const { return m_noneClass.get(); } |
|||
|
|||
/// Prepare the manager for a board update |
|||
/// Must be called prior to updating the PCB from the netlist |
|||
void InitNetlistUpdate(); |
|||
|
|||
/// Cleans up the manager after a board update |
|||
/// Must be called after updating the PCB from the netlist |
|||
void FinishNetlistUpdate(); |
|||
|
|||
/// Resets the contents of the manager |
|||
// All pointers to COMPONENT_CLASS objects will being invalid |
|||
void Reset(); |
|||
|
|||
/// @brief Fetches a read-only map of the fundamental component classes |
|||
const std::unordered_map<wxString, std::unique_ptr<COMPONENT_CLASS>>& GetClasses() const |
|||
{ |
|||
return m_classes; |
|||
} |
|||
|
|||
protected: |
|||
/// All individual component classes |
|||
std::unordered_map<wxString, std::unique_ptr<COMPONENT_CLASS>> m_classes; |
|||
|
|||
/// Generated effective component classes |
|||
std::unordered_map<wxString, std::unique_ptr<COMPONENT_CLASS>> m_effectiveClasses; |
|||
|
|||
/// Cache of all individual component classes (for netlist updating) |
|||
std::unordered_map<wxString, std::unique_ptr<COMPONENT_CLASS>> m_classesCache; |
|||
|
|||
/// Cache of all generated effective component classes (for netlist updating) |
|||
std::unordered_map<wxString, std::unique_ptr<COMPONENT_CLASS>> m_effectiveClassesCache; |
|||
|
|||
/// The class to represent an unassigned component class |
|||
std::unique_ptr<COMPONENT_CLASS> m_noneClass; |
|||
}; |
|||
|
|||
#endif |
|||
@ -0,0 +1,100 @@ |
|||
/*
|
|||
* This program source code file is part of KiCad, a free EDA CAD application. |
|||
* |
|||
* Copyright The KiCad Developers, see AUTHORS.txt for contributors. |
|||
* |
|||
* This program is free software: you can redistribute it and/or modify it |
|||
* under the terms of the GNU General Public License as published by the |
|||
* Free Software Foundation, either version 3 of the License, or (at your |
|||
* option) any later version. |
|||
* |
|||
* This program is distributed in the hope that it will be useful, but |
|||
* WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|||
* General Public License for more details. |
|||
* |
|||
* You should have received a copy of the GNU General Public License along |
|||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/ |
|||
|
|||
|
|||
#include <component_classes/component_class.h>
|
|||
#include <wx/intl.h>
|
|||
|
|||
|
|||
void COMPONENT_CLASS::AddConstituentClass( COMPONENT_CLASS* componentClass ) |
|||
{ |
|||
m_constituentClasses.push_back( componentClass ); |
|||
} |
|||
|
|||
|
|||
const COMPONENT_CLASS* COMPONENT_CLASS::GetConstituentClass( const wxString& className ) const |
|||
{ |
|||
const auto itr = std::ranges::find_if( m_constituentClasses, |
|||
[&className]( const COMPONENT_CLASS* testClass ) |
|||
{ |
|||
return testClass->GetName() == className; |
|||
} ); |
|||
|
|||
if( itr != m_constituentClasses.end() ) |
|||
return *itr; |
|||
|
|||
return nullptr; |
|||
} |
|||
|
|||
|
|||
bool COMPONENT_CLASS::ContainsClassName( const wxString& className ) const |
|||
{ |
|||
return GetConstituentClass( className ) != nullptr; |
|||
} |
|||
|
|||
|
|||
wxString COMPONENT_CLASS::GetHumanReadableName() const |
|||
{ |
|||
if( m_constituentClasses.size() == 0 ) |
|||
return wxT( "<None>" ); |
|||
|
|||
if( m_constituentClasses.size() == 1 ) |
|||
return m_name; |
|||
|
|||
wxASSERT( m_constituentClasses.size() >= 2 ); |
|||
|
|||
wxString name; |
|||
|
|||
if( m_constituentClasses.size() == 2 ) |
|||
{ |
|||
name.Printf( _( "%s and %s" ), m_constituentClasses[0]->GetName(), |
|||
m_constituentClasses[1]->GetName() ); |
|||
} |
|||
else if( m_constituentClasses.size() == 3 ) |
|||
{ |
|||
name.Printf( _( "%s, %s and %s" ), m_constituentClasses[0]->GetName(), |
|||
m_constituentClasses[1]->GetName(), m_constituentClasses[2]->GetName() ); |
|||
} |
|||
else if( m_constituentClasses.size() > 3 ) |
|||
{ |
|||
name.Printf( _( "%s, %s and %d more" ), m_constituentClasses[0]->GetName(), |
|||
m_constituentClasses[1]->GetName(), |
|||
static_cast<int>( m_constituentClasses.size() - 2 ) ); |
|||
} |
|||
|
|||
return name; |
|||
} |
|||
|
|||
|
|||
bool COMPONENT_CLASS::IsEmpty() const |
|||
{ |
|||
return m_constituentClasses.empty(); |
|||
} |
|||
|
|||
|
|||
bool COMPONENT_CLASS::operator==( const COMPONENT_CLASS& aComponent ) const |
|||
{ |
|||
return GetName() == aComponent.GetName(); |
|||
} |
|||
|
|||
|
|||
bool COMPONENT_CLASS::operator!=( const COMPONENT_CLASS& aComponent ) const |
|||
{ |
|||
return !( *this == aComponent ); |
|||
} |
|||
@ -0,0 +1,106 @@ |
|||
/* |
|||
* This program source code file is part of KiCad, a free EDA CAD application. |
|||
* |
|||
* Copyright The KiCad Developers, see AUTHORS.txt for contributors. |
|||
* |
|||
* This program is free software: you can redistribute it and/or modify it |
|||
* under the terms of the GNU General Public License as published by the |
|||
* Free Software Foundation, either version 3 of the License, or (at your |
|||
* option) any later version. |
|||
* |
|||
* This program is distributed in the hope that it will be useful, but |
|||
* WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|||
* General Public License for more details. |
|||
* |
|||
* You should have received a copy of the GNU General Public License along |
|||
* with this program. If not, see <http://www.gnu.org/licenses/>. |
|||
*/ |
|||
|
|||
|
|||
#ifndef PCBNEW_COMPONENT_CLASS_H |
|||
#define PCBNEW_COMPONENT_CLASS_H |
|||
|
|||
#include <wx/string.h> |
|||
#include <vector> |
|||
|
|||
/** |
|||
* A lightweight representation of a component class. The membership within |
|||
* m_consituentClasses allows determination of the type of class this is: |
|||
* |
|||
* m_constituentClasses.size() == 0: This is a null class (no assigment). |
|||
* m_name is empty. |
|||
* m_constituentClasses.size() == 1: This is an atomic class. The constituent class |
|||
* pointer refers to itself. m_name contains the name of the atomic class |
|||
* m_constituentClasses.size() > 1: This is a composite class. The constituent class |
|||
* pointers refer to all atomic members. m_name contains a comma-delimited list of |
|||
* all atomic member class names. |
|||
*/ |
|||
class COMPONENT_CLASS |
|||
{ |
|||
public: |
|||
/// The assignment context in which this component class is used |
|||
enum class USAGE |
|||
{ |
|||
STATIC, |
|||
DYNAMIC, |
|||
STATIC_AND_DYNAMIC, |
|||
EFFECTIVE |
|||
}; |
|||
|
|||
/// Construct a new component class |
|||
explicit COMPONENT_CLASS( const wxString& name, const USAGE aUsageContext ) : |
|||
m_name( name ), m_usageContext( aUsageContext ) |
|||
{ |
|||
} |
|||
|
|||
/// @brief Gets the consolidated name of this component class (which may be an aggregate). This is |
|||
/// intended for display to users (e.g. in infobars or messages). WARNING: Do not use this |
|||
/// to compare equivalence, or to export to other tools) |
|||
wxString GetHumanReadableName() const; |
|||
|
|||
/// Fetches the full name of this component class |
|||
const wxString& GetName() const { return m_name; } |
|||
|
|||
/// Adds a constituent component class to an effective component class |
|||
void AddConstituentClass( COMPONENT_CLASS* componentClass ); |
|||
|
|||
/// Returns a named constituent class of this component class, or nullptr if not found |
|||
const COMPONENT_CLASS* GetConstituentClass( const wxString& className ) const; |
|||
|
|||
/// Determines if this (effective) component class contains a specific constituent class |
|||
bool ContainsClassName( const wxString& className ) const; |
|||
|
|||
/// Determines if this (effective) component class is empty (i.e. no classes defined) |
|||
bool IsEmpty() const; |
|||
|
|||
/// Fetches a vector of the constituent classes for this (effective) class |
|||
const std::vector<COMPONENT_CLASS*>& GetConstituentClasses() const |
|||
{ |
|||
return m_constituentClasses; |
|||
} |
|||
|
|||
/// Gets the assignment context in which this component class is being used |
|||
USAGE GetUsageContext() const { return m_usageContext; } |
|||
|
|||
/// Sets the assignment context in which this component class is being used |
|||
void SetUsageContext( const USAGE aUsageContext ) { m_usageContext = aUsageContext; } |
|||
|
|||
/// Tests two component classes for equality based on full class name |
|||
bool operator==( const COMPONENT_CLASS& aComponent ) const; |
|||
|
|||
/// Tests two component classes for inequality based on full class name |
|||
bool operator!=( const COMPONENT_CLASS& aComponent ) const; |
|||
|
|||
private: |
|||
/// The full name of the component class |
|||
wxString m_name; |
|||
|
|||
/// The COMPONENT_CLASS objects contributing to this complete component class |
|||
std::vector<COMPONENT_CLASS*> m_constituentClasses; |
|||
|
|||
/// The assignment context in which this component class is being used |
|||
USAGE m_usageContext; |
|||
}; |
|||
|
|||
#endif //PCBNEW_COMPONENT_CLASS_H |
|||
@ -0,0 +1,38 @@ |
|||
/*
|
|||
* This program source code file is part of KiCad, a free EDA CAD application. |
|||
* |
|||
* Copyright The KiCad Developers, see AUTHORS.txt for contributors. |
|||
* |
|||
* This program is free software: you can redistribute it and/or modify it |
|||
* under the terms of the GNU General Public License as published by the |
|||
* Free Software Foundation, either version 3 of the License, or (at your |
|||
* option) any later version. |
|||
* |
|||
* This program is distributed in the hope that it will be useful, but |
|||
* WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|||
* General Public License for more details. |
|||
* |
|||
* You should have received a copy of the GNU General Public License along |
|||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/ |
|||
|
|||
|
|||
#include <component_classes/component_class_assignment_rule.h>
|
|||
#include <footprint.h>
|
|||
|
|||
|
|||
COMPONENT_CLASS_ASSIGNMENT_RULE::COMPONENT_CLASS_ASSIGNMENT_RULE( |
|||
const wxString& aComponentClass, std::shared_ptr<DRC_RULE_CONDITION>&& aCondition ) : |
|||
m_componentClass( aComponentClass ), m_condition( std::move( aCondition ) ) |
|||
{ |
|||
} |
|||
|
|||
|
|||
bool COMPONENT_CLASS_ASSIGNMENT_RULE::Matches( const FOOTPRINT* aFootprint ) const |
|||
{ |
|||
if( !m_condition ) |
|||
return true; |
|||
|
|||
return m_condition->EvaluateFor( aFootprint, nullptr, 0, aFootprint->GetSide(), nullptr ); |
|||
} |
|||
@ -0,0 +1,60 @@ |
|||
/* |
|||
* This program source code file is part of KiCad, a free EDA CAD application. |
|||
* |
|||
* Copyright The KiCad Developers, see AUTHORS.txt for contributors. |
|||
* |
|||
* This program is free software: you can redistribute it and/or modify it |
|||
* under the terms of the GNU General Public License as published by the |
|||
* Free Software Foundation, either version 3 of the License, or (at your |
|||
* option) any later version. |
|||
* |
|||
* This program is distributed in the hope that it will be useful, but |
|||
* WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|||
* General Public License for more details. |
|||
* |
|||
* You should have received a copy of the GNU General Public License along |
|||
* with this program. If not, see <http://www.gnu.org/licenses/>. |
|||
*/ |
|||
|
|||
#ifndef COMPONENT_CLASS_ASSIGNMENT_RULE_H |
|||
#define COMPONENT_CLASS_ASSIGNMENT_RULE_H |
|||
|
|||
#include <memory> |
|||
#include <vector> |
|||
#include <wx/string.h> |
|||
|
|||
#include <drc/drc_rule_condition.h> |
|||
|
|||
class FOOTPRINT; |
|||
|
|||
/** |
|||
* Class which represents a component class assignment rule. These are used to dynamically assign component classes |
|||
* based on FOOTPRINT parameters which are exposed through the DRC language. |
|||
*/ |
|||
class COMPONENT_CLASS_ASSIGNMENT_RULE |
|||
{ |
|||
public: |
|||
/// Construct a component class assignment rule |
|||
explicit COMPONENT_CLASS_ASSIGNMENT_RULE( const wxString& aComponentClass, |
|||
std::shared_ptr<DRC_RULE_CONDITION>&& aCondition ); |
|||
|
|||
/// The component class to assign to matching footprints |
|||
wxString GetComponentClass() const { return m_componentClass; } |
|||
void SetComponentClass( const wxString& aComponentClass ) |
|||
{ |
|||
m_componentClass = aComponentClass; |
|||
} |
|||
|
|||
/// Tests whether this rules matches the given footprint |
|||
bool Matches( const FOOTPRINT* aFootprint ) const; |
|||
|
|||
protected: |
|||
/// The component class to assign to matching footprints |
|||
wxString m_componentClass; |
|||
|
|||
/// The DRC condition which specifies footprint matches for this component class |
|||
std::shared_ptr<DRC_RULE_CONDITION> m_condition; |
|||
}; |
|||
|
|||
#endif // COMPONENT_CLASS_ASSIGNMENT_RULE_H |
|||
@ -0,0 +1,48 @@ |
|||
/*
|
|||
* This program source code file is part of KiCad, a free EDA CAD application. |
|||
* |
|||
* Copyright The KiCad Developers, see AUTHORS.txt for contributors. |
|||
* |
|||
* This program is free software: you can redistribute it and/or modify it |
|||
* under the terms of the GNU General Public License as published by the |
|||
* Free Software Foundation, either version 3 of the License, or (at your |
|||
* option) any later version. |
|||
* |
|||
* This program is distributed in the hope that it will be useful, but |
|||
* WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|||
* General Public License for more details. |
|||
* |
|||
* You should have received a copy of the GNU General Public License along |
|||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/ |
|||
|
|||
|
|||
#include <component_classes/component_class_cache_proxy.h>
|
|||
|
|||
#include <board.h>
|
|||
#include <footprint.h>
|
|||
|
|||
const COMPONENT_CLASS* COMPONENT_CLASS_CACHE_PROXY::GetComponentClass() const |
|||
{ |
|||
COMPONENT_CLASS_MANAGER& mgr = m_footprint->GetBoard()->GetComponentClassManager(); |
|||
|
|||
if( mgr.GetTicker() > m_lastTickerValue ) |
|||
{ |
|||
RecomputeComponentClass( &mgr ); |
|||
} |
|||
|
|||
return m_finalComponentClass; |
|||
} |
|||
|
|||
|
|||
void COMPONENT_CLASS_CACHE_PROXY::RecomputeComponentClass( COMPONENT_CLASS_MANAGER* manager ) const |
|||
{ |
|||
if( !manager ) |
|||
manager = &m_footprint->GetBoard()->GetComponentClassManager(); |
|||
|
|||
m_dynamicComponentClass = manager->GetDynamicComponentClassesForFootprint( m_footprint ); |
|||
m_finalComponentClass = |
|||
manager->GetCombinedComponentClass( m_staticComponentClass, m_dynamicComponentClass ); |
|||
m_lastTickerValue = manager->GetTicker(); |
|||
} |
|||
@ -0,0 +1,70 @@ |
|||
/* |
|||
* This program source code file is part of KiCad, a free EDA CAD application. |
|||
* |
|||
* Copyright The KiCad Developers, see AUTHORS.txt for contributors. |
|||
* |
|||
* This program is free software: you can redistribute it and/or modify it |
|||
* under the terms of the GNU General Public License as published by the |
|||
* Free Software Foundation, either version 3 of the License, or (at your |
|||
* option) any later version. |
|||
* |
|||
* This program is distributed in the hope that it will be useful, but |
|||
* WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|||
* General Public License for more details. |
|||
* |
|||
* You should have received a copy of the GNU General Public License along |
|||
* with this program. If not, see <http://www.gnu.org/licenses/>. |
|||
*/ |
|||
|
|||
|
|||
#ifndef PCBNEW_COMPONENT_CLASS_CACHE_PROXY_H |
|||
#define PCBNEW_COMPONENT_CLASS_CACHE_PROXY_H |
|||
|
|||
#include <component_classes/component_class.h> |
|||
#include <footprint.h> |
|||
|
|||
/* |
|||
* A class which acts as a cache-aware proxy for a FOOTPRINT's component class. |
|||
* Creating dynamic component classes (from component class generators) is an |
|||
* expensive operation, so we want to cache the results. This class is a cache |
|||
* proxy which tracks the validity of the cached component class with respect |
|||
* to loaded static and dynamic component class rules |
|||
*/ |
|||
class COMPONENT_CLASS_CACHE_PROXY |
|||
{ |
|||
public: |
|||
explicit COMPONENT_CLASS_CACHE_PROXY( FOOTPRINT* footprint ) : m_footprint( footprint ) {} |
|||
|
|||
/// Sets the static component class |
|||
/// Static component classes are assigned in the schematic, and are transferred through the |
|||
/// netlist |
|||
void SetStaticComponentClass( const COMPONENT_CLASS* compClass ) |
|||
{ |
|||
m_staticComponentClass = compClass; |
|||
} |
|||
|
|||
/// Gets the static component class |
|||
const COMPONENT_CLASS* GetStaticComponentClass() const { return m_staticComponentClass; } |
|||
|
|||
/// Gets the full component class (static + dynamic resultant component class) |
|||
const COMPONENT_CLASS* GetComponentClass() const; |
|||
|
|||
/// Forces recomputation of the component class |
|||
void RecomputeComponentClass( COMPONENT_CLASS_MANAGER* manager = nullptr ) const; |
|||
|
|||
/// Invalidates the cache |
|||
/// The component class will be recalculated on the next access |
|||
void InvalidateCache() { m_lastTickerValue = -1; } |
|||
|
|||
protected: |
|||
FOOTPRINT* m_footprint; |
|||
|
|||
const COMPONENT_CLASS* m_staticComponentClass{ nullptr }; |
|||
mutable const COMPONENT_CLASS* m_dynamicComponentClass{ nullptr }; |
|||
mutable const COMPONENT_CLASS* m_finalComponentClass{ nullptr }; |
|||
|
|||
mutable long long int m_lastTickerValue{ -1 }; |
|||
}; |
|||
|
|||
#endif //PCBNEW_COMPONENT_CLASS_CACHE_PROXY_H |
|||
@ -0,0 +1,507 @@ |
|||
/*
|
|||
* This program source code file is part of KiCad, a free EDA CAD application. |
|||
* |
|||
* Copyright The KiCad Developers, see AUTHORS.txt for contributors. |
|||
* |
|||
* This program is free software: you can redistribute it and/or modify it |
|||
* under the terms of the GNU General Public License as published by the |
|||
* Free Software Foundation, either version 3 of the License, or (at your |
|||
* option) any later version. |
|||
* |
|||
* This program is distributed in the hope that it will be useful, but |
|||
* WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|||
* General Public License for more details. |
|||
* |
|||
* You should have received a copy of the GNU General Public License along |
|||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/ |
|||
|
|||
|
|||
#include <component_classes/component_class_manager.h>
|
|||
|
|||
#include <board.h>
|
|||
#include <component_classes/component_class.h>
|
|||
#include <component_classes/component_class_assignment_rule.h>
|
|||
#include <drc/drc_cache_generator.h>
|
|||
#include <drc/drc_rule_parser.h>
|
|||
#include <footprint.h>
|
|||
#include <project/component_class_settings.h>
|
|||
#include <tools/drc_tool.h>
|
|||
|
|||
|
|||
COMPONENT_CLASS_MANAGER::COMPONENT_CLASS_MANAGER( BOARD* board ) : |
|||
m_board( board ), m_hasCustomAssignmentConditions( false ) |
|||
{ |
|||
m_noneClass = |
|||
std::make_shared<COMPONENT_CLASS>( wxEmptyString, COMPONENT_CLASS::USAGE::STATIC ); |
|||
} |
|||
|
|||
|
|||
/**
|
|||
* Computes and returns an effective component class for a (possibly empty) set of constituent |
|||
* class names. This is called by the netlist updater to set static component classes on footprints. |
|||
* |
|||
* Where constituent or effective component classes already exist, they are re-used. This allows |
|||
* efficient comparison of (effective) component classes by pointer in DRC checks. |
|||
* |
|||
* Preconditions: InitNetlistUpdate() must be called before invoking this method. |
|||
* @param classNames The constitent component class names |
|||
* @return A pointer to an effective COMPONENT_CLASS representing all constituent component classes |
|||
*/ |
|||
COMPONENT_CLASS* COMPONENT_CLASS_MANAGER::GetEffectiveStaticComponentClass( |
|||
const std::unordered_set<wxString>& classNames ) |
|||
{ |
|||
// Handle no component class condition
|
|||
if( classNames.size() == 0 ) |
|||
return m_noneClass.get(); |
|||
|
|||
// Handle single-assignment component classes
|
|||
if( classNames.size() == 1 ) |
|||
{ |
|||
const wxString& className = *classNames.begin(); |
|||
m_staticClassNamesCache.erase( className ); |
|||
return getOrCreateConstituentClass( className, COMPONENT_CLASS::USAGE::STATIC ); |
|||
} |
|||
|
|||
// Handle composite component classes
|
|||
const std::vector<wxString> sortedClassNames = sortClassNames( classNames ); |
|||
wxString fullName = GetFullClassNameForConstituents( sortedClassNames ); |
|||
|
|||
COMPONENT_CLASS* effectiveClass = |
|||
getOrCreateEffectiveClass( sortedClassNames, COMPONENT_CLASS::USAGE::STATIC ); |
|||
|
|||
for( const COMPONENT_CLASS* constituentClass : effectiveClass->GetConstituentClasses() ) |
|||
m_staticClassNamesCache.erase( constituentClass->GetName() ); |
|||
|
|||
return effectiveClass; |
|||
} |
|||
|
|||
|
|||
void COMPONENT_CLASS_MANAGER::InitNetlistUpdate() |
|||
{ |
|||
for( const auto& [className, classPtr] : m_constituentClasses ) |
|||
{ |
|||
if( classPtr->GetUsageContext() == COMPONENT_CLASS::USAGE::STATIC |
|||
|| classPtr->GetUsageContext() == COMPONENT_CLASS::USAGE::STATIC_AND_DYNAMIC ) |
|||
{ |
|||
m_staticClassNamesCache.insert( className ); |
|||
} |
|||
} |
|||
|
|||
++m_ticker; |
|||
} |
|||
|
|||
|
|||
void COMPONENT_CLASS_MANAGER::FinishNetlistUpdate() |
|||
{ |
|||
// m_staticClassesCache now contains any static component classes that are unused from the
|
|||
// netlist update. Delete any effective component classes which refer to them in a static-only
|
|||
// context, or update their usage context.
|
|||
for( const wxString& className : m_staticClassNamesCache ) |
|||
{ |
|||
COMPONENT_CLASS* staticClass = m_constituentClasses[className].get(); |
|||
|
|||
if( staticClass->GetUsageContext() == COMPONENT_CLASS::USAGE::STATIC ) |
|||
{ |
|||
// Any static-only classes can be deleted, along with effective classes which refer to them
|
|||
std::unordered_set<wxString> classesToDelete; |
|||
|
|||
for( const auto& [combinedFullName, combinedCompClass] : m_effectiveClasses ) |
|||
{ |
|||
if( combinedCompClass->ContainsClassName( className ) ) |
|||
classesToDelete.insert( combinedFullName ); |
|||
} |
|||
|
|||
for( const wxString& classNameToDelete : classesToDelete ) |
|||
m_effectiveClasses.erase( classNameToDelete ); |
|||
|
|||
m_constituentClasses.erase( className ); |
|||
} |
|||
else |
|||
{ |
|||
// Set the component class to dynamic-only scope
|
|||
wxASSERT( staticClass->GetUsageContext() |
|||
== COMPONENT_CLASS::USAGE::STATIC_AND_DYNAMIC ); |
|||
staticClass->SetUsageContext( COMPONENT_CLASS::USAGE::DYNAMIC ); |
|||
} |
|||
} |
|||
|
|||
// Clear the caches
|
|||
m_staticClassNamesCache.clear(); |
|||
} |
|||
|
|||
|
|||
wxString COMPONENT_CLASS_MANAGER::GetFullClassNameForConstituents( |
|||
const std::unordered_set<wxString>& classNames ) |
|||
{ |
|||
const std::vector<wxString> sortedClassNames = sortClassNames( classNames ); |
|||
|
|||
return GetFullClassNameForConstituents( sortedClassNames ); |
|||
} |
|||
|
|||
|
|||
wxString |
|||
COMPONENT_CLASS_MANAGER::GetFullClassNameForConstituents( const std::vector<wxString>& classNames ) |
|||
{ |
|||
if( classNames.size() == 0 ) |
|||
return wxEmptyString; |
|||
|
|||
wxString fullName = classNames[0]; |
|||
|
|||
for( std::size_t i = 1; i < classNames.size(); ++i ) |
|||
{ |
|||
fullName += ","; |
|||
fullName += classNames[i]; |
|||
} |
|||
|
|||
return fullName; |
|||
} |
|||
|
|||
|
|||
bool COMPONENT_CLASS_MANAGER::SyncDynamicComponentClassAssignments( |
|||
const std::vector<COMPONENT_CLASS_ASSIGNMENT_DATA>& aAssignments, |
|||
bool aGenerateSheetClasses, const std::unordered_set<wxString>& aNewSheetPaths ) |
|||
{ |
|||
m_hasCustomAssignmentConditions = false; |
|||
bool success = true; |
|||
|
|||
// Invalidate component class cache entries
|
|||
++m_ticker; |
|||
|
|||
// Save previous dynamically assigned component class names
|
|||
std::unordered_set<wxString> prevClassNames; |
|||
|
|||
for( const auto& rule : m_assignmentRules ) |
|||
prevClassNames.insert( rule->GetComponentClass() ); |
|||
|
|||
m_assignmentRules.clear(); |
|||
|
|||
// Parse all assignment rules
|
|||
std::vector<std::shared_ptr<COMPONENT_CLASS_ASSIGNMENT_RULE>> rules; |
|||
|
|||
for( const COMPONENT_CLASS_ASSIGNMENT_DATA& assignment : aAssignments ) |
|||
{ |
|||
if( assignment.GetConditions().contains( |
|||
COMPONENT_CLASS_ASSIGNMENT_DATA::CONDITION_TYPE::CUSTOM ) ) |
|||
{ |
|||
m_hasCustomAssignmentConditions = true; |
|||
} |
|||
|
|||
std::shared_ptr<COMPONENT_CLASS_ASSIGNMENT_RULE> rule = CompileAssignmentRule( assignment ); |
|||
|
|||
if( rule ) |
|||
rules.emplace_back( std::move( rule ) ); |
|||
else |
|||
success = false; |
|||
} |
|||
|
|||
// Generate sheet classes if required
|
|||
if( aGenerateSheetClasses ) |
|||
{ |
|||
std::unordered_set<wxString> sheetNames = aNewSheetPaths; |
|||
|
|||
for( const FOOTPRINT* footprint : m_board->Footprints() ) |
|||
sheetNames.insert( footprint->GetSheetname() ); |
|||
|
|||
for( wxString sheetName : sheetNames ) |
|||
{ |
|||
// Don't generate a class for empty sheets (e.g. manually placed footprints) or the root
|
|||
// sheet
|
|||
if( sheetName.empty() || sheetName == wxT( "/" ) ) |
|||
continue; |
|||
|
|||
sheetName.Replace( wxT( "\"" ), wxT( "" ) ); |
|||
sheetName.Replace( wxT( "'" ), wxT( "" ) ); |
|||
|
|||
COMPONENT_CLASS_ASSIGNMENT_DATA assignment; |
|||
assignment.SetComponentClass( sheetName ); |
|||
assignment.SetCondition( COMPONENT_CLASS_ASSIGNMENT_DATA::CONDITION_TYPE::SHEET_NAME, |
|||
sheetName, wxEmptyString ); |
|||
|
|||
std::shared_ptr<COMPONENT_CLASS_ASSIGNMENT_RULE> rule = |
|||
CompileAssignmentRule( assignment ); |
|||
|
|||
if( rule ) |
|||
rules.emplace_back( std::move( rule ) ); |
|||
else |
|||
success = false; |
|||
} |
|||
} |
|||
|
|||
// Set the assignment rules
|
|||
if( success ) |
|||
m_assignmentRules = std::move( rules ); |
|||
|
|||
// Re-use or create component classes which may be output by assignment rules
|
|||
for( const auto& rule : m_assignmentRules ) |
|||
{ |
|||
wxString className = rule->GetComponentClass(); |
|||
prevClassNames.erase( className ); |
|||
getOrCreateConstituentClass( className, COMPONENT_CLASS::USAGE::DYNAMIC ); |
|||
} |
|||
|
|||
// prevClassNames now contains all dynamic component class names no longer in use. Remove any
|
|||
// effective component classes no longer in use.
|
|||
for( const wxString& className : prevClassNames ) |
|||
{ |
|||
COMPONENT_CLASS* dynamicClass = m_constituentClasses[className].get(); |
|||
|
|||
if( dynamicClass->GetUsageContext() == COMPONENT_CLASS::USAGE::DYNAMIC ) |
|||
{ |
|||
// Any dynamic-only classes can be deleted, along with effective classes which refer to them
|
|||
std::unordered_set<wxString> classesToDelete; |
|||
|
|||
for( const auto& [combinedFullName, combinedCompClass] : m_effectiveClasses ) |
|||
{ |
|||
if( combinedCompClass->ContainsClassName( className ) ) |
|||
classesToDelete.insert( combinedFullName ); |
|||
} |
|||
|
|||
for( const wxString& classNameToDelete : classesToDelete ) |
|||
m_effectiveClasses.erase( classNameToDelete ); |
|||
|
|||
m_constituentClasses.erase( className ); |
|||
} |
|||
else |
|||
{ |
|||
// Set the component class to dynamic-only scope
|
|||
wxASSERT( dynamicClass->GetUsageContext() |
|||
== COMPONENT_CLASS::USAGE::STATIC_AND_DYNAMIC ); |
|||
dynamicClass->SetUsageContext( COMPONENT_CLASS::USAGE::STATIC ); |
|||
} |
|||
} |
|||
|
|||
return success; |
|||
} |
|||
|
|||
|
|||
std::shared_ptr<COMPONENT_CLASS_ASSIGNMENT_RULE> |
|||
COMPONENT_CLASS_MANAGER::CompileAssignmentRule( const COMPONENT_CLASS_ASSIGNMENT_DATA& aAssignment ) |
|||
{ |
|||
const wxString ruleSource = aAssignment.GetAssignmentInDRCLanguage(); |
|||
|
|||
// Ignore incomplete rules (e.g. no component class name specified)
|
|||
if( ruleSource.empty() ) |
|||
return nullptr; |
|||
|
|||
DRC_RULES_PARSER parser( ruleSource, wxT( "Component class assignment rule" ) ); |
|||
|
|||
try |
|||
{ |
|||
std::vector<std::shared_ptr<COMPONENT_CLASS_ASSIGNMENT_RULE>> parsed; |
|||
|
|||
WX_STRING_REPORTER reporter; |
|||
parser.ParseComponentClassAssignmentRules( parsed, &reporter ); |
|||
|
|||
if( reporter.HasMessageOfSeverity( RPT_SEVERITY_ERROR ) ) |
|||
return nullptr; |
|||
|
|||
if( parsed.size() != 1 ) |
|||
return nullptr; |
|||
|
|||
return parsed[0]; |
|||
} |
|||
catch( PARSE_ERROR& ) |
|||
{ |
|||
return nullptr; |
|||
} |
|||
} |
|||
|
|||
|
|||
const COMPONENT_CLASS* |
|||
COMPONENT_CLASS_MANAGER::GetCombinedComponentClass( const COMPONENT_CLASS* staticClass, |
|||
const COMPONENT_CLASS* dynamicClass ) |
|||
{ |
|||
std::unordered_set<wxString> classNames; |
|||
|
|||
if( staticClass ) |
|||
{ |
|||
for( const COMPONENT_CLASS* compClass : staticClass->GetConstituentClasses() ) |
|||
classNames.insert( compClass->GetName() ); |
|||
} |
|||
|
|||
if( dynamicClass ) |
|||
{ |
|||
for( const COMPONENT_CLASS* compClass : dynamicClass->GetConstituentClasses() ) |
|||
classNames.insert( compClass->GetName() ); |
|||
} |
|||
|
|||
if( classNames.empty() ) |
|||
return GetNoneComponentClass(); |
|||
|
|||
if( classNames.size() == 1 ) |
|||
{ |
|||
wxASSERT( m_constituentClasses.contains( *classNames.begin() ) ); |
|||
return m_constituentClasses[*classNames.begin()].get(); |
|||
} |
|||
|
|||
const std::vector<wxString> sortedClassNames = sortClassNames( classNames ); |
|||
|
|||
wxString fullCombinedName = GetFullClassNameForConstituents( sortedClassNames ); |
|||
|
|||
if( !m_effectiveClasses.contains( fullCombinedName ) ) |
|||
{ |
|||
std::unique_ptr<COMPONENT_CLASS> combinedClass = std::make_unique<COMPONENT_CLASS>( |
|||
fullCombinedName, COMPONENT_CLASS::USAGE::EFFECTIVE ); |
|||
|
|||
for( const wxString& className : sortedClassNames ) |
|||
{ |
|||
wxASSERT( m_constituentClasses.contains( className ) ); |
|||
combinedClass->AddConstituentClass( m_constituentClasses[className].get() ); |
|||
} |
|||
|
|||
m_effectiveClasses[fullCombinedName] = std::move( combinedClass ); |
|||
} |
|||
|
|||
return m_effectiveClasses[fullCombinedName].get(); |
|||
} |
|||
|
|||
|
|||
void COMPONENT_CLASS_MANAGER::InvalidateComponentClasses() |
|||
{ |
|||
++m_ticker; |
|||
} |
|||
|
|||
|
|||
void COMPONENT_CLASS_MANAGER::ForceComponentClassRecalculation() const |
|||
{ |
|||
for( const auto& footprint : m_board->Footprints() ) |
|||
{ |
|||
footprint->RecomputeComponentClass(); |
|||
} |
|||
} |
|||
|
|||
|
|||
const COMPONENT_CLASS* |
|||
COMPONENT_CLASS_MANAGER::GetDynamicComponentClassesForFootprint( const FOOTPRINT* footprint ) |
|||
{ |
|||
std::unordered_set<wxString> classNames; |
|||
|
|||
// Assemble matching component class names
|
|||
for( const auto& rule : m_assignmentRules ) |
|||
{ |
|||
if( rule->Matches( footprint ) ) |
|||
classNames.insert( rule->GetComponentClass() ); |
|||
} |
|||
|
|||
// Handle composite component classes
|
|||
const std::vector<wxString> sortedClassNames = sortClassNames( classNames ); |
|||
const wxString fullName = GetFullClassNameForConstituents( sortedClassNames ); |
|||
|
|||
// No matching component classes
|
|||
if( classNames.empty() ) |
|||
return nullptr; |
|||
|
|||
// One matching component class
|
|||
if( classNames.size() == 1 ) |
|||
return getOrCreateConstituentClass( *classNames.begin(), COMPONENT_CLASS::USAGE::DYNAMIC ); |
|||
|
|||
// Multiple matching component classes
|
|||
return getOrCreateEffectiveClass( sortedClassNames, COMPONENT_CLASS::USAGE::DYNAMIC ); |
|||
} |
|||
|
|||
|
|||
std::vector<wxString> |
|||
COMPONENT_CLASS_MANAGER::sortClassNames( const std::unordered_set<wxString>& classNames ) |
|||
{ |
|||
std::vector<wxString> sortedClassNames( classNames.begin(), classNames.end() ); |
|||
|
|||
std::ranges::sort( sortedClassNames, |
|||
[]( const wxString& str1, const wxString& str2 ) |
|||
{ |
|||
return str1.Cmp( str2 ) < 0; |
|||
} ); |
|||
|
|||
return sortedClassNames; |
|||
} |
|||
|
|||
|
|||
COMPONENT_CLASS* |
|||
COMPONENT_CLASS_MANAGER::getOrCreateConstituentClass( const wxString& aClassName, |
|||
COMPONENT_CLASS::USAGE aContext ) |
|||
{ |
|||
if( aContext == COMPONENT_CLASS::USAGE::STATIC_AND_DYNAMIC |
|||
|| aContext == COMPONENT_CLASS::USAGE::EFFECTIVE ) |
|||
{ |
|||
wxFAIL_MSG( "Can't create a STATIC_AND_DYNAMIC or EFFECTIVE constituent component class" ); |
|||
return m_noneClass.get(); |
|||
} |
|||
|
|||
if( m_constituentClasses.contains( aClassName ) ) |
|||
{ |
|||
COMPONENT_CLASS* compClass = m_constituentClasses[aClassName].get(); |
|||
|
|||
if( aContext != compClass->GetUsageContext() ) |
|||
compClass->SetUsageContext( COMPONENT_CLASS::USAGE::STATIC_AND_DYNAMIC ); |
|||
|
|||
return compClass; |
|||
} |
|||
|
|||
std::unique_ptr<COMPONENT_CLASS> newClass = |
|||
std::make_unique<COMPONENT_CLASS>( aClassName, aContext ); |
|||
newClass->AddConstituentClass( newClass.get() ); |
|||
|
|||
m_constituentClasses[aClassName] = std::move( newClass ); |
|||
|
|||
return m_constituentClasses[aClassName].get(); |
|||
} |
|||
|
|||
|
|||
COMPONENT_CLASS* |
|||
COMPONENT_CLASS_MANAGER::getOrCreateEffectiveClass( const std::vector<wxString>& aClassNames, |
|||
COMPONENT_CLASS::USAGE aContext ) |
|||
{ |
|||
wxString fullClassName = GetFullClassNameForConstituents( aClassNames ); |
|||
|
|||
if( m_effectiveClasses.contains( fullClassName ) ) |
|||
{ |
|||
COMPONENT_CLASS* compClass = m_effectiveClasses[fullClassName].get(); |
|||
|
|||
for( COMPONENT_CLASS* constituentClass : compClass->GetConstituentClasses() ) |
|||
{ |
|||
if( constituentClass->GetUsageContext() != aContext ) |
|||
constituentClass->SetUsageContext( COMPONENT_CLASS::USAGE::STATIC_AND_DYNAMIC ); |
|||
} |
|||
} |
|||
else |
|||
{ |
|||
std::unique_ptr<COMPONENT_CLASS> effectiveClass = std::make_unique<COMPONENT_CLASS>( |
|||
fullClassName, COMPONENT_CLASS::USAGE::EFFECTIVE ); |
|||
|
|||
for( const wxString& className : aClassNames ) |
|||
{ |
|||
COMPONENT_CLASS* constituentClass = getOrCreateConstituentClass( className, aContext ); |
|||
effectiveClass->AddConstituentClass( constituentClass ); |
|||
} |
|||
|
|||
m_effectiveClasses[fullClassName] = std::move( effectiveClass ); |
|||
} |
|||
|
|||
return m_effectiveClasses[fullClassName].get(); |
|||
} |
|||
|
|||
|
|||
std::unordered_set<wxString> COMPONENT_CLASS_MANAGER::GetClassNames() const |
|||
{ |
|||
std::unordered_set<wxString> classNames; |
|||
|
|||
for( const auto& className : m_constituentClasses | std::views::keys ) |
|||
classNames.insert( className ); |
|||
|
|||
return classNames; |
|||
} |
|||
|
|||
|
|||
void COMPONENT_CLASS_MANAGER::RebuildRequiredCaches( FOOTPRINT* aFootprint ) const |
|||
{ |
|||
if( aFootprint ) |
|||
{ |
|||
aFootprint->BuildCourtyardCaches(); |
|||
} |
|||
else |
|||
{ |
|||
for( FOOTPRINT* fp : m_board->Footprints() ) |
|||
fp->BuildCourtyardCaches(); |
|||
} |
|||
} |
|||
@ -0,0 +1,153 @@ |
|||
/* |
|||
* This program source code file is part of KiCad, a free EDA CAD application. |
|||
* |
|||
* Copyright The KiCad Developers, see AUTHORS.txt for contributors. |
|||
* |
|||
* This program is free software: you can redistribute it and/or modify it |
|||
* under the terms of the GNU General Public License as published by the |
|||
* Free Software Foundation, either version 3 of the License, or (at your |
|||
* option) any later version. |
|||
* |
|||
* This program is distributed in the hope that it will be useful, but |
|||
* WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|||
* General Public License for more details. |
|||
* |
|||
* You should have received a copy of the GNU General Public License along |
|||
* with this program. If not, see <http://www.gnu.org/licenses/>. |
|||
*/ |
|||
|
|||
#ifndef PCBNEW_COMPONENT_CLASS_MANAGER_H |
|||
#define PCBNEW_COMPONENT_CLASS_MANAGER_H |
|||
|
|||
#include <unordered_map> |
|||
#include <unordered_set> |
|||
#include <wx/string.h> |
|||
|
|||
#include <component_classes/component_class.h> |
|||
#include <project/component_class_settings.h> |
|||
|
|||
|
|||
class BOARD; |
|||
class COMPONENT_CLASS_ASSIGNMENT_RULE; |
|||
class DRC_TOOL; |
|||
class FOOTPRINT; |
|||
|
|||
/** |
|||
* A class to manage Component Classes in a board context |
|||
* |
|||
* This manager owns generated COMPONENT_CLASS objects, and guarantees that pointers to managed |
|||
* objects are valid for the duration of the board lifetime. Note that, in order to maintain this |
|||
* guarantee, there are two methods that must be called when updating the board from the netlist |
|||
* (InitNetlistUpdate and FinishNetlistUpdate). |
|||
*/ |
|||
class COMPONENT_CLASS_MANAGER |
|||
{ |
|||
public: |
|||
explicit COMPONENT_CLASS_MANAGER( BOARD* board ); |
|||
|
|||
/// @brief Gets the full effective class name for the given set of constituent classes |
|||
static wxString |
|||
GetFullClassNameForConstituents( const std::unordered_set<wxString>& classNames ); |
|||
|
|||
/// @brief Gets the full effective class name for the given set of constituent classes |
|||
/// @param classNames a sorted vector of consituent class names |
|||
static wxString GetFullClassNameForConstituents( const std::vector<wxString>& classNames ); |
|||
|
|||
/// @brief Gets an effective component class for the given constituent class names |
|||
/// @param classNames The names of the constituent component classes |
|||
/// @return Effective COMPONENT_CLASS object |
|||
COMPONENT_CLASS* |
|||
GetEffectiveStaticComponentClass( const std::unordered_set<wxString>& classNames ); |
|||
|
|||
/// Returns the unassigned component class |
|||
const COMPONENT_CLASS* GetNoneComponentClass() const { return m_noneClass.get(); } |
|||
|
|||
/// Prepare the manager for a board update |
|||
/// Must be called prior to updating the PCB from the netlist |
|||
void InitNetlistUpdate(); |
|||
|
|||
/// Cleans up the manager after a board update |
|||
/// Must be called after updating the PCB from the netlist |
|||
void FinishNetlistUpdate(); |
|||
|
|||
/// Fetches a read-only map of the fundamental component classes |
|||
std::unordered_set<wxString> GetClassNames() const; |
|||
|
|||
/// Synchronises all dynamic component class assignment rules |
|||
/// @returns false if rules fail to parse, true if successful |
|||
bool SyncDynamicComponentClassAssignments( |
|||
const std::vector<COMPONENT_CLASS_ASSIGNMENT_DATA>& aAssignments, |
|||
bool aGenerateSheetClasses, const std::unordered_set<wxString>& aNewSheetPaths ); |
|||
|
|||
/// Gets the dynamic component classes which match the given footprint |
|||
const COMPONENT_CLASS* GetDynamicComponentClassesForFootprint( const FOOTPRINT* footprint ); |
|||
|
|||
/// Gets the combined component class with the given static and dynamic constituent component classes |
|||
const COMPONENT_CLASS* GetCombinedComponentClass( const COMPONENT_CLASS* staticClass, |
|||
const COMPONENT_CLASS* dynamicClass ); |
|||
|
|||
/// Forces the component class for all footprints to be recalculated. This should be called before running DRC as |
|||
/// checking for valid component class cache entries is threadsafe, but computing them is not. Blocking during this |
|||
/// check would be a negative performance impact for DRC computation, so we force recalculation instead. |
|||
void ForceComponentClassRecalculation() const; |
|||
|
|||
/// Gets the component class validity ticker |
|||
/// Used to check validity of cached component classes |
|||
long long int GetTicker() const { return m_ticker; } |
|||
|
|||
/// Invalidates any caches component classes and recomputes caches if required. This will force |
|||
/// recomputation of component classes on next access |
|||
void InvalidateComponentClasses(); |
|||
|
|||
/// Rebuilds any caches that may be required by custom assignment rules |
|||
/// @param fp the footprint to rebuild. If null, rebuilds all footprint caches |
|||
void RebuildRequiredCaches( FOOTPRINT* aFootprint = nullptr ) const; |
|||
|
|||
/// Determines whether any custom dynamic rules have a custom assignment condition |
|||
bool HasCustomAssignmentConditions() const { return m_hasCustomAssignmentConditions; } |
|||
|
|||
static std::shared_ptr<COMPONENT_CLASS_ASSIGNMENT_RULE> |
|||
CompileAssignmentRule( const COMPONENT_CLASS_ASSIGNMENT_DATA& aAssignment ); |
|||
|
|||
protected: |
|||
/// Sorts the given class names in to canonical order |
|||
static std::vector<wxString> sortClassNames( const std::unordered_set<wxString>& classNames ); |
|||
|
|||
/// Returns a constituent component class, re-using an existing instantiation where possible |
|||
COMPONENT_CLASS* getOrCreateConstituentClass( const wxString& aClassName, |
|||
COMPONENT_CLASS::USAGE aContext ); |
|||
|
|||
/// Returns an effective component class for the given set of constituent class names |
|||
/// Precondition: aClassNames is sorted by sortClassNames |
|||
COMPONENT_CLASS* getOrCreateEffectiveClass( const std::vector<wxString>& aClassNames, |
|||
COMPONENT_CLASS::USAGE aContext ); |
|||
|
|||
/// The board these component classes are assigned to / from |
|||
BOARD* m_board; |
|||
|
|||
/// The class to represent an unassigned component class |
|||
std::shared_ptr<COMPONENT_CLASS> m_noneClass; |
|||
|
|||
/// All individual component classes from static assignments |
|||
std::unordered_map<wxString, std::unique_ptr<COMPONENT_CLASS>> m_constituentClasses; |
|||
|
|||
/// Generated effective (composite) static component classes |
|||
std::unordered_map<wxString, std::unique_ptr<COMPONENT_CLASS>> m_effectiveClasses; |
|||
|
|||
/// Cache of in-use static component class names |
|||
/// Used for cleanup following netlist updates |
|||
std::unordered_set<wxString> m_staticClassNamesCache; |
|||
|
|||
|
|||
/// Active component class assignment rules |
|||
std::vector<std::shared_ptr<COMPONENT_CLASS_ASSIGNMENT_RULE>> m_assignmentRules; |
|||
|
|||
/// Quick lookup of presence of custom dynamic assignment conditions |
|||
bool m_hasCustomAssignmentConditions; |
|||
|
|||
/// Monotonically increasing ticker to test cached component class validity |
|||
long long int m_ticker{ 0 }; |
|||
}; |
|||
|
|||
#endif |
|||
2417
pcbnew/dialogs/dialog_import_settings_base.fbp
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
@ -0,0 +1,788 @@ |
|||
/*
|
|||
* This program source code file is part of KiCad, a free EDA CAD application. |
|||
* |
|||
* Copyright The KiCad Developers, see AUTHORS.txt for contributors. |
|||
* |
|||
* This program is free software; you can redistribute it and/or |
|||
* modify it under the terms of the GNU General Public License |
|||
* as published by the Free Software Foundation; either version 2 |
|||
* of the License, or (at your option) any later version. |
|||
* |
|||
* This program is distributed in the hope that it will be useful, |
|||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
* GNU General Public License for more details. |
|||
* |
|||
* You should have received a copy of the GNU General Public License |
|||
* along with this program; if not, you may find one here: |
|||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
|||
* or you may search the http://www.gnu.org website for the version 2 license,
|
|||
* or you may write to the Free Software Foundation, Inc., |
|||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA |
|||
*/ |
|||
|
|||
|
|||
#include <dialogs/panel_assign_component_classes.h>
|
|||
|
|||
#include <bitmaps.h>
|
|||
#include <board.h>
|
|||
#include <component_classes/component_class_assignment_rule.h>
|
|||
#include <component_classes/component_class_manager.h>
|
|||
#include <footprint.h>
|
|||
#include <kiway.h>
|
|||
#include <pcb_edit_frame.h>
|
|||
#include <project/project_file.h>
|
|||
#include <tool/selection_tool.h>
|
|||
#include <tool/tool_manager.h>
|
|||
#include <tools/pcb_selection_tool.h>
|
|||
#include <widgets/paged_dialog.h>
|
|||
#include <widgets/std_bitmap_button.h>
|
|||
|
|||
|
|||
/**************************************************************************************************
|
|||
* |
|||
* PANEL_ASSIGN_COMPONENT_CLASSES implementation |
|||
* This is the top-level panel for component class configuration |
|||
* |
|||
*************************************************************************************************/ |
|||
|
|||
PANEL_ASSIGN_COMPONENT_CLASSES::PANEL_ASSIGN_COMPONENT_CLASSES( |
|||
wxWindow* aParentWindow, PCB_EDIT_FRAME* aFrame, |
|||
std::shared_ptr<COMPONENT_CLASS_SETTINGS> aSettings, DIALOG_SHIM* aDlg ) : |
|||
PANEL_ASSIGN_COMPONENT_CLASSES_BASE( aParentWindow ), m_dlg( aDlg ), m_frame( aFrame ), |
|||
m_componentClassSettings( std::move( aSettings ) ), |
|||
m_assignmentsList( static_cast<wxBoxSizer*>( m_assignmentsScrollWindow->GetSizer() ) ) |
|||
{ |
|||
// Load footprint fields and sheet names
|
|||
const BOARD* board = dynamic_cast<BOARD*>( m_frame->GetModel() ); |
|||
std::set<wxString> fieldsSet; |
|||
std::set<wxString> sheetsSet; |
|||
|
|||
for( const FOOTPRINT* fp : board->Footprints() ) |
|||
{ |
|||
wxString sheetName = fp->GetSheetname(); |
|||
|
|||
if( !sheetName.empty() ) |
|||
{ |
|||
sheetName.Replace( wxT( "\"" ), wxT( "" ) ); |
|||
sheetName.Replace( wxT( "'" ), wxT( "" ) ); |
|||
sheetsSet.insert( fp->GetSheetname() ); |
|||
} |
|||
|
|||
for( const PCB_FIELD* field : fp->GetFields() ) |
|||
fieldsSet.insert( field->GetName() ); |
|||
} |
|||
|
|||
// Sort field names
|
|||
std::vector<wxString> fieldNames( fieldsSet.begin(), fieldsSet.end() ); |
|||
std::ranges::sort( fieldNames, |
|||
[]( const wxString& a, const wxString& b ) |
|||
{ |
|||
return a.Cmp( b ) < 0; |
|||
} ); |
|||
|
|||
m_fieldNames = std::move( fieldNames ); |
|||
|
|||
// Sort sheet names
|
|||
std::vector<wxString> sheetNames( sheetsSet.begin(), sheetsSet.end() ); |
|||
std::ranges::sort( sheetNames, |
|||
[]( const wxString& a, const wxString& b ) |
|||
{ |
|||
return a.Cmp( b ) < 0; |
|||
} ); |
|||
|
|||
m_sheetNames = std::move( sheetNames ); |
|||
|
|||
// Get references of currently selected items
|
|||
std::set<wxString> refsSet; |
|||
|
|||
for( const EDA_ITEM* item : m_frame->GetCurrentSelection() ) |
|||
{ |
|||
if( item->Type() != PCB_FOOTPRINT_T ) |
|||
continue; |
|||
|
|||
const FOOTPRINT* fp = static_cast<const FOOTPRINT*>( item ); |
|||
wxString ref = fp->GetReferenceAsString(); |
|||
refsSet.insert( ref ); |
|||
} |
|||
|
|||
std::vector<wxString> refs( refsSet.begin(), refsSet.end() ); |
|||
std::ranges::sort( refs, |
|||
[]( const wxString& a, const wxString& b ) |
|||
{ |
|||
return a.Cmp( b ) < 0; |
|||
} ); |
|||
|
|||
m_selectionRefs = std::move( refs ); |
|||
} |
|||
|
|||
|
|||
PANEL_ASSIGN_COMPONENT_CLASSES::~PANEL_ASSIGN_COMPONENT_CLASSES() |
|||
{ |
|||
BOARD* board = dynamic_cast<BOARD*>( m_frame->GetModel() ); |
|||
PCB_SELECTION_TOOL* selTool = m_frame->GetToolManager()->GetTool<PCB_SELECTION_TOOL>(); |
|||
|
|||
for( FOOTPRINT* fp : board->Footprints() ) |
|||
selTool->UnbrightenItem( fp ); |
|||
|
|||
m_frame->GetCanvas()->Refresh(); |
|||
} |
|||
|
|||
|
|||
bool PANEL_ASSIGN_COMPONENT_CLASSES::TransferDataToWindow() |
|||
{ |
|||
// Load sheet-level settings
|
|||
m_assignSheetClasses->SetValue( m_componentClassSettings->GetEnableSheetComponentClasses() ); |
|||
|
|||
// Load dynamic component class assignments
|
|||
for( const COMPONENT_CLASS_ASSIGNMENT_DATA& assignmentData : |
|||
m_componentClassSettings->GetComponentClassAssignments() ) |
|||
{ |
|||
PANEL_COMPONENT_CLASS_ASSIGNMENT* assignment = addAssignment(); |
|||
assignment->SetComponentClass( assignmentData.GetComponentClass() ); |
|||
assignment->SetConditionsOperator( assignmentData.GetConditionsOperator() ); |
|||
|
|||
for( const auto& [conditionType, conditionData] : assignmentData.GetConditions() ) |
|||
{ |
|||
CONDITION_DATA* match = assignment->AddCondition( conditionType ); |
|||
match->SetPrimaryField( conditionData.first ); |
|||
match->SetSecondaryField( conditionData.second ); |
|||
} |
|||
} |
|||
|
|||
return true; |
|||
} |
|||
|
|||
|
|||
bool PANEL_ASSIGN_COMPONENT_CLASSES::TransferDataFromWindow() |
|||
{ |
|||
if( !Validate() ) |
|||
return false; |
|||
|
|||
// Save sheet-level settings
|
|||
m_componentClassSettings->SetEnableSheetComponentClasses( m_assignSheetClasses->GetValue() ); |
|||
|
|||
// Save dynamic component class assignments
|
|||
m_componentClassSettings->ClearComponentClassAssignments(); |
|||
|
|||
for( const auto assignment : m_assignments ) |
|||
{ |
|||
COMPONENT_CLASS_ASSIGNMENT_DATA assignmentData = assignment->GenerateAssignmentData(); |
|||
m_componentClassSettings->AddComponentClassAssignment( assignmentData ); |
|||
} |
|||
|
|||
return true; |
|||
} |
|||
|
|||
|
|||
bool PANEL_ASSIGN_COMPONENT_CLASSES::Validate() |
|||
{ |
|||
PCB_EDIT_FRAME* frame = GetFrame(); |
|||
BOARD* board = dynamic_cast<BOARD*>( frame->GetModel() ); |
|||
|
|||
frame->GetCanvas()->Refresh(); |
|||
|
|||
for( PANEL_COMPONENT_CLASS_ASSIGNMENT* assignment : m_assignments ) |
|||
{ |
|||
const COMPONENT_CLASS_ASSIGNMENT_DATA assignmentData = assignment->GenerateAssignmentData(); |
|||
const std::shared_ptr<COMPONENT_CLASS_ASSIGNMENT_RULE> rule = |
|||
board->GetComponentClassManager().CompileAssignmentRule( assignmentData ); |
|||
|
|||
if( !rule ) |
|||
{ |
|||
const wxString msg = wxString::Format( |
|||
_( "Error with conditions for component class assignment %s" ), |
|||
assignment->GetComponentClass() ); |
|||
PAGED_DIALOG::GetDialog( this )->SetError( msg, this, assignment ); |
|||
scrollToAssignment( assignment ); |
|||
assignment->SetFocus(); |
|||
return false; |
|||
} |
|||
} |
|||
|
|||
return true; |
|||
} |
|||
|
|||
|
|||
void PANEL_ASSIGN_COMPONENT_CLASSES::OnAddAssignmentClick( wxCommandEvent& event ) |
|||
{ |
|||
PANEL_COMPONENT_CLASS_ASSIGNMENT* assignment = addAssignment(); |
|||
scrollToAssignment( assignment ); |
|||
} |
|||
|
|||
|
|||
PANEL_COMPONENT_CLASS_ASSIGNMENT* PANEL_ASSIGN_COMPONENT_CLASSES::addAssignment() |
|||
{ |
|||
PANEL_COMPONENT_CLASS_ASSIGNMENT* assignmentPanel = |
|||
new PANEL_COMPONENT_CLASS_ASSIGNMENT( m_assignmentsScrollWindow, this, m_dlg ); |
|||
|
|||
#if __OSX__
|
|||
m_assignmentsList->Add( assignmentPanel, 0, wxEXPAND, 5 ); |
|||
#else
|
|||
m_assignmentsList->Add( assignmentPanel, 0, wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM, 5 ); |
|||
#endif
|
|||
|
|||
Layout(); |
|||
|
|||
m_assignments.push_back( assignmentPanel ); |
|||
|
|||
return assignmentPanel; |
|||
} |
|||
|
|||
|
|||
void PANEL_ASSIGN_COMPONENT_CLASSES::scrollToAssignment( |
|||
const PANEL_COMPONENT_CLASS_ASSIGNMENT* aAssignment ) const |
|||
{ |
|||
const wxPoint viewStart = m_assignmentsScrollWindow->GetViewStart(); |
|||
const wxPoint panelPosition = aAssignment->GetPosition(); |
|||
const wxSize panelSize = aAssignment->GetClientSize(); |
|||
|
|||
m_assignmentsScrollWindow->Scroll( viewStart.x, panelPosition.y + panelSize.y ); |
|||
} |
|||
|
|||
|
|||
void PANEL_ASSIGN_COMPONENT_CLASSES::RemoveAssignment( PANEL_COMPONENT_CLASS_ASSIGNMENT* aPanel ) |
|||
{ |
|||
m_assignments.erase( std::ranges::find( m_assignments, aPanel ) ); |
|||
m_assignmentsList->Detach( aPanel ); |
|||
aPanel->Destroy(); |
|||
Layout(); |
|||
} |
|||
|
|||
|
|||
void PANEL_ASSIGN_COMPONENT_CLASSES::ImportSettingsFrom( |
|||
const std::shared_ptr<COMPONENT_CLASS_SETTINGS>& aOtherSettings ) |
|||
{ |
|||
std::shared_ptr<COMPONENT_CLASS_SETTINGS> savedSettings = m_componentClassSettings; |
|||
|
|||
m_componentClassSettings = aOtherSettings; |
|||
TransferDataToWindow(); |
|||
|
|||
m_componentClassSettings = std::move( savedSettings ); |
|||
} |
|||
|
|||
|
|||
/**************************************************************************************************
|
|||
* |
|||
* CONDITION_DATA implementation |
|||
* Provides a common interface for all condition panel types |
|||
* |
|||
*************************************************************************************************/ |
|||
|
|||
wxString CONDITION_DATA::GetPrimaryField() const |
|||
{ |
|||
wxString data = m_primaryCtrl->GetValue(); |
|||
data.Trim( true ); |
|||
data.Trim( false ); |
|||
|
|||
if( m_conditionType != COMPONENT_CLASS_ASSIGNMENT_DATA::CONDITION_TYPE::CUSTOM ) |
|||
{ |
|||
data.Replace( wxT( "\"" ), wxT( "" ) ); |
|||
data.Replace( wxT( "'" ), wxT( "" ) ); |
|||
} |
|||
|
|||
return data; |
|||
} |
|||
|
|||
|
|||
void CONDITION_DATA::SetPrimaryField( const wxString& aVal ) |
|||
{ |
|||
m_primaryCtrl->SetValue( aVal ); |
|||
} |
|||
|
|||
|
|||
wxString CONDITION_DATA::GetSecondaryField() const |
|||
{ |
|||
if( !m_secondaryCtrl ) |
|||
return wxEmptyString; |
|||
|
|||
wxString data = m_secondaryCtrl->GetValue(); |
|||
data.Trim( true ); |
|||
data.Trim( false ); |
|||
|
|||
if( m_conditionType != COMPONENT_CLASS_ASSIGNMENT_DATA::CONDITION_TYPE::CUSTOM ) |
|||
{ |
|||
data.Replace( wxT( "\"" ), wxT( "" ) ); |
|||
data.Replace( wxT( "'" ), wxT( "" ) ); |
|||
} |
|||
|
|||
return data; |
|||
} |
|||
|
|||
|
|||
void CONDITION_DATA::SetSecondaryField( const wxString& aVal ) |
|||
{ |
|||
if( m_secondaryCtrl ) |
|||
m_secondaryCtrl->SetValue( aVal ); |
|||
}; |
|||
|
|||
/**************************************************************************************************
|
|||
* |
|||
* PANEL_COMPONENT_CLASS_ASSIGNMENT implementation |
|||
* This is the dynamically-added panel for each component class assignment rule set |
|||
* |
|||
*************************************************************************************************/ |
|||
|
|||
PANEL_COMPONENT_CLASS_ASSIGNMENT::PANEL_COMPONENT_CLASS_ASSIGNMENT( |
|||
wxWindow* aParent, PANEL_ASSIGN_COMPONENT_CLASSES* aPanelParent, DIALOG_SHIM* aDlg ) : |
|||
PANEL_COMPONENT_CLASS_ASSIGNMENT_BASE( aParent ), m_parentPanel( aPanelParent ), |
|||
m_matchesList( static_cast<wxStaticBoxSizer*>( GetSizer() ) ), m_dlg( aDlg ) |
|||
{ |
|||
m_buttonAddCondition->SetBitmap( KiBitmapBundle( BITMAPS::small_plus ) ); |
|||
m_buttonDeleteAssignment->SetBitmap( KiBitmapBundle( BITMAPS::small_trash ) ); |
|||
m_buttonHighlightItems->SetBitmap( KiBitmapBundle( BITMAPS::net_highlight ) ); |
|||
|
|||
Connect( wxEVT_MENU, wxCommandEventHandler( PANEL_COMPONENT_CLASS_ASSIGNMENT::onMenu ), nullptr, |
|||
this ); |
|||
} |
|||
|
|||
|
|||
PANEL_COMPONENT_CLASS_ASSIGNMENT::~PANEL_COMPONENT_CLASS_ASSIGNMENT() |
|||
{ |
|||
Disconnect( wxEVT_MENU, wxCommandEventHandler( PANEL_COMPONENT_CLASS_ASSIGNMENT::onMenu ), |
|||
nullptr, this ); |
|||
} |
|||
|
|||
|
|||
COMPONENT_CLASS_ASSIGNMENT_DATA PANEL_COMPONENT_CLASS_ASSIGNMENT::GenerateAssignmentData() const |
|||
{ |
|||
COMPONENT_CLASS_ASSIGNMENT_DATA assignmentData; |
|||
assignmentData.SetComponentClass( GetComponentClass() ); |
|||
assignmentData.SetConditionsOperation( GetConditionsOperator() ); |
|||
|
|||
for( const auto& condition : GetConditions() ) |
|||
{ |
|||
assignmentData.SetCondition( condition->GetConditionType(), condition->GetPrimaryField(), |
|||
condition->GetSecondaryField() ); |
|||
} |
|||
|
|||
return assignmentData; |
|||
} |
|||
|
|||
|
|||
void PANEL_COMPONENT_CLASS_ASSIGNMENT::OnAddConditionClick( wxCommandEvent& event ) |
|||
{ |
|||
auto hasCondition = [this]( const COMPONENT_CLASS_ASSIGNMENT_DATA::CONDITION_TYPE aCondition ) |
|||
{ |
|||
return m_conditionTypes.contains( aCondition ); |
|||
}; |
|||
|
|||
wxMenu menu; |
|||
menu.Append( ID_REFERENCE, _( "Reference..." ) ); |
|||
menu.Append( ID_FOOTPRINT, _( "Footprint..." ) ); |
|||
menu.Append( ID_SIDE, _( "Side..." ) ); |
|||
menu.Append( ID_ROTATION, _( "Rotation..." ) ); |
|||
menu.Append( ID_FOOTPRINT_FIELD, _( "Footprint Field..." ) ); |
|||
menu.Append( ID_SHEET_NAME, _( "Sheet Name..." ) ); |
|||
menu.Append( ID_CUSTOM, _( "Custom..." ) ); |
|||
menu.Enable( ID_REFERENCE, |
|||
!hasCondition( COMPONENT_CLASS_ASSIGNMENT_DATA::CONDITION_TYPE::REFERENCE ) ); |
|||
menu.Enable( ID_FOOTPRINT, |
|||
!hasCondition( COMPONENT_CLASS_ASSIGNMENT_DATA::CONDITION_TYPE::FOOTPRINT ) ); |
|||
menu.Enable( ID_SIDE, !hasCondition( COMPONENT_CLASS_ASSIGNMENT_DATA::CONDITION_TYPE::SIDE ) ); |
|||
menu.Enable( ID_ROTATION, |
|||
!hasCondition( COMPONENT_CLASS_ASSIGNMENT_DATA::CONDITION_TYPE::ROTATION ) ); |
|||
menu.Enable( |
|||
ID_FOOTPRINT_FIELD, |
|||
!hasCondition( COMPONENT_CLASS_ASSIGNMENT_DATA::CONDITION_TYPE::FOOTPRINT_FIELD ) ); |
|||
menu.Enable( ID_CUSTOM, |
|||
!hasCondition( COMPONENT_CLASS_ASSIGNMENT_DATA::CONDITION_TYPE::CUSTOM ) ); |
|||
menu.Enable( ID_SHEET_NAME, |
|||
!hasCondition( COMPONENT_CLASS_ASSIGNMENT_DATA::CONDITION_TYPE::SHEET_NAME ) ); |
|||
PopupMenu( &menu ); |
|||
} |
|||
|
|||
|
|||
void PANEL_COMPONENT_CLASS_ASSIGNMENT::OnDeleteAssignmentClick( wxCommandEvent& event ) |
|||
{ |
|||
m_parentPanel->RemoveAssignment( this ); |
|||
} |
|||
|
|||
|
|||
void PANEL_COMPONENT_CLASS_ASSIGNMENT::SetComponentClass( const wxString& aComponentClass ) const |
|||
{ |
|||
m_componentClass->SetValue( aComponentClass ); |
|||
} |
|||
|
|||
|
|||
const wxString PANEL_COMPONENT_CLASS_ASSIGNMENT::GetComponentClass() const |
|||
{ |
|||
return m_componentClass->GetValue(); |
|||
} |
|||
|
|||
|
|||
void PANEL_COMPONENT_CLASS_ASSIGNMENT::onMenu( wxCommandEvent& aEvent ) |
|||
{ |
|||
switch( aEvent.GetId() ) |
|||
{ |
|||
case ID_REFERENCE: |
|||
AddCondition( COMPONENT_CLASS_ASSIGNMENT_DATA::CONDITION_TYPE::REFERENCE ); |
|||
break; |
|||
case ID_FOOTPRINT: |
|||
AddCondition( COMPONENT_CLASS_ASSIGNMENT_DATA::CONDITION_TYPE::FOOTPRINT ); |
|||
break; |
|||
case ID_SIDE: AddCondition( COMPONENT_CLASS_ASSIGNMENT_DATA::CONDITION_TYPE::SIDE ); break; |
|||
case ID_ROTATION: |
|||
AddCondition( COMPONENT_CLASS_ASSIGNMENT_DATA::CONDITION_TYPE::ROTATION ); |
|||
break; |
|||
case ID_FOOTPRINT_FIELD: |
|||
AddCondition( COMPONENT_CLASS_ASSIGNMENT_DATA::CONDITION_TYPE::FOOTPRINT_FIELD ); |
|||
break; |
|||
case ID_CUSTOM: AddCondition( COMPONENT_CLASS_ASSIGNMENT_DATA::CONDITION_TYPE::CUSTOM ); break; |
|||
case ID_SHEET_NAME: |
|||
AddCondition( COMPONENT_CLASS_ASSIGNMENT_DATA::CONDITION_TYPE::SHEET_NAME ); |
|||
break; |
|||
|
|||
default: wxFAIL_MSG( wxT( "Unknown ID in context menu event" ) ); |
|||
} |
|||
} |
|||
|
|||
|
|||
CONDITION_DATA* PANEL_COMPONENT_CLASS_ASSIGNMENT::AddCondition( |
|||
const COMPONENT_CLASS_ASSIGNMENT_DATA::CONDITION_TYPE aCondition ) |
|||
{ |
|||
wxASSERT_MSG( !m_conditionTypes.contains( aCondition ), "Condition type already exists" ); |
|||
|
|||
wxPanel* panelToAdd = nullptr; |
|||
|
|||
switch( aCondition ) |
|||
{ |
|||
case COMPONENT_CLASS_ASSIGNMENT_DATA::CONDITION_TYPE::REFERENCE: |
|||
{ |
|||
PANEL_COMPONENT_CLASS_CONDITION_REFERENCE* refsPanel = |
|||
new PANEL_COMPONENT_CLASS_CONDITION_REFERENCE( this ); |
|||
refsPanel->SetSelectionRefs( m_parentPanel->GetSelectionRefs() ); |
|||
panelToAdd = refsPanel; |
|||
m_conditionTypes.insert( COMPONENT_CLASS_ASSIGNMENT_DATA::CONDITION_TYPE::REFERENCE ); |
|||
break; |
|||
} |
|||
case COMPONENT_CLASS_ASSIGNMENT_DATA::CONDITION_TYPE::FOOTPRINT: |
|||
{ |
|||
panelToAdd = new PANEL_COMPONENT_CLASS_CONDITION_FOOTPRINT( this, m_dlg ); |
|||
m_conditionTypes.insert( COMPONENT_CLASS_ASSIGNMENT_DATA::CONDITION_TYPE::FOOTPRINT ); |
|||
break; |
|||
} |
|||
case COMPONENT_CLASS_ASSIGNMENT_DATA::CONDITION_TYPE::SIDE: |
|||
{ |
|||
panelToAdd = new PANEL_COMPONENT_CLASS_CONDITION_SIDE( this ); |
|||
m_conditionTypes.insert( COMPONENT_CLASS_ASSIGNMENT_DATA::CONDITION_TYPE::SIDE ); |
|||
break; |
|||
} |
|||
case COMPONENT_CLASS_ASSIGNMENT_DATA::CONDITION_TYPE::ROTATION: |
|||
{ |
|||
panelToAdd = new PANEL_COMPONENT_CLASS_CONDITION_ROTATION( this ); |
|||
m_conditionTypes.insert( COMPONENT_CLASS_ASSIGNMENT_DATA::CONDITION_TYPE::ROTATION ); |
|||
break; |
|||
} |
|||
case COMPONENT_CLASS_ASSIGNMENT_DATA::CONDITION_TYPE::FOOTPRINT_FIELD: |
|||
{ |
|||
PANEL_COMPONENT_CLASS_CONDITION_FIELD* fieldPanel = |
|||
new PANEL_COMPONENT_CLASS_CONDITION_FIELD( this ); |
|||
fieldPanel->SetFieldsList( m_parentPanel->GetFieldNames() ); |
|||
panelToAdd = fieldPanel; |
|||
m_conditionTypes.insert( COMPONENT_CLASS_ASSIGNMENT_DATA::CONDITION_TYPE::FOOTPRINT_FIELD ); |
|||
break; |
|||
} |
|||
case COMPONENT_CLASS_ASSIGNMENT_DATA::CONDITION_TYPE::CUSTOM: |
|||
{ |
|||
panelToAdd = new PANEL_COMPONENT_CLASS_CONDITION_CUSTOM( this ); |
|||
m_conditionTypes.insert( COMPONENT_CLASS_ASSIGNMENT_DATA::CONDITION_TYPE::CUSTOM ); |
|||
break; |
|||
} |
|||
case COMPONENT_CLASS_ASSIGNMENT_DATA::CONDITION_TYPE::SHEET_NAME: |
|||
{ |
|||
PANEL_COMPONENT_CLASS_CONDITION_SHEET* sheetPanel = |
|||
new PANEL_COMPONENT_CLASS_CONDITION_SHEET( this ); |
|||
sheetPanel->SetSheetsList( m_parentPanel->GetSheetNames() ); |
|||
panelToAdd = sheetPanel; |
|||
m_conditionTypes.insert( COMPONENT_CLASS_ASSIGNMENT_DATA::CONDITION_TYPE::SHEET_NAME ); |
|||
break; |
|||
} |
|||
} |
|||
|
|||
const size_t numItems = m_matchesList->GetItemCount(); |
|||
m_matchesList->Insert( numItems - 1, panelToAdd, 0, wxEXPAND | wxTOP, 5 ); |
|||
Layout(); |
|||
GetParent()->Layout(); |
|||
m_parentPanel->Layout(); |
|||
|
|||
CONDITION_DATA* conditionIface = dynamic_cast<CONDITION_DATA*>( panelToAdd ); |
|||
m_matches.push_back( conditionIface ); |
|||
|
|||
return conditionIface; |
|||
} |
|||
|
|||
|
|||
void PANEL_COMPONENT_CLASS_ASSIGNMENT::RemoveCondition( wxPanel* aMatch ) |
|||
{ |
|||
if( CONDITION_DATA* matchData = dynamic_cast<CONDITION_DATA*>( aMatch ) ) |
|||
{ |
|||
m_conditionTypes.erase( matchData->GetConditionType() ); |
|||
m_matches.erase( std::ranges::find( m_matches, matchData ) ); |
|||
} |
|||
|
|||
m_matchesList->Detach( aMatch ); |
|||
aMatch->Destroy(); |
|||
Layout(); |
|||
m_parentPanel->Layout(); |
|||
} |
|||
|
|||
|
|||
void PANEL_COMPONENT_CLASS_ASSIGNMENT::SetConditionsOperator( |
|||
const COMPONENT_CLASS_ASSIGNMENT_DATA::CONDITIONS_OPERATOR aCondition ) const |
|||
{ |
|||
if( aCondition == COMPONENT_CLASS_ASSIGNMENT_DATA::CONDITIONS_OPERATOR::ALL ) |
|||
{ |
|||
m_radioAll->SetValue( true ); |
|||
m_radioAny->SetValue( false ); |
|||
} |
|||
else |
|||
{ |
|||
m_radioAll->SetValue( false ); |
|||
m_radioAny->SetValue( true ); |
|||
} |
|||
} |
|||
|
|||
|
|||
COMPONENT_CLASS_ASSIGNMENT_DATA::CONDITIONS_OPERATOR |
|||
PANEL_COMPONENT_CLASS_ASSIGNMENT::GetConditionsOperator() const |
|||
{ |
|||
if( m_radioAll->GetValue() == true ) |
|||
return COMPONENT_CLASS_ASSIGNMENT_DATA::CONDITIONS_OPERATOR::ALL; |
|||
|
|||
return COMPONENT_CLASS_ASSIGNMENT_DATA::CONDITIONS_OPERATOR::ANY; |
|||
} |
|||
|
|||
|
|||
void PANEL_COMPONENT_CLASS_ASSIGNMENT::OnHighlightItemsClick( wxCommandEvent& event ) |
|||
{ |
|||
PCB_EDIT_FRAME* frame = m_parentPanel->GetFrame(); |
|||
BOARD* board = dynamic_cast<BOARD*>( frame->GetModel() ); |
|||
PCB_SELECTION_TOOL* selTool = frame->GetToolManager()->GetTool<PCB_SELECTION_TOOL>(); |
|||
|
|||
const COMPONENT_CLASS_ASSIGNMENT_DATA assignment = GenerateAssignmentData(); |
|||
const std::shared_ptr<COMPONENT_CLASS_ASSIGNMENT_RULE> rule = |
|||
board->GetComponentClassManager().CompileAssignmentRule( assignment ); |
|||
|
|||
if( !rule ) |
|||
return; |
|||
|
|||
for( FOOTPRINT* fp : board->Footprints() ) |
|||
{ |
|||
if( rule->Matches( fp ) ) |
|||
selTool->BrightenItem( fp ); |
|||
else |
|||
selTool->UnbrightenItem( fp ); |
|||
} |
|||
|
|||
frame->GetCanvas()->Refresh(); |
|||
} |
|||
|
|||
|
|||
/**************************************************************************************************
|
|||
* |
|||
* PANEL_COMPONENT_CLASS_CONDITION_* implementations |
|||
* These are the dynamically-added panels for each condition / match type |
|||
* |
|||
*************************************************************************************************/ |
|||
|
|||
PANEL_COMPONENT_CLASS_CONDITION_REFERENCE::PANEL_COMPONENT_CLASS_CONDITION_REFERENCE( |
|||
wxWindow* aParent ) : |
|||
PANEL_COMPONENT_CLASS_CONDITION_REFERENCE_BASE( aParent ), |
|||
CONDITION_DATA( COMPONENT_CLASS_ASSIGNMENT_DATA::CONDITION_TYPE::REFERENCE, m_refs ), |
|||
m_panelParent( static_cast<PANEL_COMPONENT_CLASS_ASSIGNMENT*>( aParent ) ) |
|||
{ |
|||
m_title->SetMinSize( { GetTextExtent( _( "Footprint Field:" ) ).x, -1 } ); |
|||
|
|||
m_buttonImportRefs->SetBitmap( KiBitmapBundle( BITMAPS::config ) ); |
|||
m_buttonDeleteMatch->SetBitmap( KiBitmapBundle( BITMAPS::small_trash ) ); |
|||
|
|||
Connect( wxEVT_MENU, wxCommandEventHandler( PANEL_COMPONENT_CLASS_CONDITION_REFERENCE::onMenu ), |
|||
nullptr, this ); |
|||
} |
|||
|
|||
|
|||
void PANEL_COMPONENT_CLASS_CONDITION_REFERENCE::OnDeleteConditionClick( wxCommandEvent& event ) |
|||
{ |
|||
m_panelParent->RemoveCondition( this ); |
|||
|
|||
Disconnect( wxEVT_MENU, |
|||
wxCommandEventHandler( PANEL_COMPONENT_CLASS_CONDITION_REFERENCE::onMenu ), nullptr, |
|||
this ); |
|||
} |
|||
|
|||
|
|||
void PANEL_COMPONENT_CLASS_CONDITION_REFERENCE::OnImportRefsClick( wxCommandEvent& event ) |
|||
{ |
|||
wxMenu menu; |
|||
menu.Append( ID_IMPORT_REFS, _( "Import references from selection" ) ); |
|||
menu.Enable( ID_IMPORT_REFS, !m_selectionRefs.empty() ); |
|||
PopupMenu( &menu ); |
|||
} |
|||
|
|||
|
|||
void PANEL_COMPONENT_CLASS_CONDITION_REFERENCE::onMenu( wxCommandEvent& aEvent ) |
|||
{ |
|||
if( aEvent.GetId() != ID_IMPORT_REFS ) |
|||
wxFAIL_MSG( wxT( "Unknown ID in context menu event" ) ); |
|||
|
|||
if( m_selectionRefs.empty() ) |
|||
return; |
|||
|
|||
wxString refs = m_selectionRefs[0]; |
|||
|
|||
for( size_t i = 1; i < m_selectionRefs.size(); i++ ) |
|||
{ |
|||
refs += wxT( "," ); |
|||
refs += m_selectionRefs[i]; |
|||
} |
|||
|
|||
m_refs->SetValue( refs ); |
|||
} |
|||
|
|||
|
|||
PANEL_COMPONENT_CLASS_CONDITION_FOOTPRINT::PANEL_COMPONENT_CLASS_CONDITION_FOOTPRINT( |
|||
wxWindow* aParent, DIALOG_SHIM* aDlg ) : |
|||
PANEL_COMPONENT_CLASS_CONDITION_FOOTPRINT_BASE( aParent ), |
|||
CONDITION_DATA( COMPONENT_CLASS_ASSIGNMENT_DATA::CONDITION_TYPE::FOOTPRINT, m_footprint ), |
|||
m_panelParent( static_cast<PANEL_COMPONENT_CLASS_ASSIGNMENT*>( aParent ) ), m_dlg( aDlg ) |
|||
{ |
|||
m_title->SetMinSize( { GetTextExtent( _( "Footprint Field:" ) ).x, -1 } ); |
|||
|
|||
m_buttonDeleteMatch->SetBitmap( KiBitmapBundle( BITMAPS::small_trash ) ); |
|||
m_buttonShowLibrary->SetBitmap( KiBitmapBundle( BITMAPS::small_library ) ); |
|||
} |
|||
|
|||
|
|||
void PANEL_COMPONENT_CLASS_CONDITION_FOOTPRINT::OnDeleteConditionClick( wxCommandEvent& event ) |
|||
{ |
|||
m_panelParent->RemoveCondition( this ); |
|||
} |
|||
|
|||
|
|||
void PANEL_COMPONENT_CLASS_CONDITION_FOOTPRINT::OnShowLibraryClick( wxCommandEvent& event ) |
|||
{ |
|||
wxString fpId = m_footprint->GetValue(); |
|||
|
|||
if( KIWAY_PLAYER* frame = m_dlg->Kiway().Player( FRAME_FOOTPRINT_CHOOSER, true, m_dlg ) ) |
|||
{ |
|||
if( frame->ShowModal( &fpId, this ) ) |
|||
{ |
|||
m_footprint->SetValue( fpId ); |
|||
} |
|||
|
|||
frame->Destroy(); |
|||
} |
|||
} |
|||
|
|||
|
|||
PANEL_COMPONENT_CLASS_CONDITION_SIDE::PANEL_COMPONENT_CLASS_CONDITION_SIDE( wxWindow* aParent ) : |
|||
PANEL_COMPONENT_CLASS_CONDITION_SIDE_BASE( aParent ), |
|||
CONDITION_DATA( COMPONENT_CLASS_ASSIGNMENT_DATA::CONDITION_TYPE::SIDE, m_side ), |
|||
m_panelParent( static_cast<PANEL_COMPONENT_CLASS_ASSIGNMENT*>( aParent ) ) |
|||
{ |
|||
m_title->SetMinSize( { GetTextExtent( _( "Footprint Field:" ) ).x, -1 } ); |
|||
|
|||
m_buttonDeleteMatch->SetBitmap( KiBitmapBundle( BITMAPS::small_trash ) ); |
|||
m_side->Append( wxT( "Any" ) ); |
|||
m_side->Append( wxT( "Front" ) ); |
|||
m_side->Append( wxT( "Back" ) ); |
|||
m_side->SetValue( wxT( "Any" ) ); |
|||
} |
|||
|
|||
|
|||
void PANEL_COMPONENT_CLASS_CONDITION_SIDE::OnDeleteConditionClick( wxCommandEvent& event ) |
|||
{ |
|||
m_panelParent->RemoveCondition( this ); |
|||
} |
|||
|
|||
|
|||
PANEL_COMPONENT_CLASS_CONDITION_ROTATION::PANEL_COMPONENT_CLASS_CONDITION_ROTATION( |
|||
wxWindow* aParent ) : |
|||
PANEL_COMPONENT_CLASS_CONDITION_ROTATION_BASE( aParent ), |
|||
CONDITION_DATA( COMPONENT_CLASS_ASSIGNMENT_DATA::CONDITION_TYPE::ROTATION, m_rotation ), |
|||
m_panelParent( static_cast<PANEL_COMPONENT_CLASS_ASSIGNMENT*>( aParent ) ) |
|||
{ |
|||
m_title->SetMinSize( { GetTextExtent( _( "Footprint Field:" ) ).x, -1 } ); |
|||
m_rotUnit->SetLabel( wxT( "°" ) ); |
|||
|
|||
m_buttonDeleteMatch->SetBitmap( KiBitmapBundle( BITMAPS::small_trash ) ); |
|||
m_rotation->Append( wxT( "Any" ) ); |
|||
m_rotation->Append( wxT( "0" ) ); |
|||
m_rotation->Append( wxT( "90" ) ); |
|||
m_rotation->Append( wxT( "180" ) ); |
|||
m_rotation->Append( wxT( "-90" ) ); |
|||
m_rotation->SetValue( wxT( "Any" ) ); |
|||
} |
|||
|
|||
|
|||
void PANEL_COMPONENT_CLASS_CONDITION_ROTATION::OnDeleteConditionClick( wxCommandEvent& event ) |
|||
{ |
|||
m_panelParent->RemoveCondition( this ); |
|||
} |
|||
|
|||
|
|||
PANEL_COMPONENT_CLASS_CONDITION_FIELD::PANEL_COMPONENT_CLASS_CONDITION_FIELD( wxWindow* aParent ) : |
|||
PANEL_COMPONENT_CLASS_CONDITION_FIELD_BASE( aParent ), |
|||
CONDITION_DATA( COMPONENT_CLASS_ASSIGNMENT_DATA::CONDITION_TYPE::FOOTPRINT_FIELD, |
|||
m_fieldName, m_fieldValue ), |
|||
m_panelParent( static_cast<PANEL_COMPONENT_CLASS_ASSIGNMENT*>( aParent ) ) |
|||
{ |
|||
m_title->SetMinSize( { GetTextExtent( _( "Footprint Field:" ) ).x, -1 } ); |
|||
|
|||
m_buttonDeleteMatch->SetBitmap( KiBitmapBundle( BITMAPS::small_trash ) ); |
|||
} |
|||
|
|||
|
|||
void PANEL_COMPONENT_CLASS_CONDITION_FIELD::OnDeleteConditionClick( wxCommandEvent& event ) |
|||
{ |
|||
m_panelParent->RemoveCondition( this ); |
|||
} |
|||
|
|||
|
|||
void PANEL_COMPONENT_CLASS_CONDITION_FIELD::SetFieldsList( const std::vector<wxString>& aFields ) |
|||
{ |
|||
m_fieldName->Append( aFields ); |
|||
} |
|||
|
|||
|
|||
PANEL_COMPONENT_CLASS_CONDITION_CUSTOM::PANEL_COMPONENT_CLASS_CONDITION_CUSTOM( |
|||
wxWindow* aParent ) : |
|||
PANEL_COMPONENT_CLASS_CONDITION_CUSTOM_BASE( aParent ), |
|||
CONDITION_DATA( COMPONENT_CLASS_ASSIGNMENT_DATA::CONDITION_TYPE::CUSTOM, |
|||
m_customCondition ), |
|||
m_panelParent( static_cast<PANEL_COMPONENT_CLASS_ASSIGNMENT*>( aParent ) ) |
|||
{ |
|||
m_title->SetMinSize( { GetTextExtent( _( "Footprint Field:" ) ).x, -1 } ); |
|||
|
|||
m_buttonDeleteMatch->SetBitmap( KiBitmapBundle( BITMAPS::small_trash ) ); |
|||
} |
|||
|
|||
|
|||
void PANEL_COMPONENT_CLASS_CONDITION_CUSTOM::OnDeleteConditionClick( wxCommandEvent& event ) |
|||
{ |
|||
m_panelParent->RemoveCondition( this ); |
|||
} |
|||
|
|||
|
|||
PANEL_COMPONENT_CLASS_CONDITION_SHEET::PANEL_COMPONENT_CLASS_CONDITION_SHEET( wxWindow* aParent ) : |
|||
PANEL_COMPONENT_CLASS_CONDITION_SHEET_BASE( aParent ), |
|||
CONDITION_DATA( COMPONENT_CLASS_ASSIGNMENT_DATA::CONDITION_TYPE::SHEET_NAME, m_sheetName ), |
|||
m_panelParent( static_cast<PANEL_COMPONENT_CLASS_ASSIGNMENT*>( aParent ) ) |
|||
{ |
|||
m_title->SetMinSize( { GetTextExtent( _( "Footprint Field:" ) ).x, -1 } ); |
|||
|
|||
m_buttonDeleteMatch->SetBitmap( KiBitmapBundle( BITMAPS::small_trash ) ); |
|||
} |
|||
|
|||
|
|||
void PANEL_COMPONENT_CLASS_CONDITION_SHEET::OnDeleteConditionClick( wxCommandEvent& event ) |
|||
{ |
|||
m_panelParent->RemoveCondition( this ); |
|||
} |
|||
|
|||
|
|||
void PANEL_COMPONENT_CLASS_CONDITION_SHEET::SetSheetsList( const std::vector<wxString>& aSheets ) |
|||
{ |
|||
m_sheetName->Append( aSheets ); |
|||
} |
|||
@ -0,0 +1,471 @@ |
|||
///////////////////////////////////////////////////////////////////////////
|
|||
// C++ code generated with wxFormBuilder (version 4.2.1-0-g80c4cb6)
|
|||
// http://www.wxformbuilder.org/
|
|||
//
|
|||
// PLEASE DO *NOT* EDIT THIS FILE!
|
|||
///////////////////////////////////////////////////////////////////////////
|
|||
|
|||
#include "widgets/std_bitmap_button.h"
|
|||
|
|||
#include "panel_assign_component_classes_base.h"
|
|||
|
|||
///////////////////////////////////////////////////////////////////////////
|
|||
|
|||
PANEL_ASSIGN_COMPONENT_CLASSES_BASE::PANEL_ASSIGN_COMPONENT_CLASSES_BASE( wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style, const wxString& name ) : wxPanel( parent, id, pos, size, style, name ) |
|||
{ |
|||
wxBoxSizer* bSizerMain; |
|||
bSizerMain = new wxBoxSizer( wxVERTICAL ); |
|||
|
|||
m_assignSheetClasses = new wxCheckBox( this, wxID_ANY, _("Assign component class per sheet"), wxDefaultPosition, wxDefaultSize, 0 ); |
|||
bSizerMain->Add( m_assignSheetClasses, 0, wxALL, 5 ); |
|||
|
|||
m_staticline1 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL ); |
|||
bSizerMain->Add( m_staticline1, 0, wxEXPAND | wxALL, 5 ); |
|||
|
|||
wxFlexGridSizer* fgSizer8; |
|||
fgSizer8 = new wxFlexGridSizer( 0, 3, 0, 0 ); |
|||
fgSizer8->AddGrowableCol( 1 ); |
|||
fgSizer8->SetFlexibleDirection( wxHORIZONTAL ); |
|||
fgSizer8->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED ); |
|||
|
|||
m_staticText3 = new wxStaticText( this, wxID_ANY, _("Custom Assignments:"), wxDefaultPosition, wxDefaultSize, 0 ); |
|||
m_staticText3->Wrap( -1 ); |
|||
fgSizer8->Add( m_staticText3, 0, wxALL, 5 ); |
|||
|
|||
|
|||
fgSizer8->Add( 0, 0, 1, wxEXPAND, 5 ); |
|||
|
|||
m_btnAddAssignment = new wxButton( this, wxID_ANY, _("Add Custom Assignment"), wxDefaultPosition, wxDefaultSize, 0 ); |
|||
fgSizer8->Add( m_btnAddAssignment, 0, wxALL, 5 ); |
|||
|
|||
|
|||
bSizerMain->Add( fgSizer8, 0, wxEXPAND, 5 ); |
|||
|
|||
m_assignmentsScrollWindow = new wxScrolledWindow( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxHSCROLL|wxVSCROLL ); |
|||
m_assignmentsScrollWindow->SetScrollRate( 5, 5 ); |
|||
wxBoxSizer* m_assignmentsList; |
|||
m_assignmentsList = new wxBoxSizer( wxVERTICAL ); |
|||
|
|||
|
|||
m_assignmentsScrollWindow->SetSizer( m_assignmentsList ); |
|||
m_assignmentsScrollWindow->Layout(); |
|||
m_assignmentsList->Fit( m_assignmentsScrollWindow ); |
|||
bSizerMain->Add( m_assignmentsScrollWindow, 1, wxALL|wxEXPAND, 5 ); |
|||
|
|||
|
|||
this->SetSizer( bSizerMain ); |
|||
this->Layout(); |
|||
bSizerMain->Fit( this ); |
|||
|
|||
// Connect Events
|
|||
m_btnAddAssignment->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_ASSIGN_COMPONENT_CLASSES_BASE::OnAddAssignmentClick ), NULL, this ); |
|||
} |
|||
|
|||
PANEL_ASSIGN_COMPONENT_CLASSES_BASE::~PANEL_ASSIGN_COMPONENT_CLASSES_BASE() |
|||
{ |
|||
// Disconnect Events
|
|||
m_btnAddAssignment->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_ASSIGN_COMPONENT_CLASSES_BASE::OnAddAssignmentClick ), NULL, this ); |
|||
|
|||
} |
|||
|
|||
PANEL_COMPONENT_CLASS_ASSIGNMENT_BASE::PANEL_COMPONENT_CLASS_ASSIGNMENT_BASE( wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style, const wxString& name ) : wxPanel( parent, id, pos, size, style, name ) |
|||
{ |
|||
this->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_3DLIGHT ) ); |
|||
|
|||
wxStaticBoxSizer* m_assignmentGroup; |
|||
m_assignmentGroup = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, wxEmptyString ), wxVERTICAL ); |
|||
|
|||
wxFlexGridSizer* m_header; |
|||
m_header = new wxFlexGridSizer( 0, 5, 0, 0 ); |
|||
m_header->AddGrowableCol( 1 ); |
|||
m_header->SetFlexibleDirection( wxHORIZONTAL ); |
|||
m_header->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_NONE ); |
|||
|
|||
m_staticText101 = new wxStaticText( m_assignmentGroup->GetStaticBox(), wxID_ANY, _("Component Class:"), wxDefaultPosition, wxDefaultSize, 0 ); |
|||
m_staticText101->Wrap( -1 ); |
|||
m_header->Add( m_staticText101, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); |
|||
|
|||
m_componentClass = new wxTextCtrl( m_assignmentGroup->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); |
|||
m_header->Add( m_componentClass, 0, wxALIGN_CENTER_VERTICAL|wxALL|wxEXPAND, 5 ); |
|||
|
|||
|
|||
m_header->Add( 10, 0, 1, wxEXPAND, 5 ); |
|||
|
|||
m_buttonHighlightItems = new STD_BITMAP_BUTTON( m_assignmentGroup->GetStaticBox(), wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW|0 ); |
|||
m_header->Add( m_buttonHighlightItems, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); |
|||
|
|||
m_buttonDeleteAssignment = new STD_BITMAP_BUTTON( m_assignmentGroup->GetStaticBox(), wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW|0 ); |
|||
m_header->Add( m_buttonDeleteAssignment, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); |
|||
|
|||
|
|||
m_assignmentGroup->Add( m_header, 0, wxEXPAND, 0 ); |
|||
|
|||
wxBoxSizer* bSizer4; |
|||
bSizer4 = new wxBoxSizer( wxVERTICAL ); |
|||
|
|||
|
|||
bSizer4->Add( 0, 5, 0, 0, 5 ); |
|||
|
|||
wxBoxSizer* bSizer3; |
|||
bSizer3 = new wxBoxSizer( wxHORIZONTAL ); |
|||
|
|||
m_buttonAddCondition = new STD_BITMAP_BUTTON( m_assignmentGroup->GetStaticBox(), wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW|0 ); |
|||
bSizer3->Add( m_buttonAddCondition, 0, wxALIGN_CENTER_VERTICAL, 0 ); |
|||
|
|||
|
|||
bSizer3->Add( 0, 0, 1, wxEXPAND, 5 ); |
|||
|
|||
m_radioAll = new wxRadioButton( m_assignmentGroup->GetStaticBox(), wxID_ANY, _("Match All"), wxDefaultPosition, wxDefaultSize, 0 ); |
|||
m_radioAll->SetValue( true ); |
|||
bSizer3->Add( m_radioAll, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); |
|||
|
|||
m_radioAny = new wxRadioButton( m_assignmentGroup->GetStaticBox(), wxID_ANY, _("Match Any"), wxDefaultPosition, wxDefaultSize, 0 ); |
|||
bSizer3->Add( m_radioAny, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); |
|||
|
|||
|
|||
bSizer4->Add( bSizer3, 0, wxEXPAND, 5 ); |
|||
|
|||
|
|||
m_assignmentGroup->Add( bSizer4, 0, wxEXPAND, 5 ); |
|||
|
|||
|
|||
this->SetSizer( m_assignmentGroup ); |
|||
this->Layout(); |
|||
m_assignmentGroup->Fit( this ); |
|||
|
|||
// Connect Events
|
|||
m_buttonHighlightItems->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_COMPONENT_CLASS_ASSIGNMENT_BASE::OnHighlightItemsClick ), NULL, this ); |
|||
m_buttonDeleteAssignment->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_COMPONENT_CLASS_ASSIGNMENT_BASE::OnDeleteAssignmentClick ), NULL, this ); |
|||
m_buttonAddCondition->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_COMPONENT_CLASS_ASSIGNMENT_BASE::OnAddConditionClick ), NULL, this ); |
|||
} |
|||
|
|||
PANEL_COMPONENT_CLASS_ASSIGNMENT_BASE::~PANEL_COMPONENT_CLASS_ASSIGNMENT_BASE() |
|||
{ |
|||
// Disconnect Events
|
|||
m_buttonHighlightItems->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_COMPONENT_CLASS_ASSIGNMENT_BASE::OnHighlightItemsClick ), NULL, this ); |
|||
m_buttonDeleteAssignment->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_COMPONENT_CLASS_ASSIGNMENT_BASE::OnDeleteAssignmentClick ), NULL, this ); |
|||
m_buttonAddCondition->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_COMPONENT_CLASS_ASSIGNMENT_BASE::OnAddConditionClick ), NULL, this ); |
|||
|
|||
} |
|||
|
|||
PANEL_COMPONENT_CLASS_CONDITION_REFERENCE_BASE::PANEL_COMPONENT_CLASS_CONDITION_REFERENCE_BASE( wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style, const wxString& name ) : wxPanel( parent, id, pos, size, style, name ) |
|||
{ |
|||
this->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_3DLIGHT ) ); |
|||
|
|||
wxFlexGridSizer* m_conditionSizer; |
|||
m_conditionSizer = new wxFlexGridSizer( 0, 65, 0, 0 ); |
|||
m_conditionSizer->AddGrowableCol( 1 ); |
|||
m_conditionSizer->SetFlexibleDirection( wxBOTH ); |
|||
m_conditionSizer->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED ); |
|||
|
|||
m_title = new wxStaticText( this, wxID_ANY, _("Reference:"), wxDefaultPosition, wxDefaultSize, 0 ); |
|||
m_title->Wrap( -1 ); |
|||
m_title->SetFont( wxFont( 12, wxFONTFAMILY_SWISS, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL, false, wxT("Helvetica") ) ); |
|||
|
|||
m_conditionSizer->Add( m_title, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); |
|||
|
|||
m_refs = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); |
|||
m_conditionSizer->Add( m_refs, 0, wxALIGN_CENTER_VERTICAL|wxALL|wxEXPAND, 5 ); |
|||
|
|||
|
|||
m_conditionSizer->Add( 10, 0, 1, wxEXPAND, 5 ); |
|||
|
|||
m_buttonImportRefs = new STD_BITMAP_BUTTON( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW|0 ); |
|||
m_conditionSizer->Add( m_buttonImportRefs, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); |
|||
|
|||
m_buttonDeleteMatch = new STD_BITMAP_BUTTON( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW|0 ); |
|||
m_conditionSizer->Add( m_buttonDeleteMatch, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); |
|||
|
|||
|
|||
this->SetSizer( m_conditionSizer ); |
|||
this->Layout(); |
|||
m_conditionSizer->Fit( this ); |
|||
|
|||
// Connect Events
|
|||
m_refs->Connect( wxEVT_RIGHT_DOWN, wxMouseEventHandler( PANEL_COMPONENT_CLASS_CONDITION_REFERENCE_BASE::OnReferenceRightDown ), NULL, this ); |
|||
m_buttonImportRefs->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_COMPONENT_CLASS_CONDITION_REFERENCE_BASE::OnImportRefsClick ), NULL, this ); |
|||
m_buttonDeleteMatch->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_COMPONENT_CLASS_CONDITION_REFERENCE_BASE::OnDeleteConditionClick ), NULL, this ); |
|||
} |
|||
|
|||
PANEL_COMPONENT_CLASS_CONDITION_REFERENCE_BASE::~PANEL_COMPONENT_CLASS_CONDITION_REFERENCE_BASE() |
|||
{ |
|||
// Disconnect Events
|
|||
m_refs->Disconnect( wxEVT_RIGHT_DOWN, wxMouseEventHandler( PANEL_COMPONENT_CLASS_CONDITION_REFERENCE_BASE::OnReferenceRightDown ), NULL, this ); |
|||
m_buttonImportRefs->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_COMPONENT_CLASS_CONDITION_REFERENCE_BASE::OnImportRefsClick ), NULL, this ); |
|||
m_buttonDeleteMatch->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_COMPONENT_CLASS_CONDITION_REFERENCE_BASE::OnDeleteConditionClick ), NULL, this ); |
|||
|
|||
} |
|||
|
|||
PANEL_COMPONENT_CLASS_CONDITION_SIDE_BASE::PANEL_COMPONENT_CLASS_CONDITION_SIDE_BASE( wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style, const wxString& name ) : wxPanel( parent, id, pos, size, style, name ) |
|||
{ |
|||
this->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_3DLIGHT ) ); |
|||
|
|||
wxFlexGridSizer* m_conditionSizer; |
|||
m_conditionSizer = new wxFlexGridSizer( 0, 4, 0, 0 ); |
|||
m_conditionSizer->AddGrowableCol( 1 ); |
|||
m_conditionSizer->SetFlexibleDirection( wxBOTH ); |
|||
m_conditionSizer->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED ); |
|||
|
|||
m_title = new wxStaticText( this, wxID_ANY, _("Side:"), wxDefaultPosition, wxDefaultSize, 0 ); |
|||
m_title->Wrap( -1 ); |
|||
m_title->SetFont( wxFont( 12, wxFONTFAMILY_SWISS, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL, false, wxT("Helvetica") ) ); |
|||
|
|||
m_conditionSizer->Add( m_title, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); |
|||
|
|||
m_side = new wxComboBox( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, NULL, wxCB_READONLY ); |
|||
m_conditionSizer->Add( m_side, 0, wxALIGN_CENTER_VERTICAL|wxALL|wxEXPAND, 5 ); |
|||
|
|||
|
|||
m_conditionSizer->Add( 10, 0, 1, wxEXPAND, 5 ); |
|||
|
|||
m_buttonDeleteMatch = new STD_BITMAP_BUTTON( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW|0 ); |
|||
m_conditionSizer->Add( m_buttonDeleteMatch, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); |
|||
|
|||
|
|||
this->SetSizer( m_conditionSizer ); |
|||
this->Layout(); |
|||
m_conditionSizer->Fit( this ); |
|||
|
|||
// Connect Events
|
|||
m_buttonDeleteMatch->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_COMPONENT_CLASS_CONDITION_SIDE_BASE::OnDeleteConditionClick ), NULL, this ); |
|||
} |
|||
|
|||
PANEL_COMPONENT_CLASS_CONDITION_SIDE_BASE::~PANEL_COMPONENT_CLASS_CONDITION_SIDE_BASE() |
|||
{ |
|||
// Disconnect Events
|
|||
m_buttonDeleteMatch->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_COMPONENT_CLASS_CONDITION_SIDE_BASE::OnDeleteConditionClick ), NULL, this ); |
|||
|
|||
} |
|||
|
|||
PANEL_COMPONENT_CLASS_CONDITION_ROTATION_BASE::PANEL_COMPONENT_CLASS_CONDITION_ROTATION_BASE( wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style, const wxString& name ) : wxPanel( parent, id, pos, size, style, name ) |
|||
{ |
|||
this->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_3DLIGHT ) ); |
|||
|
|||
wxFlexGridSizer* m_conditionSizer; |
|||
m_conditionSizer = new wxFlexGridSizer( 0, 5, 0, 0 ); |
|||
m_conditionSizer->AddGrowableCol( 1 ); |
|||
m_conditionSizer->SetFlexibleDirection( wxBOTH ); |
|||
m_conditionSizer->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED ); |
|||
|
|||
m_title = new wxStaticText( this, wxID_ANY, _("Rotation:"), wxDefaultPosition, wxDefaultSize, 0 ); |
|||
m_title->Wrap( -1 ); |
|||
m_title->SetFont( wxFont( 12, wxFONTFAMILY_SWISS, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL, false, wxT("Helvetica") ) ); |
|||
|
|||
m_conditionSizer->Add( m_title, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); |
|||
|
|||
m_rotation = new wxComboBox( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, NULL, 0 ); |
|||
m_conditionSizer->Add( m_rotation, 0, wxALIGN_CENTER_VERTICAL|wxALL|wxEXPAND, 5 ); |
|||
|
|||
m_rotUnit = new wxStaticText( this, wxID_ANY, _("deg"), wxDefaultPosition, wxDefaultSize, 0 ); |
|||
m_rotUnit->Wrap( -1 ); |
|||
m_conditionSizer->Add( m_rotUnit, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); |
|||
|
|||
|
|||
m_conditionSizer->Add( 10, 0, 1, wxEXPAND, 5 ); |
|||
|
|||
m_buttonDeleteMatch = new STD_BITMAP_BUTTON( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW|0 ); |
|||
m_conditionSizer->Add( m_buttonDeleteMatch, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); |
|||
|
|||
|
|||
this->SetSizer( m_conditionSizer ); |
|||
this->Layout(); |
|||
|
|||
// Connect Events
|
|||
m_buttonDeleteMatch->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_COMPONENT_CLASS_CONDITION_ROTATION_BASE::OnDeleteConditionClick ), NULL, this ); |
|||
} |
|||
|
|||
PANEL_COMPONENT_CLASS_CONDITION_ROTATION_BASE::~PANEL_COMPONENT_CLASS_CONDITION_ROTATION_BASE() |
|||
{ |
|||
// Disconnect Events
|
|||
m_buttonDeleteMatch->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_COMPONENT_CLASS_CONDITION_ROTATION_BASE::OnDeleteConditionClick ), NULL, this ); |
|||
|
|||
} |
|||
|
|||
PANEL_COMPONENT_CLASS_CONDITION_FOOTPRINT_BASE::PANEL_COMPONENT_CLASS_CONDITION_FOOTPRINT_BASE( wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style, const wxString& name ) : wxPanel( parent, id, pos, size, style, name ) |
|||
{ |
|||
this->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_3DLIGHT ) ); |
|||
|
|||
wxFlexGridSizer* m_conditionSizer; |
|||
m_conditionSizer = new wxFlexGridSizer( 0, 6, 0, 0 ); |
|||
m_conditionSizer->AddGrowableCol( 1 ); |
|||
m_conditionSizer->SetFlexibleDirection( wxBOTH ); |
|||
m_conditionSizer->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED ); |
|||
|
|||
m_title = new wxStaticText( this, wxID_ANY, _("Footprint:"), wxDefaultPosition, wxDefaultSize, 0 ); |
|||
m_title->Wrap( -1 ); |
|||
m_title->SetFont( wxFont( 12, wxFONTFAMILY_SWISS, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL, false, wxT("Helvetica") ) ); |
|||
|
|||
m_conditionSizer->Add( m_title, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); |
|||
|
|||
m_footprint = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); |
|||
m_conditionSizer->Add( m_footprint, 0, wxALIGN_CENTER_VERTICAL|wxALL|wxEXPAND, 5 ); |
|||
|
|||
|
|||
m_conditionSizer->Add( 10, 0, 1, wxEXPAND, 5 ); |
|||
|
|||
m_buttonShowLibrary = new STD_BITMAP_BUTTON( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW|0 ); |
|||
m_conditionSizer->Add( m_buttonShowLibrary, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); |
|||
|
|||
|
|||
m_conditionSizer->Add( 10, 0, 1, wxEXPAND, 5 ); |
|||
|
|||
m_buttonDeleteMatch = new STD_BITMAP_BUTTON( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW|0 ); |
|||
m_conditionSizer->Add( m_buttonDeleteMatch, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); |
|||
|
|||
|
|||
this->SetSizer( m_conditionSizer ); |
|||
this->Layout(); |
|||
m_conditionSizer->Fit( this ); |
|||
|
|||
// Connect Events
|
|||
m_buttonShowLibrary->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_COMPONENT_CLASS_CONDITION_FOOTPRINT_BASE::OnShowLibraryClick ), NULL, this ); |
|||
m_buttonDeleteMatch->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_COMPONENT_CLASS_CONDITION_FOOTPRINT_BASE::OnDeleteConditionClick ), NULL, this ); |
|||
} |
|||
|
|||
PANEL_COMPONENT_CLASS_CONDITION_FOOTPRINT_BASE::~PANEL_COMPONENT_CLASS_CONDITION_FOOTPRINT_BASE() |
|||
{ |
|||
// Disconnect Events
|
|||
m_buttonShowLibrary->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_COMPONENT_CLASS_CONDITION_FOOTPRINT_BASE::OnShowLibraryClick ), NULL, this ); |
|||
m_buttonDeleteMatch->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_COMPONENT_CLASS_CONDITION_FOOTPRINT_BASE::OnDeleteConditionClick ), NULL, this ); |
|||
|
|||
} |
|||
|
|||
PANEL_COMPONENT_CLASS_CONDITION_FIELD_BASE::PANEL_COMPONENT_CLASS_CONDITION_FIELD_BASE( wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style, const wxString& name ) : wxPanel( parent, id, pos, size, style, name ) |
|||
{ |
|||
this->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_3DLIGHT ) ); |
|||
|
|||
wxFlexGridSizer* m_conditionSizer; |
|||
m_conditionSizer = new wxFlexGridSizer( 0, 7, 0, 0 ); |
|||
m_conditionSizer->AddGrowableCol( 1 ); |
|||
m_conditionSizer->AddGrowableCol( 4 ); |
|||
m_conditionSizer->SetFlexibleDirection( wxBOTH ); |
|||
m_conditionSizer->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED ); |
|||
|
|||
m_title = new wxStaticText( this, wxID_ANY, _("Footprint Field:"), wxDefaultPosition, wxDefaultSize, 0 ); |
|||
m_title->Wrap( -1 ); |
|||
m_title->SetFont( wxFont( 12, wxFONTFAMILY_SWISS, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL, false, wxT("Helvetica") ) ); |
|||
|
|||
m_conditionSizer->Add( m_title, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); |
|||
|
|||
m_fieldName = new wxComboBox( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, NULL, 0 ); |
|||
m_fieldName->SetFont( wxFont( 12, wxFONTFAMILY_SWISS, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL, false, wxT("Helvetica") ) ); |
|||
|
|||
m_conditionSizer->Add( m_fieldName, 0, wxALIGN_CENTER_VERTICAL|wxALL|wxEXPAND, 5 ); |
|||
|
|||
|
|||
m_conditionSizer->Add( 10, 0, 1, wxEXPAND, 5 ); |
|||
|
|||
m_staticText44 = new wxStaticText( this, wxID_ANY, _("Field Value:"), wxDefaultPosition, wxDefaultSize, 0 ); |
|||
m_staticText44->Wrap( -1 ); |
|||
m_staticText44->SetFont( wxFont( 12, wxFONTFAMILY_SWISS, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL, false, wxT("Helvetica") ) ); |
|||
|
|||
m_conditionSizer->Add( m_staticText44, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); |
|||
|
|||
m_fieldValue = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); |
|||
m_fieldValue->SetFont( wxFont( 12, wxFONTFAMILY_SWISS, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL, false, wxT("Helvetica") ) ); |
|||
|
|||
m_conditionSizer->Add( m_fieldValue, 0, wxALIGN_CENTER_VERTICAL|wxALL|wxEXPAND, 5 ); |
|||
|
|||
|
|||
m_conditionSizer->Add( 10, 0, 1, wxEXPAND, 5 ); |
|||
|
|||
m_buttonDeleteMatch = new STD_BITMAP_BUTTON( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW|0 ); |
|||
m_conditionSizer->Add( m_buttonDeleteMatch, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); |
|||
|
|||
|
|||
this->SetSizer( m_conditionSizer ); |
|||
this->Layout(); |
|||
m_conditionSizer->Fit( this ); |
|||
|
|||
// Connect Events
|
|||
m_buttonDeleteMatch->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_COMPONENT_CLASS_CONDITION_FIELD_BASE::OnDeleteConditionClick ), NULL, this ); |
|||
} |
|||
|
|||
PANEL_COMPONENT_CLASS_CONDITION_FIELD_BASE::~PANEL_COMPONENT_CLASS_CONDITION_FIELD_BASE() |
|||
{ |
|||
// Disconnect Events
|
|||
m_buttonDeleteMatch->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_COMPONENT_CLASS_CONDITION_FIELD_BASE::OnDeleteConditionClick ), NULL, this ); |
|||
|
|||
} |
|||
|
|||
PANEL_COMPONENT_CLASS_CONDITION_CUSTOM_BASE::PANEL_COMPONENT_CLASS_CONDITION_CUSTOM_BASE( wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style, const wxString& name ) : wxPanel( parent, id, pos, size, style, name ) |
|||
{ |
|||
this->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_3DLIGHT ) ); |
|||
|
|||
wxFlexGridSizer* m_conditionSizer; |
|||
m_conditionSizer = new wxFlexGridSizer( 0, 4, 0, 0 ); |
|||
m_conditionSizer->AddGrowableCol( 1 ); |
|||
m_conditionSizer->SetFlexibleDirection( wxBOTH ); |
|||
m_conditionSizer->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED ); |
|||
|
|||
m_title = new wxStaticText( this, wxID_ANY, _("Custom:"), wxDefaultPosition, wxDefaultSize, 0 ); |
|||
m_title->Wrap( -1 ); |
|||
m_title->SetFont( wxFont( 12, wxFONTFAMILY_SWISS, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL, false, wxT("Helvetica") ) ); |
|||
|
|||
m_conditionSizer->Add( m_title, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); |
|||
|
|||
m_customCondition = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); |
|||
m_conditionSizer->Add( m_customCondition, 0, wxALIGN_CENTER_VERTICAL|wxALL|wxEXPAND, 5 ); |
|||
|
|||
|
|||
m_conditionSizer->Add( 10, 0, 1, wxEXPAND, 5 ); |
|||
|
|||
m_buttonDeleteMatch = new STD_BITMAP_BUTTON( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW|0 ); |
|||
m_conditionSizer->Add( m_buttonDeleteMatch, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); |
|||
|
|||
|
|||
this->SetSizer( m_conditionSizer ); |
|||
this->Layout(); |
|||
m_conditionSizer->Fit( this ); |
|||
|
|||
// Connect Events
|
|||
m_buttonDeleteMatch->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_COMPONENT_CLASS_CONDITION_CUSTOM_BASE::OnDeleteConditionClick ), NULL, this ); |
|||
} |
|||
|
|||
PANEL_COMPONENT_CLASS_CONDITION_CUSTOM_BASE::~PANEL_COMPONENT_CLASS_CONDITION_CUSTOM_BASE() |
|||
{ |
|||
// Disconnect Events
|
|||
m_buttonDeleteMatch->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_COMPONENT_CLASS_CONDITION_CUSTOM_BASE::OnDeleteConditionClick ), NULL, this ); |
|||
|
|||
} |
|||
|
|||
PANEL_COMPONENT_CLASS_CONDITION_SHEET_BASE::PANEL_COMPONENT_CLASS_CONDITION_SHEET_BASE( wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style, const wxString& name ) : wxPanel( parent, id, pos, size, style, name ) |
|||
{ |
|||
this->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_3DLIGHT ) ); |
|||
|
|||
wxFlexGridSizer* m_conditionSizer; |
|||
m_conditionSizer = new wxFlexGridSizer( 0, 4, 0, 0 ); |
|||
m_conditionSizer->AddGrowableCol( 1 ); |
|||
m_conditionSizer->SetFlexibleDirection( wxBOTH ); |
|||
m_conditionSizer->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED ); |
|||
|
|||
m_title = new wxStaticText( this, wxID_ANY, _("Sheet Name:"), wxDefaultPosition, wxDefaultSize, 0 ); |
|||
m_title->Wrap( -1 ); |
|||
m_title->SetFont( wxFont( 12, wxFONTFAMILY_SWISS, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL, false, wxT("Helvetica") ) ); |
|||
|
|||
m_conditionSizer->Add( m_title, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); |
|||
|
|||
m_sheetName = new wxComboBox( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, NULL, wxCB_READONLY ); |
|||
m_conditionSizer->Add( m_sheetName, 0, wxALIGN_CENTER_VERTICAL|wxALL|wxEXPAND, 5 ); |
|||
|
|||
|
|||
m_conditionSizer->Add( 10, 0, 1, wxEXPAND, 5 ); |
|||
|
|||
m_buttonDeleteMatch = new STD_BITMAP_BUTTON( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW|0 ); |
|||
m_conditionSizer->Add( m_buttonDeleteMatch, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); |
|||
|
|||
|
|||
this->SetSizer( m_conditionSizer ); |
|||
this->Layout(); |
|||
m_conditionSizer->Fit( this ); |
|||
|
|||
// Connect Events
|
|||
m_buttonDeleteMatch->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_COMPONENT_CLASS_CONDITION_SHEET_BASE::OnDeleteConditionClick ), NULL, this ); |
|||
} |
|||
|
|||
PANEL_COMPONENT_CLASS_CONDITION_SHEET_BASE::~PANEL_COMPONENT_CLASS_CONDITION_SHEET_BASE() |
|||
{ |
|||
// Disconnect Events
|
|||
m_buttonDeleteMatch->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_COMPONENT_CLASS_CONDITION_SHEET_BASE::OnDeleteConditionClick ), NULL, this ); |
|||
|
|||
} |
|||
3121
pcbnew/dialogs/panel_assign_component_classes_base.fbp
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
@ -0,0 +1,269 @@ |
|||
/////////////////////////////////////////////////////////////////////////// |
|||
// C++ code generated with wxFormBuilder (version 4.2.1-0-g80c4cb6) |
|||
// http://www.wxformbuilder.org/ |
|||
// |
|||
// PLEASE DO *NOT* EDIT THIS FILE! |
|||
/////////////////////////////////////////////////////////////////////////// |
|||
|
|||
#pragma once |
|||
|
|||
#include <wx/artprov.h> |
|||
#include <wx/xrc/xmlres.h> |
|||
#include <wx/intl.h> |
|||
class STD_BITMAP_BUTTON; |
|||
|
|||
#include <wx/string.h> |
|||
#include <wx/checkbox.h> |
|||
#include <wx/gdicmn.h> |
|||
#include <wx/font.h> |
|||
#include <wx/colour.h> |
|||
#include <wx/settings.h> |
|||
#include <wx/statline.h> |
|||
#include <wx/stattext.h> |
|||
#include <wx/button.h> |
|||
#include <wx/bitmap.h> |
|||
#include <wx/image.h> |
|||
#include <wx/icon.h> |
|||
#include <wx/sizer.h> |
|||
#include <wx/scrolwin.h> |
|||
#include <wx/panel.h> |
|||
#include <wx/textctrl.h> |
|||
#include <wx/bmpbuttn.h> |
|||
#include <wx/radiobut.h> |
|||
#include <wx/statbox.h> |
|||
#include <wx/combobox.h> |
|||
|
|||
/////////////////////////////////////////////////////////////////////////// |
|||
|
|||
/////////////////////////////////////////////////////////////////////////////// |
|||
/// Class PANEL_ASSIGN_COMPONENT_CLASSES_BASE |
|||
/////////////////////////////////////////////////////////////////////////////// |
|||
class PANEL_ASSIGN_COMPONENT_CLASSES_BASE : public wxPanel |
|||
{ |
|||
private: |
|||
|
|||
protected: |
|||
wxCheckBox* m_assignSheetClasses; |
|||
wxStaticLine* m_staticline1; |
|||
wxStaticText* m_staticText3; |
|||
wxButton* m_btnAddAssignment; |
|||
wxScrolledWindow* m_assignmentsScrollWindow; |
|||
|
|||
// Virtual event handlers, override them in your derived class |
|||
virtual void OnAddAssignmentClick( wxCommandEvent& event ) { event.Skip(); } |
|||
|
|||
|
|||
public: |
|||
|
|||
PANEL_ASSIGN_COMPONENT_CLASSES_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxTAB_TRAVERSAL, const wxString& name = wxEmptyString ); |
|||
|
|||
~PANEL_ASSIGN_COMPONENT_CLASSES_BASE(); |
|||
|
|||
}; |
|||
|
|||
/////////////////////////////////////////////////////////////////////////////// |
|||
/// Class PANEL_COMPONENT_CLASS_ASSIGNMENT_BASE |
|||
/////////////////////////////////////////////////////////////////////////////// |
|||
class PANEL_COMPONENT_CLASS_ASSIGNMENT_BASE : public wxPanel |
|||
{ |
|||
private: |
|||
|
|||
protected: |
|||
wxStaticText* m_staticText101; |
|||
wxTextCtrl* m_componentClass; |
|||
STD_BITMAP_BUTTON* m_buttonHighlightItems; |
|||
STD_BITMAP_BUTTON* m_buttonDeleteAssignment; |
|||
STD_BITMAP_BUTTON* m_buttonAddCondition; |
|||
wxRadioButton* m_radioAll; |
|||
wxRadioButton* m_radioAny; |
|||
|
|||
// Virtual event handlers, override them in your derived class |
|||
virtual void OnHighlightItemsClick( wxCommandEvent& event ) { event.Skip(); } |
|||
virtual void OnDeleteAssignmentClick( wxCommandEvent& event ) { event.Skip(); } |
|||
virtual void OnAddConditionClick( wxCommandEvent& event ) { event.Skip(); } |
|||
|
|||
|
|||
public: |
|||
|
|||
PANEL_COMPONENT_CLASS_ASSIGNMENT_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxBORDER_SUNKEN|wxTAB_TRAVERSAL, const wxString& name = wxEmptyString ); |
|||
|
|||
~PANEL_COMPONENT_CLASS_ASSIGNMENT_BASE(); |
|||
|
|||
}; |
|||
|
|||
/////////////////////////////////////////////////////////////////////////////// |
|||
/// Class PANEL_COMPONENT_CLASS_CONDITION_REFERENCE_BASE |
|||
/////////////////////////////////////////////////////////////////////////////// |
|||
class PANEL_COMPONENT_CLASS_CONDITION_REFERENCE_BASE : public wxPanel |
|||
{ |
|||
private: |
|||
|
|||
protected: |
|||
wxStaticText* m_title; |
|||
wxTextCtrl* m_refs; |
|||
STD_BITMAP_BUTTON* m_buttonImportRefs; |
|||
STD_BITMAP_BUTTON* m_buttonDeleteMatch; |
|||
|
|||
// Virtual event handlers, override them in your derived class |
|||
virtual void OnReferenceRightDown( wxMouseEvent& event ) { event.Skip(); } |
|||
virtual void OnImportRefsClick( wxCommandEvent& event ) { event.Skip(); } |
|||
virtual void OnDeleteConditionClick( wxCommandEvent& event ) { event.Skip(); } |
|||
|
|||
|
|||
public: |
|||
|
|||
PANEL_COMPONENT_CLASS_CONDITION_REFERENCE_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxBORDER_SUNKEN|wxTAB_TRAVERSAL, const wxString& name = wxEmptyString ); |
|||
|
|||
~PANEL_COMPONENT_CLASS_CONDITION_REFERENCE_BASE(); |
|||
|
|||
}; |
|||
|
|||
/////////////////////////////////////////////////////////////////////////////// |
|||
/// Class PANEL_COMPONENT_CLASS_CONDITION_SIDE_BASE |
|||
/////////////////////////////////////////////////////////////////////////////// |
|||
class PANEL_COMPONENT_CLASS_CONDITION_SIDE_BASE : public wxPanel |
|||
{ |
|||
private: |
|||
|
|||
protected: |
|||
wxStaticText* m_title; |
|||
wxComboBox* m_side; |
|||
STD_BITMAP_BUTTON* m_buttonDeleteMatch; |
|||
|
|||
// Virtual event handlers, override them in your derived class |
|||
virtual void OnDeleteConditionClick( wxCommandEvent& event ) { event.Skip(); } |
|||
|
|||
|
|||
public: |
|||
|
|||
PANEL_COMPONENT_CLASS_CONDITION_SIDE_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxBORDER_SUNKEN|wxTAB_TRAVERSAL, const wxString& name = wxEmptyString ); |
|||
|
|||
~PANEL_COMPONENT_CLASS_CONDITION_SIDE_BASE(); |
|||
|
|||
}; |
|||
|
|||
/////////////////////////////////////////////////////////////////////////////// |
|||
/// Class PANEL_COMPONENT_CLASS_CONDITION_ROTATION_BASE |
|||
/////////////////////////////////////////////////////////////////////////////// |
|||
class PANEL_COMPONENT_CLASS_CONDITION_ROTATION_BASE : public wxPanel |
|||
{ |
|||
private: |
|||
|
|||
protected: |
|||
wxStaticText* m_title; |
|||
wxComboBox* m_rotation; |
|||
wxStaticText* m_rotUnit; |
|||
STD_BITMAP_BUTTON* m_buttonDeleteMatch; |
|||
|
|||
// Virtual event handlers, override them in your derived class |
|||
virtual void OnDeleteConditionClick( wxCommandEvent& event ) { event.Skip(); } |
|||
|
|||
|
|||
public: |
|||
|
|||
PANEL_COMPONENT_CLASS_CONDITION_ROTATION_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 303,65 ), long style = wxBORDER_SUNKEN|wxTAB_TRAVERSAL, const wxString& name = wxEmptyString ); |
|||
|
|||
~PANEL_COMPONENT_CLASS_CONDITION_ROTATION_BASE(); |
|||
|
|||
}; |
|||
|
|||
/////////////////////////////////////////////////////////////////////////////// |
|||
/// Class PANEL_COMPONENT_CLASS_CONDITION_FOOTPRINT_BASE |
|||
/////////////////////////////////////////////////////////////////////////////// |
|||
class PANEL_COMPONENT_CLASS_CONDITION_FOOTPRINT_BASE : public wxPanel |
|||
{ |
|||
private: |
|||
|
|||
protected: |
|||
wxStaticText* m_title; |
|||
wxTextCtrl* m_footprint; |
|||
STD_BITMAP_BUTTON* m_buttonShowLibrary; |
|||
STD_BITMAP_BUTTON* m_buttonDeleteMatch; |
|||
|
|||
// Virtual event handlers, override them in your derived class |
|||
virtual void OnShowLibraryClick( wxCommandEvent& event ) { event.Skip(); } |
|||
virtual void OnDeleteConditionClick( wxCommandEvent& event ) { event.Skip(); } |
|||
|
|||
|
|||
public: |
|||
|
|||
PANEL_COMPONENT_CLASS_CONDITION_FOOTPRINT_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxBORDER_SUNKEN|wxTAB_TRAVERSAL, const wxString& name = wxEmptyString ); |
|||
|
|||
~PANEL_COMPONENT_CLASS_CONDITION_FOOTPRINT_BASE(); |
|||
|
|||
}; |
|||
|
|||
/////////////////////////////////////////////////////////////////////////////// |
|||
/// Class PANEL_COMPONENT_CLASS_CONDITION_FIELD_BASE |
|||
/////////////////////////////////////////////////////////////////////////////// |
|||
class PANEL_COMPONENT_CLASS_CONDITION_FIELD_BASE : public wxPanel |
|||
{ |
|||
private: |
|||
|
|||
protected: |
|||
wxStaticText* m_title; |
|||
wxComboBox* m_fieldName; |
|||
wxStaticText* m_staticText44; |
|||
wxTextCtrl* m_fieldValue; |
|||
STD_BITMAP_BUTTON* m_buttonDeleteMatch; |
|||
|
|||
// Virtual event handlers, override them in your derived class |
|||
virtual void OnDeleteConditionClick( wxCommandEvent& event ) { event.Skip(); } |
|||
|
|||
|
|||
public: |
|||
|
|||
PANEL_COMPONENT_CLASS_CONDITION_FIELD_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxBORDER_SUNKEN|wxTAB_TRAVERSAL, const wxString& name = wxEmptyString ); |
|||
|
|||
~PANEL_COMPONENT_CLASS_CONDITION_FIELD_BASE(); |
|||
|
|||
}; |
|||
|
|||
/////////////////////////////////////////////////////////////////////////////// |
|||
/// Class PANEL_COMPONENT_CLASS_CONDITION_CUSTOM_BASE |
|||
/////////////////////////////////////////////////////////////////////////////// |
|||
class PANEL_COMPONENT_CLASS_CONDITION_CUSTOM_BASE : public wxPanel |
|||
{ |
|||
private: |
|||
|
|||
protected: |
|||
wxStaticText* m_title; |
|||
wxTextCtrl* m_customCondition; |
|||
STD_BITMAP_BUTTON* m_buttonDeleteMatch; |
|||
|
|||
// Virtual event handlers, override them in your derived class |
|||
virtual void OnDeleteConditionClick( wxCommandEvent& event ) { event.Skip(); } |
|||
|
|||
|
|||
public: |
|||
|
|||
PANEL_COMPONENT_CLASS_CONDITION_CUSTOM_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxBORDER_SUNKEN|wxTAB_TRAVERSAL, const wxString& name = wxEmptyString ); |
|||
|
|||
~PANEL_COMPONENT_CLASS_CONDITION_CUSTOM_BASE(); |
|||
|
|||
}; |
|||
|
|||
/////////////////////////////////////////////////////////////////////////////// |
|||
/// Class PANEL_COMPONENT_CLASS_CONDITION_SHEET_BASE |
|||
/////////////////////////////////////////////////////////////////////////////// |
|||
class PANEL_COMPONENT_CLASS_CONDITION_SHEET_BASE : public wxPanel |
|||
{ |
|||
private: |
|||
|
|||
protected: |
|||
wxStaticText* m_title; |
|||
wxComboBox* m_sheetName; |
|||
STD_BITMAP_BUTTON* m_buttonDeleteMatch; |
|||
|
|||
// Virtual event handlers, override them in your derived class |
|||
virtual void OnDeleteConditionClick( wxCommandEvent& event ) { event.Skip(); } |
|||
|
|||
|
|||
public: |
|||
|
|||
PANEL_COMPONENT_CLASS_CONDITION_SHEET_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxBORDER_SUNKEN|wxTAB_TRAVERSAL, const wxString& name = wxEmptyString ); |
|||
|
|||
~PANEL_COMPONENT_CLASS_CONDITION_SHEET_BASE(); |
|||
|
|||
}; |
|||
|
|||
3875
qa/data/pcbnew/component_classes.kicad_pcb
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
@ -0,0 +1,761 @@ |
|||
{ |
|||
"board": { |
|||
"3dviewports": [], |
|||
"design_settings": { |
|||
"defaults": { |
|||
"apply_defaults_to_fp_fields": false, |
|||
"apply_defaults_to_fp_shapes": false, |
|||
"apply_defaults_to_fp_text": false, |
|||
"board_outline_line_width": 0.05, |
|||
"copper_line_width": 0.2, |
|||
"copper_text_italic": false, |
|||
"copper_text_size_h": 1.5, |
|||
"copper_text_size_v": 1.5, |
|||
"copper_text_thickness": 0.3, |
|||
"copper_text_upright": false, |
|||
"courtyard_line_width": 0.05, |
|||
"dimension_precision": 4, |
|||
"dimension_units": 3, |
|||
"dimensions": { |
|||
"arrow_length": 1270000, |
|||
"extension_offset": 500000, |
|||
"keep_text_aligned": true, |
|||
"suppress_zeroes": true, |
|||
"text_position": 0, |
|||
"units_format": 0 |
|||
}, |
|||
"fab_line_width": 0.1, |
|||
"fab_text_italic": false, |
|||
"fab_text_size_h": 1.0, |
|||
"fab_text_size_v": 1.0, |
|||
"fab_text_thickness": 0.15, |
|||
"fab_text_upright": false, |
|||
"other_line_width": 0.1, |
|||
"other_text_italic": false, |
|||
"other_text_size_h": 1.0, |
|||
"other_text_size_v": 1.0, |
|||
"other_text_thickness": 0.15, |
|||
"other_text_upright": false, |
|||
"pads": { |
|||
"drill": 0.8, |
|||
"height": 1.27, |
|||
"width": 2.54 |
|||
}, |
|||
"silk_line_width": 0.1, |
|||
"silk_text_italic": false, |
|||
"silk_text_size_h": 1.0, |
|||
"silk_text_size_v": 1.0, |
|||
"silk_text_thickness": 0.1, |
|||
"silk_text_upright": false, |
|||
"zones": { |
|||
"min_clearance": 0.5 |
|||
} |
|||
}, |
|||
"diff_pair_dimensions": [], |
|||
"drc_exclusions": [], |
|||
"meta": { |
|||
"version": 2 |
|||
}, |
|||
"rule_severities": { |
|||
"annular_width": "error", |
|||
"clearance": "error", |
|||
"connection_width": "warning", |
|||
"copper_edge_clearance": "error", |
|||
"copper_sliver": "warning", |
|||
"courtyards_overlap": "error", |
|||
"creepage": "error", |
|||
"diff_pair_gap_out_of_range": "error", |
|||
"diff_pair_uncoupled_length_too_long": "error", |
|||
"drill_out_of_range": "error", |
|||
"duplicate_footprints": "warning", |
|||
"extra_footprint": "warning", |
|||
"footprint": "error", |
|||
"footprint_filters_mismatch": "ignore", |
|||
"footprint_symbol_mismatch": "warning", |
|||
"footprint_type_mismatch": "ignore", |
|||
"hole_clearance": "error", |
|||
"hole_to_hole": "warning", |
|||
"holes_co_located": "warning", |
|||
"invalid_outline": "error", |
|||
"isolated_copper": "warning", |
|||
"item_on_disabled_layer": "error", |
|||
"items_not_allowed": "error", |
|||
"length_out_of_range": "error", |
|||
"lib_footprint_issues": "warning", |
|||
"lib_footprint_mismatch": "warning", |
|||
"malformed_courtyard": "error", |
|||
"microvia_drill_out_of_range": "error", |
|||
"mirrored_text_on_front_layer": "warning", |
|||
"missing_courtyard": "ignore", |
|||
"missing_footprint": "warning", |
|||
"net_conflict": "warning", |
|||
"nonmirrored_text_on_back_layer": "warning", |
|||
"npth_inside_courtyard": "ignore", |
|||
"padstack": "warning", |
|||
"pth_inside_courtyard": "ignore", |
|||
"shorting_items": "error", |
|||
"silk_edge_clearance": "warning", |
|||
"silk_over_copper": "warning", |
|||
"silk_overlap": "warning", |
|||
"skew_out_of_range": "error", |
|||
"solder_mask_bridge": "error", |
|||
"starved_thermal": "error", |
|||
"text_height": "warning", |
|||
"text_on_edge_cuts": "error", |
|||
"text_thickness": "warning", |
|||
"through_hole_pad_without_hole": "error", |
|||
"too_many_vias": "error", |
|||
"track_angle": "error", |
|||
"track_dangling": "warning", |
|||
"track_segment_length": "error", |
|||
"track_width": "error", |
|||
"tracks_crossing": "error", |
|||
"unconnected_items": "error", |
|||
"unresolved_variable": "error", |
|||
"via_dangling": "warning", |
|||
"zones_intersect": "error" |
|||
}, |
|||
"rules": { |
|||
"max_error": 0.005, |
|||
"min_clearance": 0.0, |
|||
"min_connection": 0.0, |
|||
"min_copper_edge_clearance": 0.5, |
|||
"min_groove_width": 0.0, |
|||
"min_hole_clearance": 0.25, |
|||
"min_hole_to_hole": 0.25, |
|||
"min_microvia_diameter": 0.2, |
|||
"min_microvia_drill": 0.1, |
|||
"min_resolved_spokes": 2, |
|||
"min_silk_clearance": 0.0, |
|||
"min_text_height": 0.8, |
|||
"min_text_thickness": 0.08, |
|||
"min_through_hole_diameter": 0.3, |
|||
"min_track_width": 0.0, |
|||
"min_via_annular_width": 0.1, |
|||
"min_via_diameter": 0.5, |
|||
"solder_mask_to_copper_clearance": 0.0, |
|||
"use_height_for_length_calcs": true |
|||
}, |
|||
"teardrop_options": [ |
|||
{ |
|||
"td_onpthpad": true, |
|||
"td_onroundshapesonly": false, |
|||
"td_onsmdpad": true, |
|||
"td_ontrackend": false, |
|||
"td_onvia": true |
|||
} |
|||
], |
|||
"teardrop_parameters": [ |
|||
{ |
|||
"td_allow_use_two_tracks": true, |
|||
"td_curve_segcount": 0, |
|||
"td_height_ratio": 1.0, |
|||
"td_length_ratio": 0.5, |
|||
"td_maxheight": 2.0, |
|||
"td_maxlen": 1.0, |
|||
"td_on_pad_in_zone": false, |
|||
"td_target_name": "td_round_shape", |
|||
"td_width_to_size_filter_ratio": 0.9 |
|||
}, |
|||
{ |
|||
"td_allow_use_two_tracks": true, |
|||
"td_curve_segcount": 0, |
|||
"td_height_ratio": 1.0, |
|||
"td_length_ratio": 0.5, |
|||
"td_maxheight": 2.0, |
|||
"td_maxlen": 1.0, |
|||
"td_on_pad_in_zone": false, |
|||
"td_target_name": "td_rect_shape", |
|||
"td_width_to_size_filter_ratio": 0.9 |
|||
}, |
|||
{ |
|||
"td_allow_use_two_tracks": true, |
|||
"td_curve_segcount": 0, |
|||
"td_height_ratio": 1.0, |
|||
"td_length_ratio": 0.5, |
|||
"td_maxheight": 2.0, |
|||
"td_maxlen": 1.0, |
|||
"td_on_pad_in_zone": false, |
|||
"td_target_name": "td_track_end", |
|||
"td_width_to_size_filter_ratio": 0.9 |
|||
} |
|||
], |
|||
"track_widths": [], |
|||
"tuning_pattern_settings": { |
|||
"diff_pair_defaults": { |
|||
"corner_radius_percentage": 80, |
|||
"corner_style": 1, |
|||
"max_amplitude": 1.0, |
|||
"min_amplitude": 0.2, |
|||
"single_sided": false, |
|||
"spacing": 1.0 |
|||
}, |
|||
"diff_pair_skew_defaults": { |
|||
"corner_radius_percentage": 80, |
|||
"corner_style": 1, |
|||
"max_amplitude": 1.0, |
|||
"min_amplitude": 0.2, |
|||
"single_sided": false, |
|||
"spacing": 0.6 |
|||
}, |
|||
"single_track_defaults": { |
|||
"corner_radius_percentage": 80, |
|||
"corner_style": 1, |
|||
"max_amplitude": 1.0, |
|||
"min_amplitude": 0.2, |
|||
"single_sided": false, |
|||
"spacing": 0.6 |
|||
} |
|||
}, |
|||
"via_dimensions": [], |
|||
"zones_allow_external_fillets": false |
|||
}, |
|||
"ipc2581": { |
|||
"dist": "", |
|||
"distpn": "", |
|||
"internal_id": "", |
|||
"mfg": "", |
|||
"mpn": "" |
|||
}, |
|||
"layer_pairs": [], |
|||
"layer_presets": [], |
|||
"viewports": [] |
|||
}, |
|||
"boards": [], |
|||
"component_class_settings": { |
|||
"assignments": [ |
|||
{ |
|||
"component_class": "CAP_1", |
|||
"conditions": { |
|||
"FOOTPRINT": { |
|||
"primary": "Capacitor_SMD:C_0805_2012Metric" |
|||
}, |
|||
"FOOTPRINT_FIELD": { |
|||
"primary": "MY_FIELD", |
|||
"secondary": "MY_VALUE" |
|||
}, |
|||
"REFERENCE": { |
|||
"primary": "C1" |
|||
}, |
|||
"ROTATION": { |
|||
"primary": "90" |
|||
}, |
|||
"SIDE": { |
|||
"primary": "Front" |
|||
} |
|||
}, |
|||
"conditions_operator": "ALL" |
|||
}, |
|||
{ |
|||
"component_class": "CAP_2", |
|||
"conditions": { |
|||
"CUSTOM": { |
|||
"primary": "A.intersectsArea('RULE_1')" |
|||
}, |
|||
"REFERENCE": { |
|||
"primary": "C?" |
|||
} |
|||
}, |
|||
"conditions_operator": "ALL" |
|||
}, |
|||
{ |
|||
"component_class": "RES_1", |
|||
"conditions": { |
|||
"REFERENCE": { |
|||
"primary": "R?" |
|||
} |
|||
}, |
|||
"conditions_operator": "ALL" |
|||
}, |
|||
{ |
|||
"component_class": "RES_2", |
|||
"conditions": { |
|||
"REFERENCE": { |
|||
"primary": "R*" |
|||
} |
|||
}, |
|||
"conditions_operator": "ALL" |
|||
}, |
|||
{ |
|||
"component_class": "RES_3", |
|||
"conditions": { |
|||
"FOOTPRINT_FIELD": { |
|||
"primary": "FIELD_2", |
|||
"secondary": "ANOTHER*" |
|||
} |
|||
}, |
|||
"conditions_operator": "ALL" |
|||
}, |
|||
{ |
|||
"component_class": "RES_4", |
|||
"conditions": { |
|||
"REFERENCE": { |
|||
"primary": "R1" |
|||
}, |
|||
"ROTATION": { |
|||
"primary": "180" |
|||
}, |
|||
"SIDE": { |
|||
"primary": "Back" |
|||
} |
|||
}, |
|||
"conditions_operator": "ALL" |
|||
}, |
|||
{ |
|||
"component_class": "ANY", |
|||
"conditions": { |
|||
"FOOTPRINT_FIELD": { |
|||
"primary": "FIELD2", |
|||
"secondary": "VALUE" |
|||
}, |
|||
"REFERENCE": { |
|||
"primary": "U1" |
|||
} |
|||
}, |
|||
"conditions_operator": "ANY" |
|||
}, |
|||
{ |
|||
"component_class": "MULTI_REF", |
|||
"conditions": { |
|||
"REFERENCE": { |
|||
"primary": "U3,U4" |
|||
} |
|||
}, |
|||
"conditions_operator": "ALL" |
|||
}, |
|||
{ |
|||
"component_class": "REF_WILDCARD", |
|||
"conditions": { |
|||
"REFERENCE": { |
|||
"primary": "U5?" |
|||
} |
|||
}, |
|||
"conditions_operator": "ALL" |
|||
}, |
|||
{ |
|||
"component_class": "REF_WILDCARD2", |
|||
"conditions": { |
|||
"REFERENCE": { |
|||
"primary": "U5*" |
|||
} |
|||
}, |
|||
"conditions_operator": "ALL" |
|||
} |
|||
], |
|||
"meta": { |
|||
"version": 0 |
|||
}, |
|||
"sheet_component_classes": { |
|||
"enabled": true |
|||
} |
|||
}, |
|||
"cvpcb": { |
|||
"equivalence_files": [] |
|||
}, |
|||
"erc": { |
|||
"erc_exclusions": [], |
|||
"meta": { |
|||
"version": 0 |
|||
}, |
|||
"pin_map": [ |
|||
[ |
|||
0, |
|||
0, |
|||
0, |
|||
0, |
|||
0, |
|||
0, |
|||
1, |
|||
0, |
|||
0, |
|||
0, |
|||
0, |
|||
2 |
|||
], |
|||
[ |
|||
0, |
|||
2, |
|||
0, |
|||
1, |
|||
0, |
|||
0, |
|||
1, |
|||
0, |
|||
2, |
|||
2, |
|||
2, |
|||
2 |
|||
], |
|||
[ |
|||
0, |
|||
0, |
|||
0, |
|||
0, |
|||
0, |
|||
0, |
|||
1, |
|||
0, |
|||
1, |
|||
0, |
|||
1, |
|||
2 |
|||
], |
|||
[ |
|||
0, |
|||
1, |
|||
0, |
|||
0, |
|||
0, |
|||
0, |
|||
1, |
|||
1, |
|||
2, |
|||
1, |
|||
1, |
|||
2 |
|||
], |
|||
[ |
|||
0, |
|||
0, |
|||
0, |
|||
0, |
|||
0, |
|||
0, |
|||
1, |
|||
0, |
|||
0, |
|||
0, |
|||
0, |
|||
2 |
|||
], |
|||
[ |
|||
0, |
|||
0, |
|||
0, |
|||
0, |
|||
0, |
|||
0, |
|||
0, |
|||
0, |
|||
0, |
|||
0, |
|||
0, |
|||
2 |
|||
], |
|||
[ |
|||
1, |
|||
1, |
|||
1, |
|||
1, |
|||
1, |
|||
0, |
|||
1, |
|||
1, |
|||
1, |
|||
1, |
|||
1, |
|||
2 |
|||
], |
|||
[ |
|||
0, |
|||
0, |
|||
0, |
|||
1, |
|||
0, |
|||
0, |
|||
1, |
|||
0, |
|||
0, |
|||
0, |
|||
0, |
|||
2 |
|||
], |
|||
[ |
|||
0, |
|||
2, |
|||
1, |
|||
2, |
|||
0, |
|||
0, |
|||
1, |
|||
0, |
|||
2, |
|||
2, |
|||
2, |
|||
2 |
|||
], |
|||
[ |
|||
0, |
|||
2, |
|||
0, |
|||
1, |
|||
0, |
|||
0, |
|||
1, |
|||
0, |
|||
2, |
|||
0, |
|||
0, |
|||
2 |
|||
], |
|||
[ |
|||
0, |
|||
2, |
|||
1, |
|||
1, |
|||
0, |
|||
0, |
|||
1, |
|||
0, |
|||
2, |
|||
0, |
|||
0, |
|||
2 |
|||
], |
|||
[ |
|||
2, |
|||
2, |
|||
2, |
|||
2, |
|||
2, |
|||
2, |
|||
2, |
|||
2, |
|||
2, |
|||
2, |
|||
2, |
|||
2 |
|||
] |
|||
], |
|||
"rule_severities": { |
|||
"bus_definition_conflict": "error", |
|||
"bus_entry_needed": "error", |
|||
"bus_to_bus_conflict": "error", |
|||
"bus_to_net_conflict": "error", |
|||
"different_unit_footprint": "error", |
|||
"different_unit_net": "error", |
|||
"duplicate_reference": "error", |
|||
"duplicate_sheet_names": "error", |
|||
"endpoint_off_grid": "warning", |
|||
"extra_units": "error", |
|||
"footprint_filter": "ignore", |
|||
"footprint_link_issues": "warning", |
|||
"four_way_junction": "ignore", |
|||
"global_label_dangling": "warning", |
|||
"hier_label_mismatch": "error", |
|||
"label_dangling": "error", |
|||
"label_multiple_wires": "warning", |
|||
"lib_symbol_issues": "warning", |
|||
"lib_symbol_mismatch": "warning", |
|||
"missing_bidi_pin": "warning", |
|||
"missing_input_pin": "warning", |
|||
"missing_power_pin": "error", |
|||
"missing_unit": "warning", |
|||
"multiple_net_names": "warning", |
|||
"net_not_bus_member": "warning", |
|||
"no_connect_connected": "warning", |
|||
"no_connect_dangling": "warning", |
|||
"pin_not_connected": "error", |
|||
"pin_not_driven": "error", |
|||
"pin_to_pin": "warning", |
|||
"power_pin_not_driven": "error", |
|||
"same_local_global_label": "warning", |
|||
"similar_label_and_power": "warning", |
|||
"similar_labels": "warning", |
|||
"similar_power": "warning", |
|||
"simulation_model_issue": "ignore", |
|||
"single_global_label": "ignore", |
|||
"unannotated": "error", |
|||
"unconnected_wire_endpoint": "warning", |
|||
"unit_value_mismatch": "error", |
|||
"unresolved_variable": "error", |
|||
"wire_dangling": "error" |
|||
} |
|||
}, |
|||
"libraries": { |
|||
"pinned_footprint_libs": [], |
|||
"pinned_symbol_libs": [] |
|||
}, |
|||
"meta": { |
|||
"filename": "component_classes.kicad_pro", |
|||
"version": 3 |
|||
}, |
|||
"net_settings": { |
|||
"classes": [ |
|||
{ |
|||
"bus_width": 12, |
|||
"clearance": 0.2, |
|||
"diff_pair_gap": 0.25, |
|||
"diff_pair_via_gap": 0.25, |
|||
"diff_pair_width": 0.2, |
|||
"line_style": 0, |
|||
"microvia_diameter": 0.3, |
|||
"microvia_drill": 0.1, |
|||
"name": "Default", |
|||
"pcb_color": "rgba(0, 0, 0, 0.000)", |
|||
"priority": 2147483647, |
|||
"schematic_color": "rgba(0, 0, 0, 0.000)", |
|||
"track_width": 0.2, |
|||
"via_diameter": 0.6, |
|||
"via_drill": 0.3, |
|||
"wire_width": 6 |
|||
} |
|||
], |
|||
"meta": { |
|||
"version": 4 |
|||
}, |
|||
"net_colors": null, |
|||
"netclass_assignments": null, |
|||
"netclass_patterns": [] |
|||
}, |
|||
"pcbnew": { |
|||
"last_paths": { |
|||
"gencad": "", |
|||
"idf": "", |
|||
"netlist": "", |
|||
"plot": "", |
|||
"pos_files": "", |
|||
"specctra_dsn": "", |
|||
"step": "", |
|||
"svg": "", |
|||
"vrml": "" |
|||
}, |
|||
"page_layout_descr_file": "" |
|||
}, |
|||
"schematic": { |
|||
"annotate_start_num": 0, |
|||
"bom_export_filename": "${PROJECTNAME}.csv", |
|||
"bom_fmt_presets": [], |
|||
"bom_fmt_settings": { |
|||
"field_delimiter": ",", |
|||
"keep_line_breaks": false, |
|||
"keep_tabs": false, |
|||
"name": "CSV", |
|||
"ref_delimiter": ",", |
|||
"ref_range_delimiter": "", |
|||
"string_delimiter": "\"" |
|||
}, |
|||
"bom_presets": [], |
|||
"bom_settings": { |
|||
"exclude_dnp": false, |
|||
"fields_ordered": [ |
|||
{ |
|||
"group_by": false, |
|||
"label": "Reference", |
|||
"name": "Reference", |
|||
"show": true |
|||
}, |
|||
{ |
|||
"group_by": false, |
|||
"label": "Qty", |
|||
"name": "${QUANTITY}", |
|||
"show": true |
|||
}, |
|||
{ |
|||
"group_by": true, |
|||
"label": "Value", |
|||
"name": "Value", |
|||
"show": true |
|||
}, |
|||
{ |
|||
"group_by": true, |
|||
"label": "DNP", |
|||
"name": "${DNP}", |
|||
"show": true |
|||
}, |
|||
{ |
|||
"group_by": true, |
|||
"label": "Exclude from BOM", |
|||
"name": "${EXCLUDE_FROM_BOM}", |
|||
"show": true |
|||
}, |
|||
{ |
|||
"group_by": true, |
|||
"label": "Exclude from Board", |
|||
"name": "${EXCLUDE_FROM_BOARD}", |
|||
"show": true |
|||
}, |
|||
{ |
|||
"group_by": true, |
|||
"label": "Footprint", |
|||
"name": "Footprint", |
|||
"show": true |
|||
}, |
|||
{ |
|||
"group_by": false, |
|||
"label": "Datasheet", |
|||
"name": "Datasheet", |
|||
"show": true |
|||
}, |
|||
{ |
|||
"group_by": false, |
|||
"label": "Description", |
|||
"name": "Description", |
|||
"show": false |
|||
}, |
|||
{ |
|||
"group_by": false, |
|||
"label": "#", |
|||
"name": "${ITEM_NUMBER}", |
|||
"show": false |
|||
} |
|||
], |
|||
"filter_string": "", |
|||
"group_symbols": true, |
|||
"include_excluded_from_bom": true, |
|||
"name": "", |
|||
"sort_asc": true, |
|||
"sort_field": "Reference" |
|||
}, |
|||
"connection_grid_size": 50.0, |
|||
"drawing": { |
|||
"dashed_lines_dash_length_ratio": 12.0, |
|||
"dashed_lines_gap_length_ratio": 3.0, |
|||
"default_line_thickness": 6.0, |
|||
"default_text_size": 50.0, |
|||
"field_names": [], |
|||
"intersheets_ref_own_page": false, |
|||
"intersheets_ref_prefix": "", |
|||
"intersheets_ref_short": false, |
|||
"intersheets_ref_show": false, |
|||
"intersheets_ref_suffix": "", |
|||
"junction_size_choice": 3, |
|||
"label_size_ratio": 0.375, |
|||
"operating_point_overlay_i_precision": 3, |
|||
"operating_point_overlay_i_range": "~A", |
|||
"operating_point_overlay_v_precision": 3, |
|||
"operating_point_overlay_v_range": "~V", |
|||
"overbar_offset_ratio": 1.23, |
|||
"pin_symbol_size": 25.0, |
|||
"text_offset_ratio": 0.15 |
|||
}, |
|||
"legacy_lib_dir": "", |
|||
"legacy_lib_list": [], |
|||
"meta": { |
|||
"version": 1 |
|||
}, |
|||
"net_format_name": "", |
|||
"page_layout_descr_file": "", |
|||
"plot_directory": "", |
|||
"space_save_all_events": true, |
|||
"spice_current_sheet_as_root": false, |
|||
"spice_external_command": "spice \"%I\"", |
|||
"spice_model_current_sheet_as_root": true, |
|||
"spice_save_all_currents": false, |
|||
"spice_save_all_dissipations": false, |
|||
"spice_save_all_voltages": false, |
|||
"subpart_first_id": 65, |
|||
"subpart_id_separator": 0 |
|||
}, |
|||
"sheets": [ |
|||
[ |
|||
"d9ed75ce-7084-4177-b32b-fceb2cf7aac3", |
|||
"Root" |
|||
], |
|||
[ |
|||
"e826c7ec-b0cb-4f53-915d-da3597387304", |
|||
"SHEET1" |
|||
] |
|||
], |
|||
"text_variables": {} |
|||
} |
|||
@ -0,0 +1,784 @@ |
|||
(kicad_sch |
|||
(version 20250227) |
|||
(generator "eeschema") |
|||
(generator_version "9.99") |
|||
(uuid "d9ed75ce-7084-4177-b32b-fceb2cf7aac3") |
|||
(paper "A4") |
|||
(lib_symbols |
|||
(symbol "Device:C" |
|||
(pin_numbers |
|||
(hide yes) |
|||
) |
|||
(pin_names |
|||
(offset 0.254) |
|||
) |
|||
(exclude_from_sim no) |
|||
(in_bom yes) |
|||
(on_board yes) |
|||
(property "Reference" "C" |
|||
(at 0.635 2.54 0) |
|||
(effects |
|||
(font |
|||
(size 1.27 1.27) |
|||
) |
|||
(justify left) |
|||
) |
|||
) |
|||
(property "Value" "C" |
|||
(at 0.635 -2.54 0) |
|||
(effects |
|||
(font |
|||
(size 1.27 1.27) |
|||
) |
|||
(justify left) |
|||
) |
|||
) |
|||
(property "Footprint" "" |
|||
(at 0.9652 -3.81 0) |
|||
(hide yes) |
|||
(effects |
|||
(font |
|||
(size 1.27 1.27) |
|||
) |
|||
) |
|||
) |
|||
(property "Datasheet" "~" |
|||
(at 0 0 0) |
|||
(hide yes) |
|||
(effects |
|||
(font |
|||
(size 1.27 1.27) |
|||
) |
|||
) |
|||
) |
|||
(property "Description" "Unpolarized capacitor" |
|||
(at 0 0 0) |
|||
(hide yes) |
|||
(effects |
|||
(font |
|||
(size 1.27 1.27) |
|||
) |
|||
) |
|||
) |
|||
(property "ki_keywords" "cap capacitor" |
|||
(at 0 0 0) |
|||
(hide yes) |
|||
(effects |
|||
(font |
|||
(size 1.27 1.27) |
|||
) |
|||
) |
|||
) |
|||
(property "ki_fp_filters" "C_*" |
|||
(at 0 0 0) |
|||
(hide yes) |
|||
(effects |
|||
(font |
|||
(size 1.27 1.27) |
|||
) |
|||
) |
|||
) |
|||
(symbol "C_0_1" |
|||
(polyline |
|||
(pts |
|||
(xy -2.032 0.762) (xy 2.032 0.762) |
|||
) |
|||
(stroke |
|||
(width 0.508) |
|||
(type default) |
|||
) |
|||
(fill |
|||
(type none) |
|||
) |
|||
) |
|||
(polyline |
|||
(pts |
|||
(xy -2.032 -0.762) (xy 2.032 -0.762) |
|||
) |
|||
(stroke |
|||
(width 0.508) |
|||
(type default) |
|||
) |
|||
(fill |
|||
(type none) |
|||
) |
|||
) |
|||
) |
|||
(symbol "C_1_1" |
|||
(pin passive line |
|||
(at 0 3.81 270) |
|||
(length 2.794) |
|||
(name "~" |
|||
(effects |
|||
(font |
|||
(size 1.27 1.27) |
|||
) |
|||
) |
|||
) |
|||
(number "1" |
|||
(effects |
|||
(font |
|||
(size 1.27 1.27) |
|||
) |
|||
) |
|||
) |
|||
) |
|||
(pin passive line |
|||
(at 0 -3.81 90) |
|||
(length 2.794) |
|||
(name "~" |
|||
(effects |
|||
(font |
|||
(size 1.27 1.27) |
|||
) |
|||
) |
|||
) |
|||
(number "2" |
|||
(effects |
|||
(font |
|||
(size 1.27 1.27) |
|||
) |
|||
) |
|||
) |
|||
) |
|||
) |
|||
(embedded_fonts no) |
|||
) |
|||
(symbol "Device:R" |
|||
(pin_numbers |
|||
(hide yes) |
|||
) |
|||
(pin_names |
|||
(offset 0) |
|||
) |
|||
(exclude_from_sim no) |
|||
(in_bom yes) |
|||
(on_board yes) |
|||
(property "Reference" "R" |
|||
(at 2.032 0 90) |
|||
(effects |
|||
(font |
|||
(size 1.27 1.27) |
|||
) |
|||
) |
|||
) |
|||
(property "Value" "R" |
|||
(at 0 0 90) |
|||
(effects |
|||
(font |
|||
(size 1.27 1.27) |
|||
) |
|||
) |
|||
) |
|||
(property "Footprint" "" |
|||
(at -1.778 0 90) |
|||
(hide yes) |
|||
(effects |
|||
(font |
|||
(size 1.27 1.27) |
|||
) |
|||
) |
|||
) |
|||
(property "Datasheet" "~" |
|||
(at 0 0 0) |
|||
(hide yes) |
|||
(effects |
|||
(font |
|||
(size 1.27 1.27) |
|||
) |
|||
) |
|||
) |
|||
(property "Description" "Resistor" |
|||
(at 0 0 0) |
|||
(hide yes) |
|||
(effects |
|||
(font |
|||
(size 1.27 1.27) |
|||
) |
|||
) |
|||
) |
|||
(property "ki_keywords" "R res resistor" |
|||
(at 0 0 0) |
|||
(hide yes) |
|||
(effects |
|||
(font |
|||
(size 1.27 1.27) |
|||
) |
|||
) |
|||
) |
|||
(property "ki_fp_filters" "R_*" |
|||
(at 0 0 0) |
|||
(hide yes) |
|||
(effects |
|||
(font |
|||
(size 1.27 1.27) |
|||
) |
|||
) |
|||
) |
|||
(symbol "R_0_1" |
|||
(rectangle |
|||
(start -1.016 -2.54) |
|||
(end 1.016 2.54) |
|||
(stroke |
|||
(width 0.254) |
|||
(type default) |
|||
) |
|||
(fill |
|||
(type none) |
|||
) |
|||
) |
|||
) |
|||
(symbol "R_1_1" |
|||
(pin passive line |
|||
(at 0 3.81 270) |
|||
(length 1.27) |
|||
(name "~" |
|||
(effects |
|||
(font |
|||
(size 1.27 1.27) |
|||
) |
|||
) |
|||
) |
|||
(number "1" |
|||
(effects |
|||
(font |
|||
(size 1.27 1.27) |
|||
) |
|||
) |
|||
) |
|||
) |
|||
(pin passive line |
|||
(at 0 -3.81 90) |
|||
(length 1.27) |
|||
(name "~" |
|||
(effects |
|||
(font |
|||
(size 1.27 1.27) |
|||
) |
|||
) |
|||
) |
|||
(number "2" |
|||
(effects |
|||
(font |
|||
(size 1.27 1.27) |
|||
) |
|||
) |
|||
) |
|||
) |
|||
) |
|||
(embedded_fonts no) |
|||
) |
|||
) |
|||
(rule_area |
|||
(polyline |
|||
(pts |
|||
(xy 59.69 54.61) (xy 71.12 54.61) (xy 71.12 68.58) (xy 59.69 68.58) |
|||
) |
|||
(stroke |
|||
(width 0) |
|||
(type dash) |
|||
) |
|||
(fill |
|||
(type none) |
|||
) |
|||
(uuid 60676821-919a-4f11-bd58-e337d82fbd8b) |
|||
) |
|||
) |
|||
(rule_area |
|||
(polyline |
|||
(pts |
|||
(xy 83.82 49.53) (xy 111.76 49.53) (xy 111.76 71.12) (xy 83.82 71.12) |
|||
) |
|||
(stroke |
|||
(width 0) |
|||
(type dash) |
|||
) |
|||
(fill |
|||
(type none) |
|||
) |
|||
(uuid a23b373f-8385-48e5-92cc-856340ee73bd) |
|||
) |
|||
) |
|||
(rule_area |
|||
(polyline |
|||
(pts |
|||
(xy 55.88 49.53) (xy 81.28 49.53) (xy 81.28 71.12) (xy 55.88 71.12) |
|||
) |
|||
(stroke |
|||
(width 0) |
|||
(type dash) |
|||
) |
|||
(fill |
|||
(type none) |
|||
) |
|||
(uuid bf519547-0f5f-46b4-89ee-2b48c33cd0fa) |
|||
) |
|||
) |
|||
(rule_area |
|||
(polyline |
|||
(pts |
|||
(xy 87.63 54.61) (xy 99.06 54.61) (xy 99.06 68.58) (xy 87.63 68.58) |
|||
) |
|||
(stroke |
|||
(width 0) |
|||
(type dash) |
|||
) |
|||
(fill |
|||
(type none) |
|||
) |
|||
(uuid cbff79ad-6039-46f6-903e-1814abb160d6) |
|||
) |
|||
) |
|||
(netclass_flag "" |
|||
(length 2.54) |
|||
(shape round) |
|||
(at 60.96 54.61 0) |
|||
(fields_autoplaced yes) |
|||
(effects |
|||
(font |
|||
(size 1.27 1.27) |
|||
) |
|||
(justify left bottom) |
|||
) |
|||
(uuid "95ce2569-329d-4346-bbd4-b51dfac2d0ae") |
|||
(property "Net Class" "" |
|||
(at -93.98 -5.08 0) |
|||
(effects |
|||
(font |
|||
(size 1.27 1.27) |
|||
) |
|||
) |
|||
) |
|||
(property "Component Class" "CLASS_2" |
|||
(at 61.6585 52.07 0) |
|||
(effects |
|||
(font |
|||
(size 1.27 1.27) |
|||
(italic yes) |
|||
) |
|||
(justify left) |
|||
) |
|||
) |
|||
) |
|||
(netclass_flag "" |
|||
(length 2.54) |
|||
(shape round) |
|||
(at 88.9 54.61 0) |
|||
(fields_autoplaced yes) |
|||
(effects |
|||
(font |
|||
(size 1.27 1.27) |
|||
) |
|||
(justify left bottom) |
|||
) |
|||
(uuid "aee35f39-27b9-471a-86b7-d88f529d2361") |
|||
(property "Net Class" "" |
|||
(at -66.04 -5.08 0) |
|||
(effects |
|||
(font |
|||
(size 1.27 1.27) |
|||
) |
|||
) |
|||
) |
|||
(property "Component Class" "CLASS_4" |
|||
(at 89.5985 52.07 0) |
|||
(effects |
|||
(font |
|||
(size 1.27 1.27) |
|||
(italic yes) |
|||
) |
|||
(justify left) |
|||
) |
|||
) |
|||
) |
|||
(netclass_flag "" |
|||
(length 2.54) |
|||
(shape round) |
|||
(at 57.15 49.53 0) |
|||
(fields_autoplaced yes) |
|||
(effects |
|||
(font |
|||
(size 1.27 1.27) |
|||
) |
|||
(justify left bottom) |
|||
) |
|||
(uuid "dbcaa6d2-dcb9-4a23-9e8c-5540859c5c95") |
|||
(property "Net Class" "" |
|||
(at -97.79 -10.16 0) |
|||
(effects |
|||
(font |
|||
(size 1.27 1.27) |
|||
) |
|||
) |
|||
) |
|||
(property "Component Class" "CLASS_1" |
|||
(at 57.8485 46.99 0) |
|||
(effects |
|||
(font |
|||
(size 1.27 1.27) |
|||
(italic yes) |
|||
) |
|||
(justify left) |
|||
) |
|||
) |
|||
) |
|||
(netclass_flag "" |
|||
(length 2.54) |
|||
(shape round) |
|||
(at 85.09 49.53 0) |
|||
(fields_autoplaced yes) |
|||
(effects |
|||
(font |
|||
(size 1.27 1.27) |
|||
) |
|||
(justify left bottom) |
|||
) |
|||
(uuid "ea51b758-1c26-4244-8696-148d5cd9f58c") |
|||
(property "Net Class" "" |
|||
(at -69.85 -10.16 0) |
|||
(effects |
|||
(font |
|||
(size 1.27 1.27) |
|||
) |
|||
) |
|||
) |
|||
(property "Component Class" "CLASS_3" |
|||
(at 85.7885 46.99 0) |
|||
(effects |
|||
(font |
|||
(size 1.27 1.27) |
|||
(italic yes) |
|||
) |
|||
(justify left) |
|||
) |
|||
) |
|||
) |
|||
(symbol |
|||
(lib_id "Device:R") |
|||
(at 64.77 60.96 0) |
|||
(unit 1) |
|||
(exclude_from_sim no) |
|||
(in_bom yes) |
|||
(on_board yes) |
|||
(dnp no) |
|||
(fields_autoplaced yes) |
|||
(uuid "46977abc-c53a-4b10-a881-2435f24468fa") |
|||
(property "Reference" "R1" |
|||
(at 67.31 59.6899 0) |
|||
(effects |
|||
(font |
|||
(size 1.27 1.27) |
|||
) |
|||
(justify left) |
|||
) |
|||
) |
|||
(property "Value" "R" |
|||
(at 67.31 62.2299 0) |
|||
(effects |
|||
(font |
|||
(size 1.27 1.27) |
|||
) |
|||
(justify left) |
|||
) |
|||
) |
|||
(property "Footprint" "Resistor_SMD:R_0805_2012Metric" |
|||
(at 62.992 60.96 90) |
|||
(hide yes) |
|||
(effects |
|||
(font |
|||
(size 1.27 1.27) |
|||
) |
|||
) |
|||
) |
|||
(property "Datasheet" "~" |
|||
(at 64.77 60.96 0) |
|||
(hide yes) |
|||
(effects |
|||
(font |
|||
(size 1.27 1.27) |
|||
) |
|||
) |
|||
) |
|||
(property "Description" "Resistor" |
|||
(at 64.77 60.96 0) |
|||
(hide yes) |
|||
(effects |
|||
(font |
|||
(size 1.27 1.27) |
|||
) |
|||
) |
|||
) |
|||
(pin "2" |
|||
(uuid "53eae49a-03b2-47c9-b978-836e854c42a1") |
|||
) |
|||
(pin "1" |
|||
(uuid "2dc56f9e-ed1a-423c-9716-246a54c077eb") |
|||
) |
|||
(instances |
|||
(project "" |
|||
(path "/d9ed75ce-7084-4177-b32b-fceb2cf7aac3" |
|||
(reference "R1") |
|||
(unit 1) |
|||
) |
|||
) |
|||
) |
|||
) |
|||
(symbol |
|||
(lib_id "Device:R") |
|||
(at 74.93 60.96 0) |
|||
(unit 1) |
|||
(exclude_from_sim no) |
|||
(in_bom yes) |
|||
(on_board yes) |
|||
(dnp no) |
|||
(fields_autoplaced yes) |
|||
(uuid "759e3836-df02-4bcc-823f-2488f4ccdc6a") |
|||
(property "Reference" "R2" |
|||
(at 77.47 59.6899 0) |
|||
(effects |
|||
(font |
|||
(size 1.27 1.27) |
|||
) |
|||
(justify left) |
|||
) |
|||
) |
|||
(property "Value" "R" |
|||
(at 77.47 62.2299 0) |
|||
(effects |
|||
(font |
|||
(size 1.27 1.27) |
|||
) |
|||
(justify left) |
|||
) |
|||
) |
|||
(property "Footprint" "Resistor_SMD:R_1206_3216Metric" |
|||
(at 73.152 60.96 90) |
|||
(hide yes) |
|||
(effects |
|||
(font |
|||
(size 1.27 1.27) |
|||
) |
|||
) |
|||
) |
|||
(property "Datasheet" "~" |
|||
(at 74.93 60.96 0) |
|||
(hide yes) |
|||
(effects |
|||
(font |
|||
(size 1.27 1.27) |
|||
) |
|||
) |
|||
) |
|||
(property "Description" "Resistor" |
|||
(at 74.93 60.96 0) |
|||
(hide yes) |
|||
(effects |
|||
(font |
|||
(size 1.27 1.27) |
|||
) |
|||
) |
|||
) |
|||
(pin "2" |
|||
(uuid "213fa619-1218-4639-837f-def396924d49") |
|||
) |
|||
(pin "1" |
|||
(uuid "3c26611e-5590-4cfc-9f38-c8d4c2888995") |
|||
) |
|||
(instances |
|||
(project "dynamic_component_class" |
|||
(path "/d9ed75ce-7084-4177-b32b-fceb2cf7aac3" |
|||
(reference "R2") |
|||
(unit 1) |
|||
) |
|||
) |
|||
) |
|||
) |
|||
(symbol |
|||
(lib_id "Device:C") |
|||
(at 92.71 60.96 0) |
|||
(unit 1) |
|||
(exclude_from_sim no) |
|||
(in_bom yes) |
|||
(on_board yes) |
|||
(dnp no) |
|||
(fields_autoplaced yes) |
|||
(uuid "ad3cf5f9-5e65-46c9-bb23-770c50780b5d") |
|||
(property "Reference" "C1" |
|||
(at 96.52 59.6899 0) |
|||
(effects |
|||
(font |
|||
(size 1.27 1.27) |
|||
) |
|||
(justify left) |
|||
) |
|||
) |
|||
(property "Value" "C" |
|||
(at 96.52 62.2299 0) |
|||
(effects |
|||
(font |
|||
(size 1.27 1.27) |
|||
) |
|||
(justify left) |
|||
) |
|||
) |
|||
(property "Footprint" "Capacitor_SMD:C_0805_2012Metric" |
|||
(at 93.6752 64.77 0) |
|||
(hide yes) |
|||
(effects |
|||
(font |
|||
(size 1.27 1.27) |
|||
) |
|||
) |
|||
) |
|||
(property "Datasheet" "~" |
|||
(at 92.71 60.96 0) |
|||
(hide yes) |
|||
(effects |
|||
(font |
|||
(size 1.27 1.27) |
|||
) |
|||
) |
|||
) |
|||
(property "Description" "Unpolarized capacitor" |
|||
(at 92.71 60.96 0) |
|||
(hide yes) |
|||
(effects |
|||
(font |
|||
(size 1.27 1.27) |
|||
) |
|||
) |
|||
) |
|||
(pin "1" |
|||
(uuid "58054707-8b09-45ae-8013-e46b0d7e0c18") |
|||
) |
|||
(pin "2" |
|||
(uuid "6718e73b-d736-47bd-ad02-995313219a5c") |
|||
) |
|||
(instances |
|||
(project "" |
|||
(path "/d9ed75ce-7084-4177-b32b-fceb2cf7aac3" |
|||
(reference "C1") |
|||
(unit 1) |
|||
) |
|||
) |
|||
) |
|||
) |
|||
(symbol |
|||
(lib_id "Device:C") |
|||
(at 104.14 60.96 0) |
|||
(unit 1) |
|||
(exclude_from_sim no) |
|||
(in_bom yes) |
|||
(on_board yes) |
|||
(dnp no) |
|||
(fields_autoplaced yes) |
|||
(uuid "efa7a2fa-3528-4332-b199-9931f7e1b80b") |
|||
(property "Reference" "C2" |
|||
(at 107.95 59.6899 0) |
|||
(effects |
|||
(font |
|||
(size 1.27 1.27) |
|||
) |
|||
(justify left) |
|||
) |
|||
) |
|||
(property "Value" "C" |
|||
(at 107.95 62.2299 0) |
|||
(effects |
|||
(font |
|||
(size 1.27 1.27) |
|||
) |
|||
(justify left) |
|||
) |
|||
) |
|||
(property "Footprint" "Capacitor_SMD:C_0805_2012Metric" |
|||
(at 105.1052 64.77 0) |
|||
(hide yes) |
|||
(effects |
|||
(font |
|||
(size 1.27 1.27) |
|||
) |
|||
) |
|||
) |
|||
(property "Datasheet" "~" |
|||
(at 104.14 60.96 0) |
|||
(hide yes) |
|||
(effects |
|||
(font |
|||
(size 1.27 1.27) |
|||
) |
|||
) |
|||
) |
|||
(property "Description" "Unpolarized capacitor" |
|||
(at 104.14 60.96 0) |
|||
(hide yes) |
|||
(effects |
|||
(font |
|||
(size 1.27 1.27) |
|||
) |
|||
) |
|||
) |
|||
(pin "1" |
|||
(uuid "cb84c371-6a34-4196-b6f2-6452853b524b") |
|||
) |
|||
(pin "2" |
|||
(uuid "24d51371-3fd2-4d66-9272-f054638174b7") |
|||
) |
|||
(instances |
|||
(project "dynamic_component_class" |
|||
(path "/d9ed75ce-7084-4177-b32b-fceb2cf7aac3" |
|||
(reference "C2") |
|||
(unit 1) |
|||
) |
|||
) |
|||
) |
|||
) |
|||
(sheet |
|||
(at 148.59 40.64) |
|||
(size 46.99 41.91) |
|||
(exclude_from_sim no) |
|||
(in_bom yes) |
|||
(on_board yes) |
|||
(dnp no) |
|||
(fields_autoplaced yes) |
|||
(stroke |
|||
(width 0.1524) |
|||
(type solid) |
|||
) |
|||
(fill |
|||
(color 0 0 0 0.0000) |
|||
) |
|||
(uuid "e826c7ec-b0cb-4f53-915d-da3597387304") |
|||
(property "Sheetname" "SHEET1" |
|||
(at 148.59 39.9284 0) |
|||
(effects |
|||
(font |
|||
(size 1.27 1.27) |
|||
) |
|||
(justify left bottom) |
|||
) |
|||
) |
|||
(property "Sheetfile" "component_classes_sheet1.kicad_sch" |
|||
(at 148.59 83.1346 0) |
|||
(effects |
|||
(font |
|||
(size 1.27 1.27) |
|||
) |
|||
(justify left top) |
|||
) |
|||
) |
|||
(instances |
|||
(project "component_classes" |
|||
(path "/d9ed75ce-7084-4177-b32b-fceb2cf7aac3" |
|||
(page "2") |
|||
) |
|||
) |
|||
) |
|||
) |
|||
(sheet_instances |
|||
(path "/" |
|||
(page "1") |
|||
) |
|||
) |
|||
(embedded_fonts no) |
|||
) |
|||
@ -0,0 +1,159 @@ |
|||
/*
|
|||
* This program source code file is part of KiCad, a free EDA CAD application. |
|||
* |
|||
* Copyright The KiCad Developers, see AUTHORS.txt for contributors. |
|||
* |
|||
* This program is free software; you can redistribute it and/or |
|||
* modify it under the terms of the GNU General Public License |
|||
* as published by the Free Software Foundation; either version 2 |
|||
* of the License, or (at your option) any later version. |
|||
* |
|||
* This program is distributed in the hope that it will be useful, |
|||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
* GNU General Public License for more details. |
|||
* |
|||
* You should have received a copy of the GNU General Public License |
|||
* along with this program; if not, you may find one here: |
|||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
|||
* or you may search the http://www.gnu.org website for the version 2 license,
|
|||
* or you may write to the Free Software Foundation, Inc., |
|||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA |
|||
*/ |
|||
|
|||
#include <qa_utils/wx_utils/unit_test_utils.h>
|
|||
#include <pcbnew_utils/board_test_utils.h>
|
|||
#include <board.h>
|
|||
#include <board_design_settings.h>
|
|||
#include <component_classes/component_class.h>
|
|||
#include <pad.h>
|
|||
#include <pcb_track.h>
|
|||
#include <pcb_marker.h>
|
|||
#include <footprint.h>
|
|||
#include <drc/drc_item.h>
|
|||
#include <settings/settings_manager.h>
|
|||
|
|||
|
|||
struct PCB_COMPONENT_CLASS_FIXTURE |
|||
{ |
|||
PCB_COMPONENT_CLASS_FIXTURE() : |
|||
m_settingsManager( true /* headless */ ) |
|||
{ } |
|||
|
|||
SETTINGS_MANAGER m_settingsManager; |
|||
std::unique_ptr<BOARD> m_board; |
|||
}; |
|||
|
|||
|
|||
BOOST_FIXTURE_TEST_CASE( ComponentClasses, PCB_COMPONENT_CLASS_FIXTURE ) |
|||
{ |
|||
KI_TEST::LoadBoard( m_settingsManager, "component_classes", m_board ); |
|||
|
|||
std::vector<DRC_ITEM> violations; |
|||
BOARD_DESIGN_SETTINGS& bds = m_board->GetDesignSettings(); |
|||
|
|||
std::vector<wxString> allClasses{ "ANY", "CAP_1", "CAP_2", "CLASS_1", |
|||
"CLASS_2", "CLASS_3", "CLASS_4", "MULTI_REF", |
|||
"REF_WILDCARD", "REF_WILDCARD2", "RES_1", "RES_2", |
|||
"RES_3", "RES_4" }; |
|||
|
|||
auto testClasses = [&allClasses](const wxString& ref, const COMPONENT_CLASS* compClass, std::vector<wxString> assignedClasses) |
|||
{ |
|||
std::vector<wxString> unassignedClasses; |
|||
std::ranges::set_difference(allClasses, assignedClasses, std::back_inserter(unassignedClasses)); |
|||
|
|||
for( const wxString& className : assignedClasses ) |
|||
{ |
|||
if( !compClass->ContainsClassName( className ) ) |
|||
{ |
|||
BOOST_ERROR( wxString::Format( |
|||
"%s component class failed (%s expected but not found - full class %s)", |
|||
ref, className, compClass->GetName() ) ); |
|||
} |
|||
} |
|||
|
|||
for( const wxString& className : unassignedClasses ) |
|||
{ |
|||
if( compClass->ContainsClassName( className ) ) |
|||
{ |
|||
BOOST_ERROR( wxString::Format( |
|||
"%s component class failed (%s found but not expected - full class %s)", |
|||
ref, className, compClass->GetName() ) ); |
|||
} |
|||
} |
|||
}; |
|||
|
|||
for( const auto fp : m_board->Footprints() ) |
|||
{ |
|||
if( fp->Reference().GetText() == wxT( "C1" ) ) |
|||
{ |
|||
testClasses( "C1", fp->GetComponentClass(), {"CAP_1", "CLASS_3", "CLASS_4"}); |
|||
} |
|||
|
|||
if( fp->Reference().GetText() == wxT( "C2" ) ) |
|||
{ |
|||
testClasses( "C2", fp->GetComponentClass(), {"CAP_2", "CLASS_3"}); |
|||
} |
|||
|
|||
if( fp->Reference().GetText() == wxT( "C3" ) ) |
|||
{ |
|||
testClasses( "C2", fp->GetComponentClass(), {}); |
|||
} |
|||
|
|||
if( fp->Reference().GetText() == wxT( "R8" ) ) |
|||
{ |
|||
testClasses( "R8", fp->GetComponentClass(), {"RES_1", "RES_2"}); |
|||
} |
|||
|
|||
if( fp->Reference().GetText() == wxT( "R88" ) ) |
|||
{ |
|||
testClasses( "R88", fp->GetComponentClass(), {"RES_2"}); |
|||
} |
|||
|
|||
if( fp->Reference().GetText() == wxT( "R2" ) ) |
|||
{ |
|||
testClasses( "R2", fp->GetComponentClass(), {"CLASS_1", "RES_1", "RES_2", "RES_3"}); |
|||
} |
|||
|
|||
if( fp->Reference().GetText() == wxT( "R1" ) ) |
|||
{ |
|||
testClasses( "R1", fp->GetComponentClass(), {"CLASS_1", "CLASS_2", "RES_1", "RES_2", "RES_4"}); |
|||
} |
|||
|
|||
if( fp->Reference().GetText() == wxT( "U1" ) ) |
|||
{ |
|||
testClasses( "U1", fp->GetComponentClass(), { "ANY" } ); |
|||
} |
|||
|
|||
if( fp->Reference().GetText() == wxT( "U2" ) ) |
|||
{ |
|||
testClasses( "U2", fp->GetComponentClass(), { "ANY" } ); |
|||
} |
|||
|
|||
if( fp->Reference().GetText() == wxT( "U3" ) ) |
|||
{ |
|||
testClasses( "U3", fp->GetComponentClass(), { "MULTI_REF" } ); |
|||
} |
|||
|
|||
if( fp->Reference().GetText() == wxT( "U4" ) ) |
|||
{ |
|||
testClasses( "U4", fp->GetComponentClass(), { "MULTI_REF" } ); |
|||
} |
|||
|
|||
if( fp->Reference().GetText() == wxT( "U55" ) ) |
|||
{ |
|||
testClasses( "U55", fp->GetComponentClass(), { "REF_WILDCARD", "REF_WILDCARD2" } ); |
|||
} |
|||
|
|||
if( fp->Reference().GetText() == wxT( "U555" ) ) |
|||
{ |
|||
testClasses( "U555", fp->GetComponentClass(), { "REF_WILDCARD2" } ); |
|||
} |
|||
|
|||
if( fp->Reference().GetText() == wxT( "R3" ) ) |
|||
{ |
|||
testClasses( "R3", fp->GetComponentClass(), { "/SHEET1/", "RES_1", "RES_2" } ); |
|||
} |
|||
} |
|||
|
|||
} |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue