Sch/PCB: allow back-updating schematic fields from PCB
Fixes: https://gitlab.com/kicad/code/kicad/-/issues/15285
This commit is contained in:
parent
b95b07e54d
commit
744452d092
|
@ -31,7 +31,7 @@
|
|||
|
||||
// Saved dialog settings
|
||||
DIALOG_UPDATE_FROM_PCB::DIALOG_UPDATE_FROM_PCB_SAVED_STATE
|
||||
DIALOG_UPDATE_FROM_PCB::s_savedDialogState{ false, true, true, true, false, true };
|
||||
DIALOG_UPDATE_FROM_PCB::s_savedDialogState{ false, true, true, true, false, true, true };
|
||||
|
||||
|
||||
DIALOG_UPDATE_FROM_PCB::DIALOG_UPDATE_FROM_PCB( SCH_EDIT_FRAME* aParent )
|
||||
|
@ -62,6 +62,7 @@ DIALOG_UPDATE_FROM_PCB::DIALOG_UPDATE_FROM_PCB( SCH_EDIT_FRAME* aParent )
|
|||
m_cbUpdateValues->SetValue( s_savedDialogState.UpdateValues );
|
||||
m_cbUpdateNetNames->SetValue( s_savedDialogState.UpdateNetNames );
|
||||
m_cbUpdateAttributes->SetValue( s_savedDialogState.UpdateAttributes );
|
||||
m_cbUpdateOtherFields->SetValue( s_savedDialogState.UpdateOtherFields );
|
||||
|
||||
SetupStandardButtons( { { wxID_OK, _( "Update Schematic" ) },
|
||||
{ wxID_CANCEL, _( "Close" ) } } );
|
||||
|
@ -82,6 +83,7 @@ void DIALOG_UPDATE_FROM_PCB::updateData()
|
|||
m_cbUpdateReferences->GetValue(),
|
||||
m_cbUpdateNetNames->GetValue(),
|
||||
m_cbUpdateAttributes->GetValue(),
|
||||
m_cbUpdateOtherFields->GetValue(),
|
||||
true );
|
||||
std::string netlist;
|
||||
|
||||
|
@ -135,6 +137,8 @@ void DIALOG_UPDATE_FROM_PCB::OnOptionChanged( wxCommandEvent& event )
|
|||
s_savedDialogState.UpdateNetNames = m_cbUpdateNetNames->GetValue();
|
||||
else if( event.GetEventObject() == m_cbUpdateAttributes )
|
||||
s_savedDialogState.UpdateAttributes = m_cbUpdateAttributes->GetValue();
|
||||
else if( event.GetEventObject() == m_cbUpdateOtherFields )
|
||||
s_savedDialogState.UpdateOtherFields = m_cbUpdateOtherFields->GetValue();
|
||||
}
|
||||
|
||||
|
||||
|
@ -150,6 +154,7 @@ void DIALOG_UPDATE_FROM_PCB::OnUpdateClick( wxCommandEvent& event )
|
|||
m_cbUpdateReferences->GetValue(),
|
||||
m_cbUpdateNetNames->GetValue(),
|
||||
m_cbUpdateAttributes->GetValue(),
|
||||
m_cbUpdateOtherFields->GetValue(),
|
||||
false );
|
||||
|
||||
if( backAnno.FetchNetlistFromPCB( netlist ) && backAnno.BackAnnotateSymbols( netlist ) )
|
||||
|
|
|
@ -56,6 +56,7 @@ private:
|
|||
bool UpdateValues;
|
||||
bool UpdateNetNames;
|
||||
bool UpdateAttributes;
|
||||
bool UpdateOtherFields;
|
||||
};
|
||||
|
||||
static DIALOG_UPDATE_FROM_PCB_SAVED_STATE s_savedDialogState;
|
||||
|
|
|
@ -72,6 +72,11 @@ DIALOG_UPDATE_FROM_PCB_BASE::DIALOG_UPDATE_FROM_PCB_BASE( wxWindow* parent, wxWi
|
|||
m_cbUpdateAttributes = new wxCheckBox( sbSizer2->GetStaticBox(), wxID_ANY, _("Attributes"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
fgSizer2->Add( m_cbUpdateAttributes, 0, wxBOTTOM|wxLEFT|wxRIGHT, 5 );
|
||||
|
||||
m_cbUpdateOtherFields = new wxCheckBox( sbSizer2->GetStaticBox(), wxID_ANY, _("Other fields"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_cbUpdateOtherFields->SetToolTip( _("Update all other fields in the symbol from the footprint") );
|
||||
|
||||
fgSizer2->Add( m_cbUpdateOtherFields, 0, wxBOTTOM|wxLEFT|wxRIGHT, 5 );
|
||||
|
||||
|
||||
sbSizer2->Add( fgSizer2, 1, wxEXPAND, 5 );
|
||||
|
||||
|
@ -112,6 +117,7 @@ DIALOG_UPDATE_FROM_PCB_BASE::DIALOG_UPDATE_FROM_PCB_BASE( wxWindow* parent, wxWi
|
|||
m_cbUpdateValues->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_UPDATE_FROM_PCB_BASE::OnOptionChanged ), NULL, this );
|
||||
m_cbUpdateNetNames->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_UPDATE_FROM_PCB_BASE::OnOptionChanged ), NULL, this );
|
||||
m_cbUpdateAttributes->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_UPDATE_FROM_PCB_BASE::OnOptionChanged ), NULL, this );
|
||||
m_cbUpdateOtherFields->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_UPDATE_FROM_PCB_BASE::OnOptionChanged ), NULL, this );
|
||||
m_sdbSizerOK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_UPDATE_FROM_PCB_BASE::OnUpdateClick ), NULL, this );
|
||||
}
|
||||
|
||||
|
@ -124,6 +130,7 @@ DIALOG_UPDATE_FROM_PCB_BASE::~DIALOG_UPDATE_FROM_PCB_BASE()
|
|||
m_cbUpdateValues->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_UPDATE_FROM_PCB_BASE::OnOptionChanged ), NULL, this );
|
||||
m_cbUpdateNetNames->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_UPDATE_FROM_PCB_BASE::OnOptionChanged ), NULL, this );
|
||||
m_cbUpdateAttributes->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_UPDATE_FROM_PCB_BASE::OnOptionChanged ), NULL, this );
|
||||
m_cbUpdateOtherFields->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_UPDATE_FROM_PCB_BASE::OnOptionChanged ), NULL, this );
|
||||
m_sdbSizerOK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_UPDATE_FROM_PCB_BASE::OnUpdateClick ), NULL, this );
|
||||
|
||||
}
|
||||
|
|
|
@ -520,6 +520,71 @@
|
|||
<event name="OnCheckBox">OnOptionChanged</event>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem" expanded="1">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxBOTTOM|wxLEFT|wxRIGHT</property>
|
||||
<property name="proportion">0</property>
|
||||
<object class="wxCheckBox" expanded="1">
|
||||
<property name="BottomDockable">1</property>
|
||||
<property name="LeftDockable">1</property>
|
||||
<property name="RightDockable">1</property>
|
||||
<property name="TopDockable">1</property>
|
||||
<property name="aui_layer"></property>
|
||||
<property name="aui_name"></property>
|
||||
<property name="aui_position"></property>
|
||||
<property name="aui_row"></property>
|
||||
<property name="best_size"></property>
|
||||
<property name="bg"></property>
|
||||
<property name="caption"></property>
|
||||
<property name="caption_visible">1</property>
|
||||
<property name="center_pane">0</property>
|
||||
<property name="checked">0</property>
|
||||
<property name="close_button">1</property>
|
||||
<property name="context_help"></property>
|
||||
<property name="context_menu">1</property>
|
||||
<property name="default_pane">0</property>
|
||||
<property name="dock">Dock</property>
|
||||
<property name="dock_fixed">0</property>
|
||||
<property name="docking">Left</property>
|
||||
<property name="enabled">1</property>
|
||||
<property name="fg"></property>
|
||||
<property name="floatable">1</property>
|
||||
<property name="font"></property>
|
||||
<property name="gripper">0</property>
|
||||
<property name="hidden">0</property>
|
||||
<property name="id">wxID_ANY</property>
|
||||
<property name="label">Other fields</property>
|
||||
<property name="max_size"></property>
|
||||
<property name="maximize_button">0</property>
|
||||
<property name="maximum_size"></property>
|
||||
<property name="min_size"></property>
|
||||
<property name="minimize_button">0</property>
|
||||
<property name="minimum_size"></property>
|
||||
<property name="moveable">1</property>
|
||||
<property name="name">m_cbUpdateOtherFields</property>
|
||||
<property name="pane_border">1</property>
|
||||
<property name="pane_position"></property>
|
||||
<property name="pane_size"></property>
|
||||
<property name="permission">protected</property>
|
||||
<property name="pin_button">1</property>
|
||||
<property name="pos"></property>
|
||||
<property name="resize">Resizable</property>
|
||||
<property name="show">1</property>
|
||||
<property name="size"></property>
|
||||
<property name="style"></property>
|
||||
<property name="subclass">; forward_declare</property>
|
||||
<property name="toolbar_pane">0</property>
|
||||
<property name="tooltip">Update all other fields in the symbol from the footprint</property>
|
||||
<property name="validator_data_type"></property>
|
||||
<property name="validator_style">wxFILTER_NONE</property>
|
||||
<property name="validator_type">wxDefaultValidator</property>
|
||||
<property name="validator_variable"></property>
|
||||
<property name="window_extra_style"></property>
|
||||
<property name="window_name"></property>
|
||||
<property name="window_style"></property>
|
||||
<event name="OnCheckBox">OnOptionChanged</event>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
|
|
|
@ -41,6 +41,7 @@ class DIALOG_UPDATE_FROM_PCB_BASE : public DIALOG_SHIM
|
|||
wxCheckBox* m_cbUpdateValues;
|
||||
wxCheckBox* m_cbUpdateNetNames;
|
||||
wxCheckBox* m_cbUpdateAttributes;
|
||||
wxCheckBox* m_cbUpdateOtherFields;
|
||||
WX_HTML_REPORT_PANEL* m_messagePanel;
|
||||
wxStdDialogButtonSizer* m_sdbSizer;
|
||||
wxButton* m_sdbSizerOK;
|
||||
|
|
|
@ -94,8 +94,9 @@ void NETLIST_EXPORTER_XML::addSymbolFields( XNODE* aNode, SCH_SYMBOL* aSymbol,
|
|||
SCH_SHEET_PATH* aSheet )
|
||||
{
|
||||
wxString value;
|
||||
wxString datasheet;
|
||||
wxString footprint;
|
||||
wxString datasheet;
|
||||
wxString description;
|
||||
wxString candidate;
|
||||
std::map<wxString, wxString> userFields;
|
||||
|
||||
|
@ -127,16 +128,20 @@ void NETLIST_EXPORTER_XML::addSymbolFields( XNODE* aNode, SCH_SYMBOL* aSymbol,
|
|||
int unit = symbol2->GetUnitSelection( aSheet );
|
||||
|
||||
// The lowest unit number wins. User should only set fields in any one unit.
|
||||
|
||||
// Value
|
||||
candidate = symbol2->GetValueFieldText( m_resolveTextVars, &sheetList[i], false );
|
||||
|
||||
if( !candidate.IsEmpty() && ( unit < minUnit || value.IsEmpty() ) )
|
||||
value = candidate;
|
||||
|
||||
// Footprint
|
||||
candidate = symbol2->GetFootprintFieldText( m_resolveTextVars, &sheetList[i], false );
|
||||
|
||||
if( !candidate.IsEmpty() && ( unit < minUnit || footprint.IsEmpty() ) )
|
||||
footprint = candidate;
|
||||
|
||||
// Datasheet
|
||||
candidate = m_resolveTextVars
|
||||
? symbol2->GetField( DATASHEET_FIELD )->GetShownText( &sheetList[i], false )
|
||||
: symbol2->GetField( DATASHEET_FIELD )->GetText();
|
||||
|
@ -144,6 +149,15 @@ void NETLIST_EXPORTER_XML::addSymbolFields( XNODE* aNode, SCH_SYMBOL* aSymbol,
|
|||
if( !candidate.IsEmpty() && ( unit < minUnit || datasheet.IsEmpty() ) )
|
||||
datasheet = candidate;
|
||||
|
||||
// Description
|
||||
candidate = m_resolveTextVars
|
||||
? symbol2->GetField( DESCRIPTION_FIELD )->GetShownText( &sheetList[i], false )
|
||||
: symbol2->GetField( DESCRIPTION_FIELD )->GetText();
|
||||
|
||||
if( !candidate.IsEmpty() && ( unit < minUnit || description.IsEmpty() ) )
|
||||
description = candidate;
|
||||
|
||||
// All non-mandatory fields
|
||||
for( int ii = MANDATORY_FIELDS; ii < symbol2->GetFieldCount(); ++ii )
|
||||
{
|
||||
const SCH_FIELD& f = symbol2->GetFields()[ ii ];
|
||||
|
@ -167,11 +181,18 @@ void NETLIST_EXPORTER_XML::addSymbolFields( XNODE* aNode, SCH_SYMBOL* aSymbol,
|
|||
value = aSymbol->GetValueFieldText( m_resolveTextVars, aSheet, false );
|
||||
footprint = aSymbol->GetFootprintFieldText( m_resolveTextVars, aSheet, false );
|
||||
|
||||
// Datasheet
|
||||
if( m_resolveTextVars )
|
||||
datasheet = aSymbol->GetField( DATASHEET_FIELD )->GetShownText( aSheet, false );
|
||||
else
|
||||
datasheet = aSymbol->GetField( DATASHEET_FIELD )->GetText();
|
||||
|
||||
// Description
|
||||
if( m_resolveTextVars )
|
||||
description = aSymbol->GetField( DESCRIPTION_FIELD )->GetShownText( aSheet, false );
|
||||
else
|
||||
description = aSymbol->GetField( DESCRIPTION_FIELD )->GetText();
|
||||
|
||||
for( int ii = MANDATORY_FIELDS; ii < aSymbol->GetFieldCount(); ++ii )
|
||||
{
|
||||
const SCH_FIELD& f = aSymbol->GetFields()[ ii ];
|
||||
|
@ -198,11 +219,26 @@ void NETLIST_EXPORTER_XML::addSymbolFields( XNODE* aNode, SCH_SYMBOL* aSymbol,
|
|||
if( datasheet.size() )
|
||||
aNode->AddChild( node( wxT( "datasheet" ), UnescapeString( datasheet ) ) );
|
||||
|
||||
if( datasheet.size() )
|
||||
aNode->AddChild( node( wxT( "description" ), UnescapeString( description ) ) );
|
||||
|
||||
if( userFields.size() )
|
||||
{
|
||||
XNODE* xfields;
|
||||
aNode->AddChild( xfields = node( wxT( "fields" ) ) );
|
||||
|
||||
XNODE* datasheetField = node( wxT( "field" ), UnescapeString( datasheet ) );
|
||||
datasheetField->AddAttribute(
|
||||
wxT( "name" ),
|
||||
UnescapeString( TEMPLATE_FIELDNAME::GetDefaultFieldName( DATASHEET_FIELD ) ) );
|
||||
xfields->AddChild( datasheetField );
|
||||
|
||||
XNODE* descriptionField = node( wxT( "field" ), UnescapeString( description ) );
|
||||
descriptionField->AddAttribute(
|
||||
wxT( "name" ),
|
||||
UnescapeString( TEMPLATE_FIELDNAME::GetDefaultFieldName( DESCRIPTION_FIELD ) ) );
|
||||
xfields->AddChild( descriptionField );
|
||||
|
||||
// non MANDATORY fields are output alphabetically
|
||||
for( const std::pair<const wxString, wxString>& f : userFields )
|
||||
{
|
||||
|
|
|
@ -44,7 +44,8 @@
|
|||
BACK_ANNOTATE::BACK_ANNOTATE( SCH_EDIT_FRAME* aFrame, REPORTER& aReporter, bool aRelinkFootprints,
|
||||
bool aProcessFootprints, bool aProcessValues,
|
||||
bool aProcessReferences, bool aProcessNetNames,
|
||||
bool aProcessAttributes, bool aDryRun ) :
|
||||
bool aProcessAttributes, bool aProcessOtherFields,
|
||||
bool aDryRun ) :
|
||||
m_reporter( aReporter ),
|
||||
m_matchByReference( aRelinkFootprints ),
|
||||
m_processFootprints( aProcessFootprints ),
|
||||
|
@ -52,6 +53,7 @@ BACK_ANNOTATE::BACK_ANNOTATE( SCH_EDIT_FRAME* aFrame, REPORTER& aReporter, bool
|
|||
m_processReferences( aProcessReferences ),
|
||||
m_processNetNames( aProcessNetNames ),
|
||||
m_processAttributes( aProcessAttributes ),
|
||||
m_processOtherFields( aProcessOtherFields ),
|
||||
m_dryRun( aDryRun ),
|
||||
m_frame( aFrame ),
|
||||
m_changesCount( 0 )
|
||||
|
@ -150,7 +152,7 @@ void BACK_ANNOTATE::getPcbModulesFromString( const std::string& aPayload )
|
|||
{
|
||||
wxString path, value, footprint;
|
||||
bool dnp = false, exBOM = false;
|
||||
std::map<wxString, wxString> pinNetMap;
|
||||
std::map<wxString, wxString> pinNetMap, fieldsMap;
|
||||
wxASSERT( item.first == "ref" );
|
||||
wxString ref = getStr( item.second );
|
||||
|
||||
|
@ -171,6 +173,29 @@ void BACK_ANNOTATE::getPcbModulesFromString( const std::string& aPayload )
|
|||
footprint = getStr( item.second.get_child( "fpid" ) );
|
||||
value = getStr( item.second.get_child( "value" ) );
|
||||
|
||||
// Get child PTREE of fields
|
||||
boost::optional<const PTREE&> fields = item.second.get_child_optional( "fields" );
|
||||
|
||||
// Parse each field out of the fields string
|
||||
if( fields )
|
||||
{
|
||||
for( const std::pair<const std::string, PTREE>& field : fields.get() )
|
||||
{
|
||||
if( field.first != "field" )
|
||||
continue;
|
||||
|
||||
// Fields are of the format "(field (name "name") "12345")
|
||||
auto fieldName = field.second.get_child_optional( "name" );
|
||||
auto fieldValue = field.second.back().first;
|
||||
|
||||
if( !fieldName )
|
||||
continue;
|
||||
|
||||
fieldsMap[getStr( fieldName.get() )] = fieldValue;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Get DNP and Exclude from BOM out of the properties if they exist
|
||||
for( const auto& child : item.second )
|
||||
{
|
||||
|
@ -226,7 +251,7 @@ void BACK_ANNOTATE::getPcbModulesFromString( const std::string& aPayload )
|
|||
{
|
||||
// Add footprint to the map
|
||||
auto data = std::make_shared<PCB_FP_DATA>( ref, footprint, value, dnp, exBOM,
|
||||
pinNetMap );
|
||||
pinNetMap, fieldsMap );
|
||||
m_pcbFootprints.insert( nearestItem, std::make_pair( path, data ) );
|
||||
}
|
||||
}
|
||||
|
@ -465,6 +490,81 @@ void BACK_ANNOTATE::applyChangelist()
|
|||
}
|
||||
}
|
||||
|
||||
if( m_processOtherFields )
|
||||
{
|
||||
// Need to handle three cases: existing field, new field, deleted field
|
||||
for( const std::pair<const wxString, wxString>& field : fpData.m_fieldsMap )
|
||||
{
|
||||
const wxString& fpFieldName = field.first;
|
||||
const wxString& fpFieldValue = field.second;
|
||||
SCH_FIELD* symField = symbol->FindField( fpFieldName );
|
||||
|
||||
// 1. Existing fields has changed value
|
||||
// PCB Field value is checked against the shown text because this is the value
|
||||
// with all the variables resolved. The footprints field value gets the symbol's
|
||||
// resolved value when the PCB is updated from the schematic.
|
||||
if( symField
|
||||
&& symField->GetShownText( &ref.GetSheetPath(), false ) != fpFieldValue )
|
||||
{
|
||||
m_changesCount++;
|
||||
msg.Printf( _( "Change field '%s' value to '%s'." ),
|
||||
symField->GetCanonicalName(), fpFieldValue );
|
||||
|
||||
if( !m_dryRun )
|
||||
{
|
||||
commit.Modify( symbol, screen );
|
||||
symField->SetText( fpFieldValue );
|
||||
}
|
||||
|
||||
m_reporter.ReportHead( msg, RPT_SEVERITY_ACTION );
|
||||
}
|
||||
|
||||
// 2. New field has been added to footprint and needs to be added to symbol
|
||||
if( symField == nullptr )
|
||||
{
|
||||
m_changesCount++;
|
||||
msg.Printf( _( "Add field '%s' with value '%s'." ), fpFieldName, fpFieldValue );
|
||||
|
||||
if( !m_dryRun )
|
||||
{
|
||||
commit.Modify( symbol, screen );
|
||||
|
||||
SCH_FIELD newField( VECTOR2I( 0, 0 ), symbol->GetFieldCount(), symbol,
|
||||
fpFieldName );
|
||||
newField.SetText( fpFieldValue );
|
||||
symbol->AddField( newField );
|
||||
}
|
||||
|
||||
m_reporter.ReportHead( msg, RPT_SEVERITY_ACTION );
|
||||
}
|
||||
}
|
||||
|
||||
// 3. Existing field has been deleted from footprint and needs to be deleted from symbol
|
||||
// Check all symbol fields for existence in the footprint field map
|
||||
for( SCH_FIELD& field : symbol->GetFields() )
|
||||
{
|
||||
// Never delete mandatory fields
|
||||
if( field.GetId() < MANDATORY_FIELDS )
|
||||
continue;
|
||||
|
||||
if( fpData.m_fieldsMap.find( field.GetCanonicalName() )
|
||||
== fpData.m_fieldsMap.end() )
|
||||
{
|
||||
// Field not found in footprint field map, delete it
|
||||
m_changesCount++;
|
||||
msg.Printf( _( "Delete field '%s.'" ), field.GetCanonicalName() );
|
||||
|
||||
if( !m_dryRun )
|
||||
{
|
||||
commit.Modify( symbol, screen );
|
||||
symbol->RemoveField( &field );
|
||||
}
|
||||
|
||||
m_reporter.ReportHead( msg, RPT_SEVERITY_ACTION );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: back-annotate netclass changes?
|
||||
}
|
||||
|
||||
|
|
|
@ -62,13 +62,15 @@ public:
|
|||
{
|
||||
PCB_FP_DATA( const wxString& aRef, const wxString& aFootprint, const wxString& aValue,
|
||||
bool aDNP, bool aExcludeFromBOM,
|
||||
const std::map<wxString, wxString>& aPinMap ) :
|
||||
const std::map<wxString, wxString>& aPinMap,
|
||||
const std::map<wxString, wxString>& aFieldsMap ) :
|
||||
m_ref( aRef ),
|
||||
m_footprint( aFootprint ),
|
||||
m_value( aValue ),
|
||||
m_DNP( aDNP ),
|
||||
m_excludeFromBOM( aExcludeFromBOM ),
|
||||
m_pinMap( aPinMap )
|
||||
m_pinMap( aPinMap ),
|
||||
m_fieldsMap( aFieldsMap )
|
||||
{}
|
||||
|
||||
wxString m_ref;
|
||||
|
@ -77,6 +79,7 @@ public:
|
|||
bool m_DNP;
|
||||
bool m_excludeFromBOM;
|
||||
std::map<wxString, wxString> m_pinMap;
|
||||
std::map<wxString, wxString> m_fieldsMap;
|
||||
};
|
||||
|
||||
///< Map to hold NETLIST footprints data
|
||||
|
@ -86,7 +89,8 @@ public:
|
|||
|
||||
BACK_ANNOTATE( SCH_EDIT_FRAME* aFrame, REPORTER& aReporter, bool aRelinkFootprints,
|
||||
bool aProcessFootprints, bool aProcessValues, bool aProcessReferences,
|
||||
bool aProcessNetNames, bool aProcessAttributes, bool aDryRun );
|
||||
bool aProcessNetNames, bool aProcessAttributes, bool aProcessOtherFields,
|
||||
bool aDryRun );
|
||||
~BACK_ANNOTATE();
|
||||
|
||||
/**
|
||||
|
@ -143,6 +147,7 @@ private:
|
|||
bool m_processReferences;
|
||||
bool m_processNetNames;
|
||||
bool m_processAttributes;
|
||||
bool m_processOtherFields;
|
||||
bool m_dryRun;
|
||||
|
||||
PCB_FOOTPRINTS_MAP m_pcbFootprints;
|
||||
|
|
|
@ -563,6 +563,12 @@ void PCB_EDIT_FRAME::KiwayMailIn( KIWAY_EXPRESS& mail )
|
|||
}
|
||||
}
|
||||
|
||||
std::map<wxString, wxString> fields;
|
||||
for( PCB_FIELD* field : footprint->Fields() )
|
||||
fields[field->GetCanonicalName()] = field->GetText();
|
||||
|
||||
component->SetFields( fields );
|
||||
|
||||
// Add DNP and Exclude from BOM properties
|
||||
std::map<wxString, wxString> properties;
|
||||
|
||||
|
|
|
@ -360,6 +360,7 @@ bool BOARD_NETLIST_UPDATER::updateFootprintParameters( FOOTPRINT* aPcbFootprint,
|
|||
|
||||
changed = true;
|
||||
|
||||
// Add or change field value
|
||||
for( auto pair : aNetlistComponent->GetFields() )
|
||||
{
|
||||
if( aPcbFootprint->HasFieldByName( pair.first ) )
|
||||
|
@ -386,6 +387,16 @@ bool BOARD_NETLIST_UPDATER::updateFootprintParameters( FOOTPRINT* aPcbFootprint,
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Remove fields that aren't present in the symbol
|
||||
for( PCB_FIELD* field : aPcbFootprint->GetFields() )
|
||||
{
|
||||
if( field->IsMandatoryField() )
|
||||
continue;
|
||||
|
||||
if( aNetlistComponent->GetFields().count( field->GetName() ) == 0 )
|
||||
aPcbFootprint->RemoveField( field->GetCanonicalName() );
|
||||
}
|
||||
}
|
||||
|
||||
m_reporter->Report( msg, RPT_SEVERITY_ACTION );
|
||||
|
|
|
@ -93,6 +93,15 @@ void COMPONENT::Format( OUTPUTFORMATTER* aOut, int aNestLevel, int aCtl )
|
|||
|
||||
aOut->Print( nl+1, "(timestamp %s)\n", aOut->Quotew( path ).c_str() );
|
||||
|
||||
// Add all fields as a (field) under a (fields) node
|
||||
aOut->Print( nl + 1, "(fields" );
|
||||
|
||||
for( std::pair<wxString, wxString> field : m_fields )
|
||||
aOut->Print( nl + 2, "\n(field (name %s) %s)", aOut->Quotew( field.first ).c_str(),
|
||||
aOut->Quotew( field.second ).c_str() );
|
||||
|
||||
aOut->Print( 0, ")\n" );
|
||||
|
||||
// Add DNP and Exclude from BOM properties if we have them
|
||||
if( m_properties.count( "dnp" ) )
|
||||
aOut->Print( nl + 1, "(property (name \"dnp\"))\n" );
|
||||
|
|
|
@ -473,6 +473,12 @@ int BOARD_EDITOR_CONTROL::ExportNetlist( const TOOL_EVENT& aEvent )
|
|||
}
|
||||
}
|
||||
|
||||
std::map<wxString, wxString> fields;
|
||||
for( PCB_FIELD* field : footprint->Fields() )
|
||||
fields[field->GetCanonicalName()] = field->GetText();
|
||||
|
||||
component->SetFields( fields );
|
||||
|
||||
netlist.AddComponent( component );
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue