Fix some bugs in Change Symbol and Update Symbols.

In particular, there was a typo that kept library values from being
updated, and there was missing logic to fetch the various field names
from the library parts (and the change-to part).

Also implements some performance gains by desisting from copying
LIB_FIELDs around every time we want to look at them.

Fixes https://gitlab.com/kicad/code/kicad/issues/6733

Fixes https://gitlab.com/kicad/code/kicad/issues/6749
This commit is contained in:
Jeff Young 2020-12-15 15:06:19 +00:00
parent ffdc46d313
commit 10e68daa37
16 changed files with 197 additions and 255 deletions

View File

@ -829,6 +829,12 @@ void LIB_PART::deleteAllFields()
} }
void LIB_PART::AddField( LIB_FIELD* aField )
{
AddDrawItem( aField );
}
void LIB_PART::SetFields( const std::vector <LIB_FIELD>& aFields ) void LIB_PART::SetFields( const std::vector <LIB_FIELD>& aFields )
{ {
deleteAllFields(); deleteAllFields();
@ -844,30 +850,35 @@ void LIB_PART::SetFields( const std::vector <LIB_FIELD>& aFields )
} }
void LIB_PART::GetFields( LIB_FIELDS& aList ) void LIB_PART::GetFields( std::vector<LIB_FIELD*>& aList )
{ {
LIB_FIELD* field; // Grab the MANDATORY_FIELDS first, in expected order given by enum NumFieldType
// Grab the MANDATORY_FIELDS first, in expected order given by
// enum NumFieldType
for( int id = 0; id < MANDATORY_FIELDS; ++id ) for( int id = 0; id < MANDATORY_FIELDS; ++id )
{ aList.push_back( GetField( id ) );
field = GetField( id );
// the MANDATORY_FIELDS are exactly that in RAM.
wxASSERT( field );
aList.push_back( *field );
}
// Now grab all the rest of fields. // Now grab all the rest of fields.
for( LIB_ITEM& item : m_drawings[ LIB_FIELD_T ] ) for( LIB_ITEM& item : m_drawings[ LIB_FIELD_T ] )
{ {
field = ( LIB_FIELD* ) &item; LIB_FIELD* field = static_cast<LIB_FIELD*>( &item );
if( field->IsMandatory() ) if( !field->IsMandatory() )
continue; // was added above aList.push_back( field );
}
}
void LIB_PART::GetFields( std::vector<LIB_FIELD>& aList )
{
// Grab the MANDATORY_FIELDS first, in expected order given by enum NumFieldType
for( int id = 0; id < MANDATORY_FIELDS; ++id )
aList.push_back( *GetField( id ) );
// Now grab all the rest of fields.
for( LIB_ITEM& item : m_drawings[ LIB_FIELD_T ] )
{
LIB_FIELD* field = static_cast<LIB_FIELD*>( &item );
if( !field->IsMandatory() )
aList.push_back( *field ); aList.push_back( *field );
} }
} }

View File

