void DIALOG_EDIT_LIBENTRY_FIELDS_IN_LIB::initBuffers() { LIB_FIELDS cmpFields; m_libEntry->GetFields( cmpFields ); #if defined(DEBUG) for( unsigned i=0; i<cmpFields.size(); ++i ) { printf( "cmpFields[%u].name:%s\n", i, TO_UTF8( cmpFields[i].GetName() ) ); } #endif /* We have 3 component related field lists to be aware of: 1) UI presentation (m_FieldsBuf), 2) fields in component ram copy, and 3) fields recorded with component on disk. m_FieldsBuf is the list of UI fields, and this list is not the same as the list which is in the component, which is also not the same as the list on disk. All 3 lists are potentially different. In the UI we choose to preserve the order of the first MANDATORY_FIELDS which are sometimes called fixed fields. Then we append the template fieldnames in the exact same order as the template fieldname editor shows them. Then we append any user defined fieldnames which came from the component, and user can modify it during editing, but cannot delete or move a fixed field. */ m_FieldsBuf.clear(); /* When this code was written, all field constructors ensured that the MANDATORY_FIELDS are all present within a component (in ram only). So we can knowingly copy them over in the normal order. Copy only the fixed fields at first. Please do not break the field constructors. */ // fixed fields: for( int i=0; i<MANDATORY_FIELDS; ++i ) { DBG( printf( "add fixed:%s\n", TO_UTF8( cmpFields[i].GetName() ) ); ) m_FieldsBuf.push_back( cmpFields[i] ); }
XNODE* NETLIST_EXPORTER_GENERIC::makeLibParts() { XNODE* xlibparts = node( wxT( "libparts" ) ); // auto_ptr wxString sLibpart = wxT( "libpart" ); wxString sLib = wxT( "lib" ); wxString sPart = wxT( "part" ); wxString sAliases = wxT( "aliases" ); wxString sAlias = wxT( "alias" ); wxString sPins = wxT( "pins" ); // key for library component pins list wxString sPin = wxT( "pin" ); // key for one library component pin descr wxString sPinNum = wxT( "num" ); // key for one library component pin num wxString sPinName = wxT( "name" ); // key for one library component pin name wxString sPinType = wxT( "type" ); // key for one library component pin electrical type wxString sName = wxT( "name" ); wxString sField = wxT( "field" ); wxString sFields = wxT( "fields" ); wxString sDescr = wxT( "description" ); wxString sDocs = wxT( "docs" ); wxString sFprints = wxT( "footprints" ); wxString sFp = wxT( "fp" ); LIB_PINS pinList; LIB_FIELDS fieldList; m_Libraries.clear(); for( std::set<LIB_PART*>::iterator it = m_LibParts.begin(); it!=m_LibParts.end(); ++it ) { LIB_PART* lcomp = *it; PART_LIB* library = lcomp->GetLib(); m_Libraries.insert( library ); // inserts component's library if unique XNODE* xlibpart; xlibparts->AddChild( xlibpart = node( sLibpart ) ); xlibpart->AddAttribute( sLib, library->GetLogicalName() ); xlibpart->AddAttribute( sPart, lcomp->GetName() ); if( lcomp->GetAliasCount() ) { wxArrayString aliases = lcomp->GetAliasNames( false ); if( aliases.GetCount() ) { XNODE* xaliases = node( sAliases ); xlibpart->AddChild( xaliases ); for( unsigned i=0; i<aliases.GetCount(); ++i ) { xaliases->AddChild( node( sAlias, aliases[i] ) ); } } } //----- show the important properties ------------------------- if( !lcomp->GetAlias( 0 )->GetDescription().IsEmpty() ) xlibpart->AddChild( node( sDescr, lcomp->GetAlias( 0 )->GetDescription() ) ); if( !lcomp->GetAlias( 0 )->GetDocFileName().IsEmpty() ) xlibpart->AddChild( node( sDocs, lcomp->GetAlias( 0 )->GetDocFileName() ) ); // Write the footprint list if( lcomp->GetFootPrints().GetCount() ) { XNODE* xfootprints; xlibpart->AddChild( xfootprints = node( sFprints ) ); for( unsigned i=0; i<lcomp->GetFootPrints().GetCount(); ++i ) { xfootprints->AddChild( node( sFp, lcomp->GetFootPrints()[i] ) ); } } //----- show the fields here ---------------------------------- fieldList.clear(); lcomp->GetFields( fieldList ); XNODE* xfields; xlibpart->AddChild( xfields = node( sFields ) ); for( unsigned i=0; i<fieldList.size(); ++i ) { if( !fieldList[i].GetText().IsEmpty() ) { XNODE* xfield; xfields->AddChild( xfield = node( sField, fieldList[i].GetText() ) ); xfield->AddAttribute( sName, fieldList[i].GetName(false) ); } } //----- show the pins here ------------------------------------ pinList.clear(); lcomp->GetPins( pinList, 0, 0 ); /* we must erase redundant Pins references in pinList * These redundant pins exist because some pins * are found more than one time when a component has * multiple parts per package or has 2 representations (DeMorgan conversion) * For instance, a 74ls00 has DeMorgan conversion, with different pin shapes, * and therefore each pin appears 2 times in the list. * Common pins (VCC, GND) can also be found more than once. */ sort( pinList.begin(), pinList.end(), sortPinsByNumber ); for( int ii = 0; ii < (int)pinList.size()-1; ii++ ) { if( pinList[ii]->GetNumber() == pinList[ii+1]->GetNumber() ) { // 2 pins have the same number, remove the redundant pin at index i+1 pinList.erase(pinList.begin() + ii + 1); ii--; } } if( pinList.size() ) { XNODE* pins; xlibpart->AddChild( pins = node( sPins ) ); for( unsigned i=0; i<pinList.size(); ++i ) { XNODE* pin; pins->AddChild( pin = node( sPin ) ); pin->AddAttribute( sPinNum, pinList[i]->GetNumberString() ); pin->AddAttribute( sPinName, pinList[i]->GetName() ); pin->AddAttribute( sPinType, pinList[i]->GetCanonicalElectricalTypeName() ); // caution: construction work site here, drive slowly } } } return xlibparts; }