@ -255,7 +255,14 @@ public:
* *
* @param aList - List to add fields to * @param aList - List to add fields to
*/ */
void GetFields( LIB_FIELDS& aList ); void GetFields( std::vector<LIB_FIELD*>& aList );
void GetFields( std::vector<LIB_FIELD>& aList );
/**
* Add a field. Takes ownership of the pointer.
* @param aField
*/
void AddField( LIB_FIELD* aField );
/** /**
* Find a field within this part matching \a aFieldName and returns it * Find a field within this part matching \a aFieldName and returns it

View File

@ -237,21 +237,11 @@ void DIALOG_CHANGE_SYMBOLS::launchNewIdSymbolBrowser( wxCommandEvent& aEvent )
void DIALOG_CHANGE_SYMBOLS::updateFieldsList() void DIALOG_CHANGE_SYMBOLS::updateFieldsList()
{ {
SCH_EDIT_FRAME* frame = dynamic_cast<SCH_EDIT_FRAME*>( GetParent() ); SCH_EDIT_FRAME* frame = dynamic_cast<SCH_EDIT_FRAME*>( GetParent() );
wxCHECK( frame, /* void */ );
LIB_ID newId;
SCH_SHEET_LIST hierarchy = frame->Schematic().GetSheets(); SCH_SHEET_LIST hierarchy = frame->Schematic().GetSheets();
if( m_mode == MODE::CHANGE ) // Load non-mandatory fields from all matching symbols and their library parts
{ std::vector<SCH_FIELD*> fields;
newId.Parse( m_newId->GetValue(), LIB_ID::ID_SCH ); std::vector<LIB_FIELD*> libFields;
if( !newId.IsValid() )
return;
}
// Load new non-mandatory fields from the library parts of all matching symbols
std::set<wxString> fieldNames; std::set<wxString> fieldNames;
for( SCH_SHEET_PATH& instance : hierarchy ) for( SCH_SHEET_PATH& instance : hierarchy )
@ -269,10 +259,43 @@ void DIALOG_CHANGE_SYMBOLS::updateFieldsList()
if( !isMatch( symbol, &instance ) ) if( !isMatch( symbol, &instance ) )
continue; continue;
std::vector<SCH_FIELD>& fields = symbol->GetFields(); symbol->GetFields( fields, false );
for( unsigned i = MANDATORY_FIELDS; i < fields.size(); ++i ) for( unsigned i = MANDATORY_FIELDS; i < fields.size(); ++i )
fieldNames.insert( fields[i].GetName() ); fieldNames.insert( fields[i]->GetName() );
if( m_mode == MODE::UPDATE && symbol->GetPartRef() )
{
symbol->GetPartRef()->Flatten()->GetFields( libFields );
for( unsigned i = MANDATORY_FIELDS; i < libFields.size(); ++i )
fieldNames.insert( libFields[i]->GetName() );
}
}
}
// Load non-mandatory fields from the change-to library part
if( m_mode == MODE::CHANGE )
{
LIB_ID newId;
newId.Parse( m_newId->GetValue(), LIB_ID::ID_SCH );
if( newId.IsValid() )
{
LIB_PART* libSymbol = frame->GetLibPart( newId );
if( libSymbol )
{
std::unique_ptr<LIB_PART> flattenedPart = libSymbol->Flatten();
flattenedPart->GetFields( libFields );
for( unsigned i = MANDATORY_FIELDS; i < libFields.size(); ++i )
fieldNames.insert( libFields[i]->GetName() );
libFields.clear(); // flattenedPart is about to go out of scope...
}
} }
} }
@ -535,7 +558,7 @@ bool DIALOG_CHANGE_SYMBOLS::processSymbol( SCH_COMPONENT* aSymbol, const SCH_SHE
else if( i == FOOTPRINT_FIELD ) else if( i == FOOTPRINT_FIELD )
aSymbol->SetFootprint( aInstance, libField->GetText() ); aSymbol->SetFootprint( aInstance, libField->GetText() );
else else
field->SetText( wxEmptyString ); field->SetText( libField->GetText() );
} }
if( resetVis ) if( resetVis )
@ -550,10 +573,8 @@ bool DIALOG_CHANGE_SYMBOLS::processSymbol( SCH_COMPONENT* aSymbol, const SCH_SHE
} }
if( resetPositions ) if( resetPositions )
{
field->SetTextPos( aSymbol->GetPosition() + libField->GetTextPos() ); field->SetTextPos( aSymbol->GetPosition() + libField->GetTextPos() );
} }
}
else if( i >= MANDATORY_FIELDS && removeExtras ) else if( i >= MANDATORY_FIELDS && removeExtras )
{ {
aSymbol->RemoveField( field->GetName() ); aSymbol->RemoveField( field->GetName() );
@ -561,12 +582,12 @@ bool DIALOG_CHANGE_SYMBOLS::processSymbol( SCH_COMPONENT* aSymbol, const SCH_SHE
} }
} }
LIB_FIELDS libFields; std::vector<LIB_FIELD*> libFields;
libSymbol->GetFields( libFields ); libSymbol->GetFields( libFields );
for( unsigned i = MANDATORY_FIELDS; i < libFields.size(); ++i ) for( unsigned i = MANDATORY_FIELDS; i < libFields.size(); ++i )
{ {
LIB_FIELD& libField = libFields[i]; const LIB_FIELD& libField = *libFields[i];
if( !alg::contains( m_updateFields, libField.GetName() ) ) if( !alg::contains( m_updateFields, libField.GetName() ) )
continue; continue;

View File

@ -113,10 +113,15 @@ DIALOG_SPICE_MODEL::DIALOG_SPICE_MODEL( wxWindow* aParent, SCH_COMPONENT& aCompo
} }
DIALOG_SPICE_MODEL::DIALOG_SPICE_MODEL( wxWindow* aParent, SCH_COMPONENT& aComponent, LIB_FIELDS* aFields ) DIALOG_SPICE_MODEL::DIALOG_SPICE_MODEL( wxWindow* aParent, SCH_COMPONENT& aComponent,
: DIALOG_SPICE_MODEL_BASE( aParent ), m_component( aComponent ), m_schfields( nullptr ), std::vector<LIB_FIELD>* aFields ) :
m_libfields( aFields ), m_useSchFields( false ), DIALOG_SPICE_MODEL_BASE( aParent ),
m_spiceEmptyValidator( true ), m_notEmptyValidator( wxFILTER_EMPTY ) m_component( aComponent ),
m_schfields( nullptr ),
m_libfields( aFields ),
m_useSchFields( false ),
m_spiceEmptyValidator( true ),
m_notEmptyValidator( wxFILTER_EMPTY )
{ {
Init(); Init();
} }

View File

@ -38,8 +38,10 @@
class DIALOG_SPICE_MODEL : public DIALOG_SPICE_MODEL_BASE class DIALOG_SPICE_MODEL : public DIALOG_SPICE_MODEL_BASE
{ {
public: public:
DIALOG_SPICE_MODEL( wxWindow* aParent, SCH_COMPONENT& aComponent, SCH_FIELDS* aSchFields ); DIALOG_SPICE_MODEL( wxWindow* aParent, SCH_COMPONENT& aComponent,
DIALOG_SPICE_MODEL( wxWindow* aParent, SCH_COMPONENT& aComponent, LIB_FIELDS* aLibFields ); std::vector<SCH_FIELD>* aSchFields );
DIALOG_SPICE_MODEL( wxWindow* aParent, SCH_COMPONENT& aComponent,
std::vector<LIB_FIELD>* aLibFields );
private: private:
/** /**
@ -124,8 +126,8 @@ private:
SCH_COMPONENT& m_component; SCH_COMPONENT& m_component;
///> Fields from the component properties dialog ///> Fields from the component properties dialog
SCH_FIELDS* m_schfields; std::vector<SCH_FIELD>* m_schfields;
LIB_FIELDS* m_libfields; std::vector<LIB_FIELD>* m_libfields;
bool m_useSchFields; bool m_useSchFields;
///> Temporary field values ///> Temporary field values

View File

@ -203,13 +203,12 @@ protected:
void SetHtmlFieldTable() void SetHtmlFieldTable()
{ {
wxString fieldtable; wxString fieldtable;
LIB_FIELDS fields; std::vector<LIB_FIELD*> fields;
m_symbol->GetFields( fields ); m_symbol->GetFields( fields );
for( auto const & field: fields ) for( const LIB_FIELD* field: fields )
{ fieldtable += GetHtmlFieldRow( *field );
fieldtable += GetHtmlFieldRow( field );
}
if( m_symbol->IsAlias() ) if( m_symbol->IsAlias() )
{ {
@ -218,16 +217,16 @@ protected:
// Append all of the unique parent fields if this is an alias. // Append all of the unique parent fields if this is an alias.
if( parent ) if( parent )
{ {
LIB_FIELDS parentFields; std::vector<LIB_FIELD*> parentFields;
parent->GetFields( parentFields ); parent->GetFields( parentFields );
for( auto const& parentField : parentFields ) for( const LIB_FIELD* parentField : parentFields )
{ {
if( m_symbol->FindField( parentField.GetCanonicalName() ) ) if( m_symbol->FindField( parentField->GetCanonicalName() ) )
continue; continue;
fieldtable += GetHtmlFieldRow( parentField ); fieldtable += GetHtmlFieldRow( *parentField );
} }
} }
} }

View File

@ -215,6 +215,4 @@ private:
LIB_ITEM::COMPARE_FLAGS aCompareFlags = LIB_ITEM::COMPARE_FLAGS::NORMAL ) const override; LIB_ITEM::COMPARE_FLAGS aCompareFlags = LIB_ITEM::COMPARE_FLAGS::NORMAL ) const override;
}; };
typedef std::vector< LIB_FIELD > LIB_FIELDS;
#endif // CLASS_LIBENTRY_FIELDS_H #endif // CLASS_LIBENTRY_FIELDS_H

View File

@ -461,7 +461,7 @@ XNODE* NETLIST_EXPORTER_XML::makeLibParts()
XNODE* xlibparts = node( "libparts" ); // auto_ptr XNODE* xlibparts = node( "libparts" ); // auto_ptr
LIB_PINS pinList; LIB_PINS pinList;
LIB_FIELDS fieldList; std::vector<LIB_FIELD*> fieldList;
m_libraries.clear(); m_libraries.clear();
@ -502,13 +502,13 @@ XNODE* NETLIST_EXPORTER_XML::makeLibParts()
XNODE* xfields; XNODE* xfields;
xlibpart->AddChild( xfields = node( "fields" ) ); xlibpart->AddChild( xfields = node( "fields" ) );
for( unsigned i=0; i<fieldList.size(); ++i ) for( const LIB_FIELD* field : fieldList )
{ {
if( !fieldList[i].GetText().IsEmpty() ) if( !field->GetText().IsEmpty() )
{ {
XNODE* xfield; XNODE* xfield;
xfields->AddChild( xfield = node( "field", fieldList[i].GetText() ) ); xfields->AddChild( xfield = node( "field", field->GetText() ) );
xfield->AddAttribute( "name", fieldList[i].GetCanonicalName() ); xfield->AddAttribute( "name", field->GetCanonicalName() );
} }
} }

View File

@ -749,12 +749,13 @@ void SCH_COMPONENT::UpdateFields( bool aResetStyle, bool aResetRef )
if( m_part ) if( m_part )
{ {
wxString symbolName; wxString symbolName;
LIB_FIELDS fields; std::vector<LIB_FIELD*> fields;
m_part->GetFields( fields ); m_part->GetFields( fields );
for( const LIB_FIELD& libField : fields ) for( const LIB_FIELD* libField : fields )
{ {
int idx = libField.GetId(); int idx = libField->GetId();
SCH_FIELD* schField; SCH_FIELD* schField;
if( idx == REFERENCE_FIELD && !aResetRef ) if( idx == REFERENCE_FIELD && !aResetRef )
@ -766,11 +767,11 @@ void SCH_COMPONENT::UpdateFields( bool aResetStyle, bool aResetRef )
} }
else else
{ {
schField = FindField( libField.GetCanonicalName() ); schField = FindField( libField->GetCanonicalName() );
if( !schField ) if( !schField )
{ {
wxString fieldName = libField.GetCanonicalName(); wxString fieldName = libField->GetCanonicalName();
SCH_FIELD newField( wxPoint( 0, 0), GetFieldCount(), this, fieldName ); SCH_FIELD newField( wxPoint( 0, 0), GetFieldCount(), this, fieldName );
schField = AddField( newField ); schField = AddField( newField );
} }
@ -778,8 +779,8 @@ void SCH_COMPONENT::UpdateFields( bool aResetStyle, bool aResetRef )
if( aResetStyle ) if( aResetStyle )
{ {
schField->ImportValues( libField ); schField->ImportValues( *libField );
schField->SetTextPos( m_pos + libField.GetTextPos() ); schField->SetTextPos( m_pos + libField->GetTextPos() );
} }
if( idx == VALUE_FIELD ) if( idx == VALUE_FIELD )
@ -793,7 +794,7 @@ void SCH_COMPONENT::UpdateFields( bool aResetStyle, bool aResetRef )
} }
else else
{ {
schField->SetText( libField.GetText() ); schField->SetText( libField->GetText() );
} }
} }
} }

View File

@ -372,9 +372,7 @@ bool SCH_FIELD::IsReplaceable() const
if( m_id == VALUE_FIELD ) if( m_id == VALUE_FIELD )
{ {
LIB_PART* part = parentSymbol->GetPartRef().get(); if( parentSymbol->GetPartRef() && parentSymbol->GetPartRef()->IsPower() )
if( part && part->IsPower() )
return false; return false;
} }
} }

View File

@ -1014,10 +1014,7 @@ void CADSTAR_SCH_ARCHIVE_LOADER::loadSymDefIntoLibrary( const SYMDEF_ID& aSymdef
if( !field ) if( !field )
{ {
field = new LIB_FIELD( aPart, FIELD1 ); field = new LIB_FIELD( aPart, FIELD1 );
std::vector<LIB_FIELD> partFields; aPart->AddField( field );
aPart->GetFields( partFields );
partFields.push_back( *field );
aPart->SetFields( partFields );
} }
field->SetName( "Part Name" ); field->SetName( "Part Name" );

View File

@ -1151,14 +1151,14 @@ void SCH_EAGLE_PLUGIN::loadInstance( wxXmlNode* aInstanceNode )
component->MirrorY( einstance.x.ToSchUnits() ); component->MirrorY( einstance.x.ToSchUnits() );
} }
LIB_FIELDS partFields; std::vector<LIB_FIELD*> partFields;
part->GetFields( partFields ); part->GetFields( partFields );
for( auto const& field : partFields ) for( const LIB_FIELD* field : partFields )
{ {
component->GetField( field.GetId() )->ImportValues( field ); component->GetField( field->GetId() )->ImportValues( *field );
component->GetField( field.GetId() ) component->GetField( field->GetId() )->SetTextPos( component->GetPosition()
->SetTextPos( component->GetPosition() + field.GetTextPos() ); + field->GetTextPos() );
} }
// If there is no footprint assigned, then prepend the reference value // If there is no footprint assigned, then prepend the reference value

View File

@ -297,8 +297,6 @@ class SCH_SEXPR_PLUGIN_CACHE
int m_versionMinor; int m_versionMinor;
SCH_LIB_TYPE m_libType; // Is this cache a component or symbol library. SCH_LIB_TYPE m_libType; // Is this cache a component or symbol library.
static FILL_TYPE parseFillMode( LINE_READER& aReader, const char* aLine,
const char** aOutput );
LIB_PART* removeSymbol( LIB_PART* aAlias ); LIB_PART* removeSymbol( LIB_PART* aAlias );
static void saveSymbolDrawItem( LIB_ITEM* aItem, OUTPUTFORMATTER& aFormatter, static void saveSymbolDrawItem( LIB_ITEM* aItem, OUTPUTFORMATTER& aFormatter,
@ -308,7 +306,8 @@ class SCH_SEXPR_PLUGIN_CACHE
int aNestLevel = 0 ); int aNestLevel = 0 );
static void saveCircle( LIB_CIRCLE* aCircle, OUTPUTFORMATTER& aFormatter, static void saveCircle( LIB_CIRCLE* aCircle, OUTPUTFORMATTER& aFormatter,
int aNestLevel = 0 ); int aNestLevel = 0 );
static void saveField( LIB_FIELD* aField, OUTPUTFORMATTER& aFormatter, int aNestLevel = 0 ); static void saveField( const LIB_FIELD* aField, OUTPUTFORMATTER& aFormatter,
int aNestLevel = 0 );
static void savePin( LIB_PIN* aPin, OUTPUTFORMATTER& aFormatter, int aNestLevel = 0 ); static void savePin( LIB_PIN* aPin, OUTPUTFORMATTER& aFormatter, int aNestLevel = 0 );
static void savePolyLine( LIB_POLYLINE* aPolyLine, OUTPUTFORMATTER& aFormatter, static void savePolyLine( LIB_POLYLINE* aPolyLine, OUTPUTFORMATTER& aFormatter,
int aNestLevel = 0 ); int aNestLevel = 0 );
@ -1520,7 +1519,7 @@ void SCH_SEXPR_PLUGIN_CACHE::SaveSymbol( LIB_PART* aSymbol, OUTPUTFORMATTER& aFo
LOCALE_IO toggle ); LOCALE_IO toggle );
int lastFieldId; int lastFieldId;
LIB_FIELDS fields; std::vector<LIB_FIELD*> fields;
std::string name = aFormatter.Quotew( aSymbol->GetLibId().Format().wx_str() ); std::string name = aFormatter.Quotew( aSymbol->GetLibId().Format().wx_str() );
std::string unitName = aSymbol->GetLibId().GetLibItemName(); std::string unitName = aSymbol->GetLibId().GetLibItemName();
@ -1575,10 +1574,10 @@ void SCH_SEXPR_PLUGIN_CACHE::SaveSymbol( LIB_PART* aSymbol, OUTPUTFORMATTER& aFo
aSymbol->GetFields( fields ); aSymbol->GetFields( fields );
for( LIB_FIELD& field : fields ) for( const LIB_FIELD* field : fields )
saveField( &field, aFormatter, aNestLevel + 1 ); saveField( field, aFormatter, aNestLevel + 1 );
lastFieldId = fields.back().GetId() + 1; lastFieldId = fields.back()->GetId() + 1;
// @todo At some point in the future the lock status (all units interchangeable) should // @todo At some point in the future the lock status (all units interchangeable) should
// be set deterministically. For now a custom lock propertery is used to preserve the // be set deterministically. For now a custom lock propertery is used to preserve the
@ -1594,7 +1593,8 @@ void SCH_SEXPR_PLUGIN_CACHE::SaveSymbol( LIB_PART* aSymbol, OUTPUTFORMATTER& aFo
// Save the draw items grouped by units. // Save the draw items grouped by units.
std::vector<PART_UNITS> units = aSymbol->GetUnitDrawItems(); std::vector<PART_UNITS> units = aSymbol->GetUnitDrawItems();
std::sort( units.begin(), units.end(), []( const PART_UNITS& a, const PART_UNITS& b ) std::sort( units.begin(), units.end(),
[]( const PART_UNITS& a, const PART_UNITS& b )
{ {
if( a.m_unit == b.m_unit ) if( a.m_unit == b.m_unit )
return a.m_convert < b.m_convert; return a.m_convert < b.m_convert;
@ -1629,10 +1629,10 @@ void SCH_SEXPR_PLUGIN_CACHE::SaveSymbol( LIB_PART* aSymbol, OUTPUTFORMATTER& aFo
aSymbol->GetFields( fields ); aSymbol->GetFields( fields );
for( LIB_FIELD& field : fields ) for( const LIB_FIELD* field : fields )
saveField( &field, aFormatter, aNestLevel + 1 ); saveField( field, aFormatter, aNestLevel + 1 );
lastFieldId = fields.back().GetId() + 1; lastFieldId = fields.back()->GetId() + 1;
saveDcmInfoAsFields( aSymbol, aFormatter, aNestLevel, lastFieldId ); saveDcmInfoAsFields( aSymbol, aFormatter, aNestLevel, lastFieldId );
} }
@ -1730,8 +1730,7 @@ void SCH_SEXPR_PLUGIN_CACHE::saveSymbolDrawItem( LIB_ITEM* aItem, OUTPUTFORMATTE
} }
void SCH_SEXPR_PLUGIN_CACHE::saveArc( LIB_ARC* aArc, void SCH_SEXPR_PLUGIN_CACHE::saveArc( LIB_ARC* aArc, OUTPUTFORMATTER& aFormatter,
OUTPUTFORMATTER& aFormatter,
int aNestLevel ) int aNestLevel )
{ {
wxCHECK_RET( aArc && aArc->Type() == LIB_ARC_T, "Invalid LIB_ARC object." ); wxCHECK_RET( aArc && aArc->Type() == LIB_ARC_T, "Invalid LIB_ARC object." );
@ -1837,8 +1836,7 @@ void SCH_SEXPR_PLUGIN_CACHE::saveCircle( LIB_CIRCLE* aCircle,
} }
void SCH_SEXPR_PLUGIN_CACHE::saveField( LIB_FIELD* aField, void SCH_SEXPR_PLUGIN_CACHE::saveField( const LIB_FIELD* aField, OUTPUTFORMATTER& aFormatter,
OUTPUTFORMATTER& aFormatter,
int aNestLevel ) int aNestLevel )
{ {
wxCHECK_RET( aField && aField->Type() == LIB_FIELD_T, "Invalid LIB_FIELD object." ); wxCHECK_RET( aField && aField->Type() == LIB_FIELD_T, "Invalid LIB_FIELD object." );
@ -1956,8 +1954,7 @@ void SCH_SEXPR_PLUGIN_CACHE::savePolyLine( LIB_POLYLINE* aPolyLine,
} }
void SCH_SEXPR_PLUGIN_CACHE::saveRectangle( LIB_RECTANGLE* aRectangle, void SCH_SEXPR_PLUGIN_CACHE::saveRectangle( LIB_RECTANGLE* aRectangle, OUTPUTFORMATTER& aFormatter,
OUTPUTFORMATTER& aFormatter,
int aNestLevel ) int aNestLevel )
{ {
wxCHECK_RET( aRectangle && aRectangle->Type() == LIB_RECTANGLE_T, wxCHECK_RET( aRectangle && aRectangle->Type() == LIB_RECTANGLE_T,
@ -1976,8 +1973,7 @@ void SCH_SEXPR_PLUGIN_CACHE::saveRectangle( LIB_RECTANGLE* aRectangle,
} }
void SCH_SEXPR_PLUGIN_CACHE::saveText( LIB_TEXT* aText, void SCH_SEXPR_PLUGIN_CACHE::saveText( LIB_TEXT* aText, OUTPUTFORMATTER& aFormatter,
OUTPUTFORMATTER& aFormatter,
int aNestLevel ) int aNestLevel )
{ {
wxCHECK_RET( aText && aText->Type() == LIB_TEXT_T, "Invalid LIB_TEXT object." ); wxCHECK_RET( aText && aText->Type() == LIB_TEXT_T, "Invalid LIB_TEXT object." );

View File

@ -514,11 +514,11 @@ class SCH_LEGACY_PLUGIN_CACHE
static void saveArc( LIB_ARC* aArc, OUTPUTFORMATTER& aFormatter ); static void saveArc( LIB_ARC* aArc, OUTPUTFORMATTER& aFormatter );
static void saveBezier( LIB_BEZIER* aBezier, OUTPUTFORMATTER& aFormatter ); static void saveBezier( LIB_BEZIER* aBezier, OUTPUTFORMATTER& aFormatter );
static void saveCircle( LIB_CIRCLE* aCircle, OUTPUTFORMATTER& aFormatter ); static void saveCircle( LIB_CIRCLE* aCircle, OUTPUTFORMATTER& aFormatter );
static void saveField( LIB_FIELD* aField, OUTPUTFORMATTER& aFormatter ); static void saveField( const LIB_FIELD* aField, OUTPUTFORMATTER& aFormatter );
static void savePin( LIB_PIN* aPin, OUTPUTFORMATTER& aFormatter ); static void savePin( const LIB_PIN* aPin, OUTPUTFORMATTER& aFormatter );
static void savePolyLine( LIB_POLYLINE* aPolyLine, OUTPUTFORMATTER& aFormatter ); static void savePolyLine( LIB_POLYLINE* aPolyLine, OUTPUTFORMATTER& aFormatter );
static void saveRectangle( LIB_RECTANGLE* aRectangle, OUTPUTFORMATTER& aFormatter ); static void saveRectangle( LIB_RECTANGLE* aRectangle, OUTPUTFORMATTER& aFormatter );
static void saveText( LIB_TEXT* aText, OUTPUTFORMATTER& aFormatter ); static void saveText( const LIB_TEXT* aText, OUTPUTFORMATTER& aFormatter );
friend SCH_LEGACY_PLUGIN; friend SCH_LEGACY_PLUGIN;
@ -3811,7 +3811,7 @@ void SCH_LEGACY_PLUGIN_CACHE::SaveSymbol( LIB_PART* aSymbol, OUTPUTFORMATTER& aF
aFormatter.Print( 0, "Ti %d/%d/%d %d:%d:%d\n", year, mon, day, hour, min, sec ); aFormatter.Print( 0, "Ti %d/%d/%d %d:%d:%d\n", year, mon, day, hour, min, sec );
} }
LIB_FIELDS fields; std::vector<LIB_FIELD*> fields;
aSymbol->GetFields( fields ); aSymbol->GetFields( fields );
// Mandatory fields: // Mandatory fields:
@ -3819,9 +3819,7 @@ void SCH_LEGACY_PLUGIN_CACHE::SaveSymbol( LIB_PART* aSymbol, OUTPUTFORMATTER& aF
// Empty fields are saved, because the user may have set visibility, // Empty fields are saved, because the user may have set visibility,
// size and orientation // size and orientation
for( int i = 0; i < MANDATORY_FIELDS; ++i ) for( int i = 0; i < MANDATORY_FIELDS; ++i )
{ saveField( fields[i], aFormatter );
saveField( &fields[i], aFormatter );
}
// User defined fields: // User defined fields:
// may have their own save policy so there is a separate loop for them. // may have their own save policy so there is a separate loop for them.
@ -3833,10 +3831,10 @@ void SCH_LEGACY_PLUGIN_CACHE::SaveSymbol( LIB_PART* aSymbol, OUTPUTFORMATTER& aF
// There is no need to save empty fields, i.e. no reason to preserve field // There is no need to save empty fields, i.e. no reason to preserve field
// names now that fields names come in dynamically through the template // names now that fields names come in dynamically through the template
// fieldnames. // fieldnames.
if( !fields[i].GetText().IsEmpty() ) if( !fields[i]->GetText().IsEmpty() )
{ {
fields[i].SetId( fieldId++ ); fields[i]->SetId( fieldId++ );
saveField( &fields[i], aFormatter ); saveField( fields[i], aFormatter );
} }
} }
@ -3846,9 +3844,7 @@ void SCH_LEGACY_PLUGIN_CACHE::SaveSymbol( LIB_PART* aSymbol, OUTPUTFORMATTER& aF
aFormatter.Print( 0, "ALIAS" ); aFormatter.Print( 0, "ALIAS" );
for( unsigned i = 0; i < aliasNames.GetCount(); i++ ) for( unsigned i = 0; i < aliasNames.GetCount(); i++ )
{
aFormatter.Print( 0, " %s", TO_UTF8( aliasNames[i] ) ); aFormatter.Print( 0, " %s", TO_UTF8( aliasNames[i] ) );
}
aFormatter.Print( 0, "\n" ); aFormatter.Print( 0, "\n" );
} }
@ -3861,9 +3857,7 @@ void SCH_LEGACY_PLUGIN_CACHE::SaveSymbol( LIB_PART* aSymbol, OUTPUTFORMATTER& aF
aFormatter.Print( 0, "$FPLIST\n" ); aFormatter.Print( 0, "$FPLIST\n" );
for( unsigned i = 0; i < footprints.GetCount(); i++ ) for( unsigned i = 0; i < footprints.GetCount(); i++ )
{
aFormatter.Print( 0, " %s\n", TO_UTF8( footprints[i] ) ); aFormatter.Print( 0, " %s\n", TO_UTF8( footprints[i] ) );
}
aFormatter.Print( 0, "$ENDFPLIST\n" ); aFormatter.Print( 0, "$ENDFPLIST\n" );
} }
@ -3880,39 +3874,15 @@ void SCH_LEGACY_PLUGIN_CACHE::SaveSymbol( LIB_PART* aSymbol, OUTPUTFORMATTER& aF
{ {
switch( item.Type() ) switch( item.Type() )
{ {
case LIB_FIELD_T: // Fields have already been saved above.
continue;
case LIB_ARC_T:
saveArc( (LIB_ARC*) &item, aFormatter );
break;
case LIB_BEZIER_T:
saveBezier( (LIB_BEZIER*) &item, aFormatter );
break;
case LIB_CIRCLE_T:
saveCircle( ( LIB_CIRCLE* ) &item, aFormatter );
break;
case LIB_PIN_T:
savePin( (LIB_PIN* ) &item, aFormatter );
break;
case LIB_POLYLINE_T:
savePolyLine( ( LIB_POLYLINE* ) &item, aFormatter );
break;
case LIB_RECTANGLE_T:
saveRectangle( ( LIB_RECTANGLE* ) &item, aFormatter );
break;
case LIB_TEXT_T:
saveText( ( LIB_TEXT* ) &item, aFormatter );
break;
default: default:
; case LIB_FIELD_T: /* Fields have already been saved above. */ break;
case LIB_ARC_T: saveArc( (LIB_ARC*) &item, aFormatter ); break;
case LIB_BEZIER_T: saveBezier( (LIB_BEZIER*) &item, aFormatter ); break;
case LIB_CIRCLE_T: saveCircle( ( LIB_CIRCLE* ) &item, aFormatter ); break;
case LIB_PIN_T: savePin( (LIB_PIN* ) &item, aFormatter ); break;
case LIB_POLYLINE_T: savePolyLine( ( LIB_POLYLINE* ) &item, aFormatter ); break;
case LIB_RECTANGLE_T: saveRectangle( ( LIB_RECTANGLE* ) &item, aFormatter ); break;
case LIB_TEXT_T: saveText( ( LIB_TEXT* ) &item, aFormatter ); break;
} }
} }
@ -3923,8 +3893,7 @@ void SCH_LEGACY_PLUGIN_CACHE::SaveSymbol( LIB_PART* aSymbol, OUTPUTFORMATTER& aF
} }
void SCH_LEGACY_PLUGIN_CACHE::saveArc( LIB_ARC* aArc, void SCH_LEGACY_PLUGIN_CACHE::saveArc( LIB_ARC* aArc, OUTPUTFORMATTER& aFormatter )
OUTPUTFORMATTER& aFormatter )
{ {
wxCHECK_RET( aArc && aArc->Type() == LIB_ARC_T, "Invalid LIB_ARC object." ); wxCHECK_RET( aArc && aArc->Type() == LIB_ARC_T, "Invalid LIB_ARC object." );
@ -3974,8 +3943,7 @@ void SCH_LEGACY_PLUGIN_CACHE::saveCircle( LIB_CIRCLE* aCircle,
} }
void SCH_LEGACY_PLUGIN_CACHE::saveField( LIB_FIELD* aField, void SCH_LEGACY_PLUGIN_CACHE::saveField( const LIB_FIELD* aField, OUTPUTFORMATTER& aFormatter )
OUTPUTFORMATTER& aFormatter )
{ {
wxCHECK_RET( aField && aField->Type() == LIB_FIELD_T, "Invalid LIB_FIELD object." ); wxCHECK_RET( aField && aField->Type() == LIB_FIELD_T, "Invalid LIB_FIELD object." );
@ -4022,8 +3990,7 @@ void SCH_LEGACY_PLUGIN_CACHE::saveField( LIB_FIELD* aField,
} }
void SCH_LEGACY_PLUGIN_CACHE::savePin( LIB_PIN* aPin, void SCH_LEGACY_PLUGIN_CACHE::savePin( const LIB_PIN* aPin, OUTPUTFORMATTER& aFormatter )
OUTPUTFORMATTER& aFormatter )
{ {
wxCHECK_RET( aPin && aPin->Type() == LIB_PIN_T, "Invalid LIB_PIN object." ); wxCHECK_RET( aPin && aPin->Type() == LIB_PIN_T, "Invalid LIB_PIN object." );
@ -4032,49 +3999,17 @@ void SCH_LEGACY_PLUGIN_CACHE::savePin( LIB_PIN* aPin,
switch( aPin->GetType() ) switch( aPin->GetType() )
{ {
default: default:
case ELECTRICAL_PINTYPE::PT_INPUT: case ELECTRICAL_PINTYPE::PT_INPUT: Etype = 'I'; break;
Etype = 'I'; case ELECTRICAL_PINTYPE::PT_OUTPUT: Etype = 'O'; break;
break; case ELECTRICAL_PINTYPE::PT_BIDI: Etype = 'B'; break;
case ELECTRICAL_PINTYPE::PT_TRISTATE: Etype = 'T'; break;
case ELECTRICAL_PINTYPE::PT_OUTPUT: case ELECTRICAL_PINTYPE::PT_PASSIVE: Etype = 'P'; break;
Etype = 'O'; case ELECTRICAL_PINTYPE::PT_UNSPECIFIED: Etype = 'U'; break;
break; case ELECTRICAL_PINTYPE::PT_POWER_IN: Etype = 'W'; break;
case ELECTRICAL_PINTYPE::PT_POWER_OUT: Etype = 'w'; break;
case ELECTRICAL_PINTYPE::PT_BIDI: case ELECTRICAL_PINTYPE::PT_OPENCOLLECTOR: Etype = 'C'; break;
Etype = 'B'; case ELECTRICAL_PINTYPE::PT_OPENEMITTER: Etype = 'E'; break;
break; case ELECTRICAL_PINTYPE::PT_NC: Etype = 'N'; break;
case ELECTRICAL_PINTYPE::PT_TRISTATE:
Etype = 'T';
break;
case ELECTRICAL_PINTYPE::PT_PASSIVE:
Etype = 'P';
break;
case ELECTRICAL_PINTYPE::PT_UNSPECIFIED:
Etype = 'U';
break;
case ELECTRICAL_PINTYPE::PT_POWER_IN:
Etype = 'W';
break;
case ELECTRICAL_PINTYPE::PT_POWER_OUT:
Etype = 'w';
break;
case ELECTRICAL_PINTYPE::PT_OPENCOLLECTOR:
Etype = 'C';
break;
case ELECTRICAL_PINTYPE::PT_OPENEMITTER:
Etype = 'E';
break;
case ELECTRICAL_PINTYPE::PT_NC:
Etype = 'N';
break;
} }
if( !aPin->GetName().IsEmpty() ) if( !aPin->GetName().IsEmpty() )
@ -4097,48 +4032,21 @@ void SCH_LEGACY_PLUGIN_CACHE::savePin( LIB_PIN* aPin,
switch( aPin->GetShape() ) switch( aPin->GetShape() )
{ {
case GRAPHIC_PINSHAPE::LINE: case GRAPHIC_PINSHAPE::LINE: break;
break; case GRAPHIC_PINSHAPE::INVERTED: aFormatter.Print( 0, "I" ); break;
case GRAPHIC_PINSHAPE::CLOCK: aFormatter.Print( 0, "C" ); break;
case GRAPHIC_PINSHAPE::INVERTED: case GRAPHIC_PINSHAPE::INVERTED_CLOCK: aFormatter.Print( 0, "IC" ); break;
aFormatter.Print( 0, "I" ); case GRAPHIC_PINSHAPE::INPUT_LOW: aFormatter.Print( 0, "L" ); break;
break; case GRAPHIC_PINSHAPE::CLOCK_LOW: aFormatter.Print( 0, "CL" ); break;
case GRAPHIC_PINSHAPE::OUTPUT_LOW: aFormatter.Print( 0, "V" ); break;
case GRAPHIC_PINSHAPE::CLOCK: case GRAPHIC_PINSHAPE::FALLING_EDGE_CLOCK: aFormatter.Print( 0, "F" ); break;
aFormatter.Print( 0, "C" ); case GRAPHIC_PINSHAPE::NONLOGIC: aFormatter.Print( 0, "X" ); break;
break; default: wxFAIL_MSG( "Invalid pin shape" );
case GRAPHIC_PINSHAPE::INVERTED_CLOCK:
aFormatter.Print( 0, "IC" );
break;
case GRAPHIC_PINSHAPE::INPUT_LOW:
aFormatter.Print( 0, "L" );
break;
case GRAPHIC_PINSHAPE::CLOCK_LOW:
aFormatter.Print( 0, "CL" );
break;
case GRAPHIC_PINSHAPE::OUTPUT_LOW:
aFormatter.Print( 0, "V" );
break;
case GRAPHIC_PINSHAPE::FALLING_EDGE_CLOCK:
aFormatter.Print( 0, "F" );
break;
case GRAPHIC_PINSHAPE::NONLOGIC:
aFormatter.Print( 0, "X" );
break;
default:
assert( !"Invalid pin shape" );
} }
aFormatter.Print( 0, "\n" ); aFormatter.Print( 0, "\n" );
aPin->ClearFlags( IS_CHANGED ); const_cast<LIB_PIN*>( aPin )->ClearFlags( IS_CHANGED );
} }
@ -4176,8 +4084,7 @@ void SCH_LEGACY_PLUGIN_CACHE::saveRectangle( LIB_RECTANGLE* aRectangle,
} }
void SCH_LEGACY_PLUGIN_CACHE::saveText( LIB_TEXT* aText, void SCH_LEGACY_PLUGIN_CACHE::saveText( const LIB_TEXT* aText, OUTPUTFORMATTER& aFormatter )
OUTPUTFORMATTER& aFormatter )
{ {
wxCHECK_RET( aText && aText->Type() == LIB_TEXT_T, "Invalid LIB_TEXT object." ); wxCHECK_RET( aText && aText->Type() == LIB_TEXT_T, "Invalid LIB_TEXT object." );

View File

@ -47,9 +47,9 @@ struct print_log_value<LIB_FIELD>
}; };
template <> template <>
struct print_log_value<LIB_FIELDS> struct print_log_value<std::vector<LIB_FIELD>>
{ {
inline void operator()( std::ostream& os, LIB_FIELDS const& f ) inline void operator()( std::ostream& os, std::vector<LIB_FIELD> const& f )
{ {
os << "LIB_FIELDS[ " << f.size() << " ]"; os << "LIB_FIELDS[ " << f.size() << " ]";
} }
@ -96,7 +96,7 @@ bool FieldNameIdMatches( const LIB_FIELD& aField, const std::string& aExpectedNa
* @param aFields the fields to check * @param aFields the fields to check
* @return true if valid * @return true if valid
*/ */
bool AreDefaultFieldsCorrect( const LIB_FIELDS& aFields ) bool AreDefaultFieldsCorrect( const std::vector<LIB_FIELD>& aFields )
{ {
const unsigned expectedCount = NumFieldType::MANDATORY_FIELDS; const unsigned expectedCount = NumFieldType::MANDATORY_FIELDS;
if( aFields.size() < expectedCount ) if( aFields.size() < expectedCount )

View File

@ -96,7 +96,7 @@ BOOST_AUTO_TEST_CASE( DefaultDrawings )
*/ */
BOOST_AUTO_TEST_CASE( DefaultFields ) BOOST_AUTO_TEST_CASE( DefaultFields )
{ {
LIB_FIELDS fields; std::vector<LIB_FIELD> fields;
m_part_no_data.GetFields( fields ); m_part_no_data.GetFields( fields );
// Should get the 4 default fields // Should get the 4 default fields
@ -120,7 +120,7 @@ BOOST_AUTO_TEST_CASE( DefaultFields )
*/ */
BOOST_AUTO_TEST_CASE( AddedFields ) BOOST_AUTO_TEST_CASE( AddedFields )
{ {
LIB_FIELDS fields; std::vector<LIB_FIELD> fields;
m_part_no_data.GetFields( fields ); m_part_no_data.GetFields( fields );
// Ctor takes non-const ref (?!) // Ctor takes non-const ref (?!)