32#include <wx/filename.h>
34#include <wx/tokenzr.h>
35#include <wx/wfstream.h>
36#include <wx/txtstrm.h>
37#include <wx/xml/xml.h>
91static int countChildren( wxXmlNode* aCurrentNode,
const wxString& aName )
97 aCurrentNode = aCurrentNode->GetChildren();
101 if( aCurrentNode->GetName() == aName )
105 aCurrentNode = aCurrentNode->GetNext();
118 bbox.
Merge( item->GetBoundingBox() );
127 return aPinName.BeforeFirst(
'@' );
140 wxCHECK( currentSheet,
nullptr );
184 std::vector<ELAYER> eagleLayers;
187 wxXmlNode* layerNode = aLayers->GetChildren();
191 ELAYER elayer( layerNode );
192 eagleLayers.push_back( elayer );
194 layerNode = layerNode->GetNext();
198 for(
const ELAYER& elayer : eagleLayers )
217 if( elayer.name == wxT(
"Nets" ) )
219 else if( elayer.name == wxT(
"Info" ) || elayer.name == wxT(
"Guide" ) )
221 else if( elayer.name == wxT(
"Busses" ) )
237 int roti = int( eagleDegrees );
247 wxASSERT_MSG(
false, wxString::Format( wxT(
"Unhandled orientation (%d degrees)" ),
256 bool aMirror,
bool aSpin,
int aAbsDegress )
258 int align = aEagleAlignment;
260 if( aRelDegress == 90 )
264 else if( aRelDegress == 180 )
266 else if( aRelDegress == 270 )
272 if( aMirror ==
true )
274 if( aAbsDegress == 90 || aAbsDegress == 270 )
285 else if( aAbsDegress == 0 || aAbsDegress == 180 )
359 m_lastProgressCount( 0 ),
382 const unsigned PROGRESS_DELTA = 5;
404 wxASSERT( !aFileName || aSchematic !=
nullptr );
422 unique_ptr<SCH_SHEET> deleter( aAppendToMe ?
nullptr :
m_rootSheet );
429 wxCHECK_MSG( aSchematic->
IsValid(),
nullptr,
430 wxT(
"Can't append to a schematic with no root!" ) );
453 wxCHECK_MSG( libTable,
nullptr, wxT(
"Could not load symbol lib table." ) );
455 m_pi.reset( SCH_IO_MGR::FindPlugin( SCH_IO_MGR::SCH_KICAD ) );
465 wxString libTableUri = wxT(
"${KIPRJMOD}/" ) +
getLibFileName().GetFullName();
478 libTable->
Format( &formatter, 0 );
487 wxXmlNode* currentNode = xmlDocument.GetRoot();
491 m_version = currentNode->GetAttribute( wxT(
"version" ), wxT(
"0.0" ) );
509 const wxString& aLibraryPath,
521 for(
const auto& [symName, libSymbol] : it->second.KiCadSymbols )
522 aSymbolNameList.push_back( symName );
528 const wxString& aLibraryPath,
540 for(
const auto& [symName, libSymbol] : it->second.KiCadSymbols )
541 aSymbolList.push_back( libSymbol );
558 auto it2 = it->second.KiCadSymbols.find( aAliasName );
560 if( it2 != it->second.KiCadSymbols.end() )
570 wxFileName fn( aLibraryPath );
572 if( fn.IsFileReadable() && fn.GetModificationTime().IsValid() )
573 return fn.GetModificationTime().GetValue().GetValue();
575 return wxDateTime( 0.0 ).GetValue().GetValue();
603 wxXmlNode* currentNode = xmlDocument.GetRoot();
607 m_version = currentNode->GetAttribute( wxT(
"version" ), wxT(
"0.0" ) );
622 wxXmlDocument xmlDocument;
623 wxFFileInputStream stream(
m_filename.GetFullPath() );
628 wxString::Format(
_(
"Unable to read file '%s'." ),
m_filename.GetFullPath() ) );
632 wxTextInputStream
text( stream );
633 wxString line =
text.ReadLine();
635 if( !line.StartsWith( wxT(
"<?xml" ) ) && !line.StartsWith( wxT(
"<!--" ) ) )
637 THROW_IO_ERROR( wxString::Format(
_(
"'%s' is an Eagle binary-format file; "
638 "only Eagle XML-format files can be imported." ),
642 if( !xmlDocument.Load( stream ) )
645 wxString::Format(
_(
"Unable to read file '%s'." ),
m_filename.GetFullPath() ) );
662 auto layers = drawingChildren[
"layers"];
667 wxXmlNode* libraryNode = drawingChildren[
"library"];
680 auto schematic = drawingChildren[
"schematic"];
693 wxXmlNode* sheetNode =
getChildrenNodes( schematicChildren, wxT(
"sheets" ) );
705 wxString netName = netNode->GetAttribute( wxT(
"name" ) );
713 netNode = netNode->GetNext();
716 sheetNode = sheetNode->GetNext();
725 wxXmlNode* partNode =
getChildrenNodes( schematicChildren, wxT(
"parts" ) );
726 wxXmlNode* libraryNode =
getChildrenNodes( schematicChildren, wxT(
"libraries" ) );
727 wxXmlNode* sheetNode =
getChildrenNodes( schematicChildren, wxT(
"sheets" ) );
733 []( wxXmlNode* aNode ) ->
unsigned
740 aNode = aNode->GetNext();
756 wxXmlNode* devicesetNode =
getChildrenNodes( libraryChildren, wxT(
"devicesets" ) );
758 while( devicesetNode )
761 wxXmlNode* deviceNode =
getChildrenNodes( deviceSetChildren, wxT(
"devices" ) );
762 wxXmlNode* gateNode =
getChildrenNodes( deviceSetChildren, wxT(
"gates" ) );
764 m_totalCount += count_nodes( deviceNode ) * count_nodes( gateNode );
766 devicesetNode = devicesetNode->GetNext();
769 libraryNode = libraryNode->GetNext();
784 sheetNode = sheetNode->GetNext();
795 std::unique_ptr<EPART> epart = std::make_unique<EPART>( partNode );
798 m_partlist[epart->name.Upper()] = std::move( epart );
799 partNode = partNode->GetNext();
807 wxString libName = libraryNode->GetAttribute( wxT(
"name" ) );
810 elib->
name = libName;
814 libraryNode = libraryNode->GetNext();
828 int sheetCount =
countChildren( sheetNode->GetParent(), wxT(
"sheet" ) );
844 std::unique_ptr<SCH_SHEET> sheet = std::make_unique<SCH_SHEET>(
m_rootSheet, pos );
846 sheet->SetScreen( screen );
849 wxCHECK2( sheet && screen,
continue );
851 wxString pageNo = wxString::Format( wxT(
"%d" ), i );
861 wxCHECK2( currentScreen,
continue );
863 currentScreen->
Append( sheet.release() );
865 sheetNode = sheetNode->GetNext();
883 sheetNode = sheetNode->GetNext();
895 int maxY = sheetBbox.
GetY();
902 const SCH_SYMBOL* origSymbol = cmp.second.cmp;
904 for(
auto& unitEntry : cmp.second.units )
906 if( unitEntry.second ==
false )
910 int unit = unitEntry.first;
914 symbol->SetUnitSelection( &sheetpath, unit );
915 symbol->SetUnit( unit );
916 symbol->SetOrientation( 0 );
917 symbol->AddHierarchicalReference( sheetpath.
Path(), reference, unit );
920 BOX2I cmpBbox = symbol->GetBoundingBox();
921 int posY = newCmpPosition.
y + cmpBbox.
GetHeight();
922 symbol->SetPosition(
VECTOR2I( newCmpPosition.
x, posY ) );
924 maxY = std::max( maxY, posY );
926 if( newCmpPosition.
x >= pageSizeIU.
x )
945 wxXmlNode* descriptionNode =
getChildrenNodes( sheetChildren, wxT(
"description" ) );
952 std::string filename;
956 if( descriptionNode )
958 des = descriptionNode->GetContent();
959 des.Replace( wxT(
"\n" ), wxT(
"_" ),
true );
961 filename = des.ToStdString();
965 filename = wxString::Format( wxT(
"%s_%d" ),
m_filename.GetName(), aSheetIndex );
966 sheetNameField.
SetText( filename );
970 replace( filename.begin(), filename.end(),
' ',
'_' );
973 fn.SetName( filename );
976 filenameField.
SetText( fn.GetFullName() );
986 wxXmlNode* instanceNode =
getChildrenNodes( sheetChildren, wxT(
"instances" ) );
988 while( instanceNode )
993 instanceNode = instanceNode->GetNext();
1013 busNode = busNode->GetNext();
1025 wxString netName = netNode->GetAttribute( wxT(
"name" ) );
1026 wxString netClass = netNode->GetAttribute( wxT(
"class" ) );
1032 netNode = netNode->GetNext();
1056 wxString nodeName = plainNode->GetName();
1058 if( nodeName == wxT(
"polygon" ) )
1062 else if( nodeName == wxT(
"wire" ) )
1067 else if( nodeName == wxT(
"text" ) )
1071 else if( nodeName == wxT(
"circle" ) )
1075 else if( nodeName == wxT(
"rectangle" ) )
1079 else if( nodeName == wxT(
"frame" ) )
1081 std::vector<SCH_ITEM*> frameItems;
1089 plainNode = plainNode->GetNext();
1102 if( pageSizeIU.
x < targetSheetSize.
x )
1105 if( pageSizeIU.
y < targetSheetSize.
y )
1112 VECTOR2I sheetcentre( pageSizeIU.
x / 2, pageSizeIU.
y / 2 );
1116 VECTOR2I translation = sheetcentre - itemsCentre;
1130 std::vector<SCH_ITEM*> allItems;
1132 std::copy( screen->
Items().
begin(), screen->
Items().
end(), std::back_inserter( allItems ) );
1136 item->SetPosition( item->GetPosition() + translation );
1141 label->AutoplaceFields( screen,
false );
1152 EFRAME eframe( aFrameNode );
1160 std::swap( xMin, xMax );
1163 std::swap( yMin, yMax );
1171 aItems.push_back( lines );
1180 aItems.push_back( lines );
1183 int height = yMax - yMin;
1187 double rowSpacing = height / double( eframe.
rows );
1188 double legendPosY = yMin + ( rowSpacing / 2 );
1190 for( i = 1; i < eframe.
rows; i++ )
1192 int newY =
KiROUND( yMin + ( rowSpacing * (
double) i ) );
1196 aItems.push_back( lines );
1199 char legendChar =
'A';
1201 for( i = 0; i < eframe.
rows; i++ )
1207 legendText->
SetText( wxString( legendChar ) );
1210 aItems.push_back( legendText );
1212 legendPosY += rowSpacing;
1223 aItems.push_back( lines );
1226 int height = yMax - yMin;
1230 double rowSpacing = height / double( eframe.
rows );
1231 double legendPosY = yMin + ( rowSpacing / 2 );
1233 for( i = 1; i < eframe.
rows; i++ )
1235 int newY =
KiROUND( yMin + ( rowSpacing * (
double) i ) );
1239 aItems.push_back( lines );
1242 char legendChar =
'A';
1244 for( i = 0; i < eframe.
rows; i++ )
1250 legendText->
SetText( wxString( legendChar ) );
1253 aItems.push_back( legendText );
1255 legendPosY += rowSpacing;
1266 aItems.push_back( lines );
1269 int width = xMax - xMin;
1273 double columnSpacing = width / double( eframe.
columns );
1274 double legendPosX = xMin + ( columnSpacing / 2 );
1276 for( i = 1; i < eframe.
columns; i++ )
1278 int newX =
KiROUND( xMin + ( columnSpacing * (
double) i ) );
1282 aItems.push_back( lines );
1285 char legendChar =
'1';
1287 for( i = 0; i < eframe.
columns; i++ )
1293 legendText->
SetText( wxString( legendChar ) );
1296 aItems.push_back( legendText );
1298 legendPosX += columnSpacing;
1309 aItems.push_back( lines );
1312 int width = xMax - xMin;
1316 double columnSpacing = width / double( eframe.
columns );
1317 double legendPosX = xMin + ( columnSpacing / 2 );
1319 for( i = 1; i < eframe.
columns; i++ )
1321 int newX =
KiROUND( xMin + ( columnSpacing * (
double) i ) );
1325 aItems.push_back( lines );
1328 char legendChar =
'1';
1330 for( i = 0; i < eframe.
columns; i++ )
1336 legendText->
SetText( wxString( legendChar ) );
1339 aItems.push_back( legendText );
1341 legendPosX += columnSpacing;
1348 const wxString& aNetClass )
1351 wxXmlNode* currentSegment = aSegmentsNode->GetChildren();
1356 int segmentCount =
countChildren( aSegmentsNode, wxT(
"segment" ) );
1358 while( currentSegment )
1360 bool labelled =
false;
1362 bool firstWireFound =
false;
1368 wxXmlNode* segmentAttribute = currentSegment->GetChildren();
1370 while( segmentAttribute )
1372 if( segmentAttribute->GetName() == wxT(
"wire" ) )
1381 if( !firstWireFound )
1383 firstWire = thisWire;
1384 firstWireFound =
true;
1390 if( !desc.labels.empty() && desc.labels.front()->GetText() == netName )
1393 for(
const SEG& seg : desc.segs )
1402 segDesc.
segs.push_back( thisWire );
1406 segmentAttribute = segmentAttribute->GetNext();
1409 segmentAttribute = currentSegment->GetChildren();
1411 while( segmentAttribute )
1413 wxString nodeName = segmentAttribute->GetName();
1415 if( nodeName == wxT(
"junction" ) )
1419 else if( nodeName == wxT(
"label" ) )
1423 wxASSERT( segDesc.
labels.empty()
1425 segDesc.
labels.push_back( label );
1428 else if( nodeName == wxT(
"pinref" ) )
1430 segmentAttribute->GetAttribute( wxT(
"gate" ) );
1431 wxString part = segmentAttribute->GetAttribute( wxT(
"part" ) );
1432 wxString
pin = segmentAttribute->GetAttribute( wxT(
"pin" ) );
1434 auto powerPort =
m_powerPorts.find( wxT(
"#" ) + part );
1442 else if( nodeName == wxT(
"wire" ) )
1452 segmentAttribute = segmentAttribute->GetNext();
1458 if( !labelled && firstWireFound )
1460 std::unique_ptr<SCH_LABEL_BASE> label;
1465 else if( segmentCount > 1 )
1470 label->SetPosition( firstWire.
A );
1475 if( firstWire.
B.
x > firstWire.
A.
x )
1480 screen->
Append( label.release() );
1484 currentSegment = currentSegment->GetNext();
1491 std::unique_ptr<SCH_SHAPE> poly = std::make_unique<SCH_SHAPE>( SHAPE_T::POLY );
1493 wxXmlNode* vertex = aPolygonNode->GetChildren();
1499 if( vertex->GetName() == wxT(
"vertex" ) )
1508 poly->GetPolyShape().Append( arc, -1, -1,
ARC_ACCURACY );
1512 poly->AddPoint( pt );
1516 prev_curve = evertex.
curve;
1519 vertex = vertex->GetNext();
1524 poly->SetFillMode( FILL_T::FILLED_SHAPE );
1526 return poly.release();
1542 endpoints =
SEG( start, end );
1546 std::unique_ptr<SCH_SHAPE> arc = std::make_unique<SCH_SHAPE>( SHAPE_T::ARC );
1549 arc->SetCenter( center );
1550 arc->SetStart( start );
1557 return arc.release();
1561 std::unique_ptr<SCH_LINE> line = std::make_unique<SCH_LINE>();
1563 line->SetStartPoint( start );
1564 line->SetEndPoint( end );
1568 return line.release();
1575 std::unique_ptr<SCH_SHAPE> circle = std::make_unique<SCH_SHAPE>( SHAPE_T::CIRCLE );
1580 circle->SetPosition( center );
1584 return circle.release();
1590 std::unique_ptr<SCH_SHAPE> rectangle = std::make_unique<SCH_SHAPE>( SHAPE_T::RECTANGLE );
1591 ERECT rect( aRectNode );
1599 VECTOR2I pos( rectangle->GetPosition() );
1600 VECTOR2I end( rectangle->GetEnd() );
1601 VECTOR2I center( rectangle->GetCenter() );
1606 rectangle->SetPosition( pos );
1607 rectangle->SetEnd( end );
1611 rectangle->SetFillMode( FILL_T::FILLED_SHAPE );
1613 return rectangle.release();
1619 std::unique_ptr<SCH_JUNCTION> junction = std::make_unique<SCH_JUNCTION>();
1624 junction->SetPosition( pos );
1626 return junction.release();
1638 std::unique_ptr<SCH_LABEL_BASE> label;
1644 label = std::make_unique<SCH_GLOBALLABEL>();
1646 label = std::make_unique<SCH_LABEL>();
1648 label->SetPosition( elabelpos );
1650 label->SetTextSize( textSize );
1656 label->Rotate90(
false );
1659 label->MirrorSpinStyle(
false );
1662 return label.release();
1666std::pair<VECTOR2I, const SEG*>
1668 const std::vector<SEG>& aLines )
const
1671 const SEG* nearestLine =
nullptr;
1673 float d, mindistance = std::numeric_limits<float>::max();
1676 for(
const SEG& line : aLines )
1679 d = sqrt(
abs( ( ( aPoint.
x - testpoint.
x ) ^ 2 ) + ( ( aPoint.
y - testpoint.
y ) ^ 2 ) ) );
1681 if( d < mindistance )
1684 nearestPoint = testpoint;
1685 nearestLine = &line;
1688 testpoint = line.Center();
1689 d = sqrt(
abs( ( ( aPoint.
x - testpoint.
x ) ^ 2 ) + ( ( aPoint.
y - testpoint.
y ) ^ 2 ) ) );
1691 if( d < mindistance )
1694 nearestPoint = testpoint;
1695 nearestLine = &line;
1699 d = sqrt(
abs( ( ( aPoint.
x - testpoint.
x ) ^ 2 ) + ( ( aPoint.
y - testpoint.
y ) ^ 2 ) ) );
1701 if( d < mindistance )
1704 nearestPoint = testpoint;
1705 nearestLine = &line;
1709 return std::make_pair( nearestPoint, nearestLine );
1728 m_reporter->
Report( wxString::Format(
_(
"Error parsing Eagle file. Could not find '%s' "
1729 "instance but it is referenced in the schematic." ),
1736 EPART* epart = part_it->second.get();
1738 wxString libraryname = epart->
library;
1741 symbolname.Replace( wxT(
"*" ), wxEmptyString );
1749 wxString altSymbolName = libraryname + wxT(
"_" ) + symbolname;
1752 wxString libIdSymbolName = altSymbolName;
1754 int unit =
m_eagleLibs[libraryname].GateUnit[gatename];
1759 auto p = elib->
package.find( kisymbolname );
1761 if( p != elib->
package.end() )
1762 package = p->second;
1764 LIB_SYMBOL* part = m_pi->LoadSymbol( getLibFileName().GetFullPath(), altSymbolName,
1765 m_properties.get() );
1769 part = m_pi->LoadSymbol( getLibFileName().GetFullPath(), kisymbolname,
1770 m_properties.get() );
1771 libIdSymbolName = kisymbolname;
1776 m_reporter->Report( wxString::Format(
_(
"Could not find '%s' in the imported library." ),
1782 LIB_ID libId( getLibName(), libIdSymbolName );
1783 std::unique_ptr<SCH_SYMBOL> symbol = std::make_unique<SCH_SYMBOL>();
1784 symbol->SetLibId( libId );
1785 symbol->SetUnit( unit );
1789 if( !package.IsEmpty() )
1791 wxString footprint = m_schematic->Prj().GetProjectName() + wxT(
":" ) + package;
1800 symbol->MirrorHorizontally( einstance.
x.
ToSchUnits() );
1803 std::vector<SCH_FIELD*> partFields;
1806 for(
const SCH_FIELD* field : partFields )
1808 symbol->GetFieldById( field->GetId() )->ImportValues( *field );
1809 symbol->GetFieldById( field->GetId() )->SetTextPos( (
VECTOR2I)symbol->GetPosition()
1810 + field->GetTextPos() );
1815 wxString reference = package.IsEmpty() ?
'#' + einstance.
part : einstance.
part;
1818 if( reference.find_last_not_of( wxT(
"0123456789" ) ) == ( reference.Length()-1 ) )
1819 reference.Append( wxT(
"0" ) );
1824 if( reference.find_first_not_of( wxT(
"0123456789" ) ) != 0 )
1825 reference.Prepend( wxT(
"UNK" ) );
1829 if( einstance.
part.find_first_not_of( wxT(
"#" ) ) != 0 )
1830 reference.Prepend( wxT(
"UNK" ) );
1833 referenceField->
SetText( reference );
1837 bool userValue = m_userValue.at( libIdSymbolName );
1841 if( !userValue && epart->
value )
1847 valueField->
SetText( kisymbolname );
1853 for(
const auto& [ attrName, attrValue ] : epart->
attribute )
1856 SCH_FIELD* lastField = symbol->GetFieldById( symbol->GetFieldCount() - 1 );
1861 SCH_FIELD newField( newFieldPosition, symbol->GetFieldCount(), symbol.get() );
1864 newField.
SetText( attrValue );
1867 symbol->AddField( newField );
1870 for(
const auto& a : epart->
variant )
1873 field->
SetName( wxT(
"VARIANT_" ) + wxString( a.first ) );
1878 bool valueAttributeFound =
false;
1879 bool nameAttributeFound =
false;
1881 wxXmlNode* attributeNode = aInstanceNode->GetChildren();
1884 while( attributeNode )
1886 if( attributeNode->GetName() == wxT(
"attribute" ) )
1891 if( attr.
name.Lower() == wxT(
"name" ) )
1894 nameAttributeFound =
true;
1896 else if( attr.
name.Lower() == wxT(
"value" ) )
1899 valueAttributeFound =
true;
1903 field = symbol->FindField( attr.
name );
1919 bool spin = attr.
rot ? attr.
rot->
spin :
false;
1925 int reldegrees = ( absdegrees - rotation + 360.0 );
1932 else if( attributeNode->GetName() == wxT(
"variant" ) )
1934 wxString variantName, fieldValue;
1936 if( attributeNode->GetAttribute( wxT(
"name" ), &variantName )
1937 && attributeNode->GetAttribute( wxT(
"value" ), &fieldValue ) )
1940 field.
SetName( wxT(
"VARIANT_" ) + variantName );
1943 symbol->AddField( field );
1947 attributeNode = attributeNode->GetNext();
1953 if( !valueAttributeFound )
1954 symbol->GetField(
VALUE_FIELD )->SetVisible(
false );
1956 if( !nameAttributeFound )
1960 symbol->AddHierarchicalReference( m_sheetPath.Path(), reference, unit );
1966 wxCHECK( libSymbol, );
1968 symbol->SetLibSymbol(
new LIB_SYMBOL( *libSymbol ) );
1970 for(
const SCH_PIN*
pin : symbol->GetLibPins() )
1971 m_connPoints[symbol->GetPinPhysicalPosition(
pin )].emplace(
pin );
1974 m_powerPorts[ reference ] = symbol->GetField(
VALUE_FIELD )->GetText();
1976 symbol->ClearFlags();
1978 screen->
Append( symbol.release() );
1987 wxXmlNode* symbolNode =
getChildrenNodes( libraryChildren, wxT(
"symbols" ) );
1991 wxString symbolName = symbolNode->GetAttribute( wxT(
"name" ) );
1992 aEagleLibrary->
SymbolNodes[symbolName] = symbolNode;
1993 symbolNode = symbolNode->GetNext();
1997 wxXmlNode* devicesetNode =
getChildrenNodes( libraryChildren, wxT(
"devicesets" ) );
1999 while( devicesetNode )
2004 wxString prefix = edeviceset.
prefix ? edeviceset.
prefix.
Get() : wxString( wxT(
"" ) );
2005 wxString deviceSetDescr;
2008 wxXmlNode* deviceNode =
getChildrenNodes( deviceSetChildren, wxT(
"devices" ) );
2009 wxXmlNode* deviceSetDescrNode =
getChildrenNodes( deviceSetChildren, wxT(
"description" ) );
2011 if( deviceSetDescrNode )
2021 wxString symbolName = edeviceset.
name + edevice.
name;
2022 symbolName.Replace( wxT(
"*" ), wxEmptyString );
2023 wxASSERT( !symbolName.IsEmpty() );
2030 std::unique_ptr<LIB_SYMBOL> libSymbol = std::make_unique<LIB_SYMBOL>( symbolName );
2033 wxXmlNode* gateNode =
getChildrenNodes( deviceSetChildren, wxT(
"gates" ) );
2034 int gates_count =
countChildren( deviceSetChildren[
"gates"], wxT(
"gate" ) );
2035 libSymbol->SetUnitCount( gates_count );
2036 libSymbol->LockUnits(
true );
2040 if( prefix.length() == 0 )
2052 bool ispower =
false;
2062 gateindex, egate.
name );
2065 gateNode = gateNode->GetNext();
2068 libSymbol->SetUnitCount( gates_count );
2070 if( gates_count == 1 && ispower )
2071 libSymbol->SetPower();
2088 wxString packageString = libName + wxT(
":" ) + aEagleLibrary->
package[symbolName];
2090 libSymbol->GetFootprintField().SetText( packageString );
2093 wxString libName = libSymbol->GetName();
2094 libSymbol->SetName( libName );
2095 libSymbol->SetDescription( deviceSetDescr );
2103 libName = aEagleLibrary->
name + wxT(
"_" ) + libName;
2105 libSymbol->SetName( libName );
2112 aEagleLibrary->
KiCadSymbols.insert( libName, libSymbol.release() );
2119 deviceNode = deviceNode->GetNext();
2122 devicesetNode = devicesetNode->GetNext();
2125 return aEagleLibrary;
2130 EDEVICE* aDevice,
int aGateNumber,
const wxString& aGateName )
2132 wxString symbolName = aSymbolNode->GetAttribute( wxT(
"name" ) );
2133 std::vector<SCH_ITEM*> items;
2135 wxXmlNode* currentNode = aSymbolNode->GetChildren();
2137 bool showRefDes =
false;
2138 bool showValue =
false;
2139 bool ispower =
false;
2142 while( currentNode )
2144 wxString nodeName = currentNode->GetName();
2146 if( nodeName == wxT(
"circle" ) )
2150 else if( nodeName == wxT(
"pin" ) )
2153 std::unique_ptr<SCH_PIN>
pin(
loadPin( aSymbol, currentNode, &ePin, aGateNumber ) );
2156 pin->SetType( ELECTRICAL_PINTYPE::PT_BIDI );
2162 if( ePin.
direction->Lower() == pinDir.first )
2164 pin->SetType( pinDir.second );
2166 if( pinDir.first == wxT(
"sup" ) )
2174 if( aDevice->
connects.size() != 0 )
2178 if( connect.
gate == aGateName &&
pin->GetName() == connect.
pin )
2180 wxArrayString pads = wxSplit( wxString( connect.
pad ),
' ' );
2182 pin->SetUnit( aGateNumber );
2185 if( pads.GetCount() > 1 )
2187 pin->SetNumberTextSize( 0 );
2190 for(
unsigned i = 0; i < pads.GetCount(); i++ )
2194 wxString padname( pads[i] );
2196 aSymbol->AddDrawItem( apin );
2205 pin->SetUnit( aGateNumber );
2206 pin->SetNumber( wxString::Format( wxT(
"%i" ), pincount ) );
2207 aSymbol->AddDrawItem(
pin.release() );
2210 else if( nodeName == wxT(
"polygon" ) )
2214 else if( nodeName == wxT(
"rectangle" ) )
2218 else if( nodeName == wxT(
"text" ) )
2220 std::unique_ptr<SCH_TEXT> libtext(
loadSymbolText( currentNode, aGateNumber ) );
2222 if( libtext->GetText() == wxT(
"${REFERENCE}" ) )
2229 showRefDes = currentNode->GetNodeContent() == wxT(
">NAME" );
2231 else if( libtext->GetText() == wxT(
"${VALUE}" ) )
2238 showValue = currentNode->GetNodeContent() == wxT(
">VALUE" );
2242 aSymbol->AddDrawItem( libtext.release() );
2245 else if( nodeName == wxT(
"wire" ) )
2247 aSymbol->AddDrawItem(
loadSymbolWire( currentNode, aGateNumber ) );
2249 else if( nodeName == wxT(
"frame" ) )
2251 std::vector<SCH_ITEM*> frameItems;
2257 item->SetParent( aSymbol.get() );
2258 item->SetUnit( aGateNumber );
2259 aSymbol->AddDrawItem( item );
2272 currentNode = currentNode->GetNext();
2279 aSymbol->GetFieldById(
VALUE_FIELD )->SetVisible(
false );
2281 return pincount == 1 ? ispower :
false;
2295 circle->
SetUnit( aGateNumber );
2303 ERECT rect( aRectNode );
2319 rectangle->
SetEnd( end );
2322 rectangle->
SetUnit( aGateNumber );
2350 double radius = sqrt( ( ( center.
x - begin.
x ) * ( center.
x - begin.
x ) ) +
2351 ( ( center.
y - begin.
y ) * ( center.
y - begin.
y ) ) );
2357 begin = center + centerStartVector;
2392 wxXmlNode* vertex = aPolygonNode->GetChildren();
2398 if( vertex->GetName() == wxT(
"vertex" ) )
2415 prev_curve = evertex.
curve;
2418 vertex = vertex->GetNext();
2430 EPIN* aEPin,
int aGateNumber )
2432 std::unique_ptr<SCH_PIN>
pin = std::make_unique<SCH_PIN>( aSymbol.get() );
2435 pin->SetUnit( aGateNumber );
2441 case 0:
pin->SetOrientation( PIN_ORIENTATION::PIN_RIGHT );
break;
2442 case 90:
pin->SetOrientation( PIN_ORIENTATION::PIN_UP );
break;
2443 case 180:
pin->SetOrientation( PIN_ORIENTATION::PIN_LEFT );
break;
2444 case 270:
pin->SetOrientation( PIN_ORIENTATION::PIN_DOWN );
break;
2445 default: wxFAIL_MSG( wxString::Format( wxT(
"Unhandled orientation (%d degrees)." ), roti ) );
2454 if( length == wxT(
"short" ) )
2456 else if( length == wxT(
"middle" ) )
2458 else if( length == wxT(
"long" ) )
2460 else if( length == wxT(
"point" ) )
2469 if( visible == wxT(
"off" ) )
2471 pin->SetNameTextSize( 0 );
2472 pin->SetNumberTextSize( 0 );
2474 else if( visible == wxT(
"pad" ) )
2476 pin->SetNameTextSize( 0 );
2478 else if( visible == wxT(
"pin" ) )
2480 pin->SetNumberTextSize( 0 );
2494 if( function == wxT(
"dot" ) )
2495 pin->SetShape( GRAPHIC_PINSHAPE::INVERTED );
2496 else if( function == wxT(
"clk" ) )
2497 pin->SetShape( GRAPHIC_PINSHAPE::CLOCK );
2498 else if( function == wxT(
"dotclk" ) )
2499 pin->SetShape( GRAPHIC_PINSHAPE::INVERTED_CLOCK );
2502 return pin.release();
2508 ETEXT etext( aLibText );
2510 const wxString& eagleText = aLibText->GetNodeContent();
2511 wxString adjustedText;
2512 wxStringTokenizer tokenizer( eagleText,
"\r\n" );
2515 while( tokenizer.HasMoreTokens() )
2517 wxString tmp =
interpretText( tokenizer.GetNextToken().Trim(
true ).Trim(
false ) );
2519 if( tokenizer.HasMoreTokens() )
2522 adjustedText += tmp;
2525 if( adjustedText.IsEmpty() )
2526 adjustedText = wxT(
"~" );
2528 auto libtext = std::make_unique<SCH_TEXT>( pos, adjustedText,
LAYER_DEVICE );
2530 libtext->SetUnit( aGateNumber );
2533 return libtext.release();
2539 EFRAME eframe( aFrameNode );
2547 std::swap( xMin, xMax );
2550 std::swap( yMin, yMax );
2558 aItems.push_back( lines );
2567 aItems.push_back( lines );
2570 int height = yMax - yMin;
2574 double rowSpacing = height / double( eframe.
rows );
2575 double legendPosY = yMax - ( rowSpacing / 2 );
2577 for( i = 1; i < eframe.
rows; i++ )
2579 int newY =
KiROUND( yMin + ( rowSpacing * (
double) i ) );
2583 aItems.push_back( lines );
2586 char legendChar =
'A';
2588 for( i = 0; i < eframe.
rows; i++ )
2594 aItems.push_back( legendText );
2596 legendPosY -= rowSpacing;
2607 aItems.push_back( lines );
2610 int height = yMax - yMin;
2614 double rowSpacing = height / double( eframe.
rows );
2615 double legendPosY = yMax - ( rowSpacing / 2 );
2617 for( i = 1; i < eframe.
rows; i++ )
2619 int newY =
KiROUND( yMin + ( rowSpacing * (
double) i ) );
2623 aItems.push_back( lines );
2626 char legendChar =
'A';
2628 for( i = 0; i < eframe.
rows; i++ )
2634 aItems.push_back( legendText );
2636 legendPosY -= rowSpacing;
2647 aItems.push_back( lines );
2650 int width = xMax - xMin;
2654 double columnSpacing = width / double( eframe.
columns );
2655 double legendPosX = xMin + ( columnSpacing / 2 );
2657 for( i = 1; i < eframe.
columns; i++ )
2659 int newX =
KiROUND( xMin + ( columnSpacing * (
double) i ) );
2663 aItems.push_back( lines );
2666 char legendChar =
'1';
2668 for( i = 0; i < eframe.
columns; i++ )
2674 aItems.push_back( legendText );
2676 legendPosX += columnSpacing;
2687 aItems.push_back( lines );
2690 int width = xMax - xMin;
2694 double columnSpacing = width / double( eframe.
columns );
2695 double legendPosX = xMin + ( columnSpacing / 2 );
2697 for( i = 1; i < eframe.
columns; i++ )
2699 int newX =
KiROUND( xMin + ( columnSpacing * (
double) i ) );
2703 aItems.push_back( lines );
2706 char legendChar =
'1';
2708 for( i = 0; i < eframe.
columns; i++ )
2714 aItems.push_back( legendText );
2716 legendPosX += columnSpacing;
2724 std::unique_ptr<SCH_TEXT> schtext = std::make_unique<SCH_TEXT>();
2727 const wxString& eagleText = aSchText->GetNodeContent();
2728 wxString adjustedText;
2729 wxStringTokenizer tokenizer( eagleText,
"\r\n" );
2732 while( tokenizer.HasMoreTokens() )
2734 wxString tmp =
interpretText( tokenizer.GetNextToken().Trim(
true ).Trim(
false ) );
2736 if( tokenizer.HasMoreTokens() )
2739 adjustedText += tmp;
2742 schtext->SetText( adjustedText.IsEmpty() ? wxString( wxT(
"\" \"" ) ) :
escapeName( adjustedText ) );
2745 schtext->SetItalic(
false );
2747 return schtext.release();
2761 bool mirror = aAttribs.
rot ? aAttribs.
rot->
mirror :
false;
2762 bool spin = aAttribs.
rot ? aAttribs.
rot->
spin :
false;
2792 auto onIntersection =
2801 for(
SCH_TEXT* label : segDesc.labels )
2804 const SEG* segAttached = segDesc.LabelAttached( label );
2806 if( segAttached && !onIntersection( labelPos ) )
2820 VECTOR2I wireDirection( segAttached->
B - segAttached->
A );
2822 const VECTOR2I origPos( labelPos );
2825 bool checkPositive =
true, checkNegative =
true,
move =
false;
2829 while( ( !
move || onIntersection( labelPos ) ) && ( checkPositive || checkNegative ) )
2834 if( trial % 2 == 1 )
2836 labelPos =
VECTOR2I( origPos + wireDirection * trial / 2 );
2837 move = checkPositive = segAttached->
Contains( labelPos );
2841 labelPos =
VECTOR2I( origPos - wireDirection * trial / 2 );
2842 move = checkNegative = segAttached->
Contains( labelPos );
2878 wxFileInputStream input( aFileName );
2883 wxTextInputStream
text( input );
2885 for(
int i = 0; i < 4; i++ )
2890 if(
text.ReadLine().Contains( wxS(
"<eagle" ) ) )
2906 if( !item->IsType( { SCH_LABEL_LOCATE_ANY_T } ) )
2910 item->SetPosition( aNewEndPoint );
2923 std::vector<SCH_LINE*> buses;
2924 std::vector<SCH_LINE*> wires;
2935 buses.push_back( line );
2936 else if( line->
IsWire() )
2937 wires.push_back( line );
2942 VECTOR2I wireStart = wire->GetStartPoint();
2943 VECTOR2I wireEnd = wire->GetEndPoint();
2947 VECTOR2I busStart = bus->GetStartPoint();
2948 VECTOR2I busEnd = bus->GetEndPoint();
2951 [](
int signX,
int signY ) ->
VECTOR2I
2963 if( wireStart.
y == wireEnd.
y && busStart.
x == busEnd.
x )
2967 if( testBusHit( wireStart ) )
2971 if( wireEnd.
x < busStart.
x )
2978 VECTOR2I p = wireStart + entrySize( -1, 0 );
2980 if( testBusHit( wireStart + entrySize( 0, -1 ) ) )
2989 screen->
Append( busEntry );
2991 wire->SetStartPoint( p );
2993 else if( testBusHit( wireStart + entrySize( 0, 1 ) ) )
3002 screen->
Append( busEntry );
3004 wire->SetStartPoint( p );
3010 screen->
Append( marker );
3020 VECTOR2I p = wireStart + entrySize( 1, 0 );
3022 if( testBusHit( wireStart + entrySize( 0, -1 ) ) )
3031 screen->
Append( busEntry );
3033 wire->SetStartPoint( p );
3035 else if( testBusHit( wireStart + entrySize( 0, 1 ) ) )
3044 screen->
Append( busEntry );
3046 wire->SetStartPoint( p );
3052 screen->
Append( marker );
3058 else if( testBusHit( wireEnd ) )
3062 if( wireStart.
x < busStart.
x )
3069 VECTOR2I p = wireEnd + entrySize( -1, 0 );
3071 if( testBusHit( wireEnd + entrySize( 0, -1 ) ) )
3080 screen->
Append( busEntry );
3082 wire->SetEndPoint( p );
3084 else if( testBusHit( wireEnd + entrySize( 0, -1 ) ) )
3093 screen->
Append( busEntry );
3094 moveLabels( wire, wireEnd + entrySize( -1, 0 ) );
3095 wire->SetEndPoint( wireEnd + entrySize( -1, 0 ) );
3101 screen->
Append( marker );
3111 VECTOR2I p = wireEnd + entrySize( 1, 0 );
3113 if( testBusHit( wireEnd + entrySize( 0, -1 ) ) )
3122 screen->
Append( busEntry );
3124 wire->SetEndPoint( p );
3126 else if( testBusHit( wireEnd + entrySize( 0, 1 ) ) )
3135 screen->
Append( busEntry );
3137 wire->SetEndPoint( p );
3143 screen->
Append( marker );
3150 else if( wireStart.
x == wireEnd.
x && busStart.
y == busEnd.
y )
3154 if( testBusHit( wireStart ) )
3158 if( wireEnd.
y < busStart.
y )
3166 VECTOR2I p = wireStart + entrySize( 0, -1 );
3168 if( testBusHit( wireStart + entrySize( -1, 0 ) ) )
3178 screen->
Append( busEntry );
3180 wire->SetStartPoint( p );
3182 else if( testBusHit( wireStart + entrySize( 1, 0 ) ) )
3192 screen->
Append( busEntry );
3194 wire->SetStartPoint( p );
3200 screen->
Append( marker );
3211 VECTOR2I p = wireStart + entrySize( 0, 1 );
3213 if( testBusHit( wireStart + entrySize( -1, 0 ) ) )
3223 screen->
Append( busEntry );
3225 wire->SetStartPoint( p );
3227 else if( testBusHit( wireStart + entrySize( 1, 0 ) ) )
3237 screen->
Append( busEntry );
3239 wire->SetStartPoint( p );
3245 screen->
Append( marker );
3251 else if( testBusHit( wireEnd ) )
3255 if( wireStart.
y < busStart.
y )
3263 VECTOR2I p = wireEnd + entrySize( 0, -1 );
3265 if( testBusHit( wireEnd + entrySize( -1, 0 ) ) )
3275 screen->
Append( busEntry );
3277 wire->SetEndPoint( p );
3279 else if( testBusHit( wireEnd + entrySize( 1, 0 ) ) )
3289 screen->
Append( busEntry );
3291 wire->SetEndPoint( p );
3297 screen->
Append( marker );
3308 VECTOR2I p = wireEnd + entrySize( 0, 1 );
3310 if( testBusHit( wireEnd + entrySize( -1, 0 ) ) )
3320 screen->
Append( busEntry );
3322 wire->SetEndPoint( p );
3324 else if( testBusHit( wireEnd + entrySize( 1, 0 ) ) )
3334 screen->
Append( busEntry );
3336 wire->SetEndPoint( p );
3342 screen->
Append( marker );
3353 if( testBusHit( wireStart ) )
3355 VECTOR2I wirevector = wireStart - wireEnd;
3357 if( wirevector.
x > 0 )
3359 if( wirevector.
y > 0 )
3361 VECTOR2I p = wireStart + entrySize( -1, -1 );
3364 screen->
Append( busEntry );
3367 wire->SetStartPoint( p );
3371 VECTOR2I p = wireStart + entrySize( -1, 1 );
3374 screen->
Append( busEntry );
3377 wire->SetStartPoint( p );
3382 if( wirevector.
y > 0 )
3384 VECTOR2I p = wireStart + entrySize( 1, -1 );
3387 screen->
Append( busEntry );
3390 wire->SetStartPoint( p );
3394 VECTOR2I p = wireStart + entrySize( 1, 1 );
3397 screen->
Append( busEntry );
3400 wire->SetStartPoint( p );
3406 else if( testBusHit( wireEnd ) )
3408 VECTOR2I wirevector = wireStart - wireEnd;
3410 if( wirevector.
x > 0 )
3412 if( wirevector.
y > 0 )
3414 VECTOR2I p = wireEnd + entrySize( 1, 1 );
3417 screen->
Append( busEntry );
3420 wire->SetEndPoint( p );
3424 VECTOR2I p = wireEnd + entrySize( 1, -1 );
3427 screen->
Append( busEntry );
3430 wire->SetEndPoint( p );
3435 if( wirevector.
y > 0 )
3437 VECTOR2I p = wireEnd + entrySize( -1, 1 );
3440 screen->
Append( busEntry );
3443 wire->SetEndPoint( p );
3447 VECTOR2I p = wireEnd + entrySize( -1, -1 );
3450 screen->
Append( busEntry );
3453 wire->SetEndPoint( p );
3469 for(
const SEG& seg : segs )
3471 if( seg.Contains( labelPos ) )
3483 wxCHECK( aSymbol && aPin,
false );
3491 const auto& items = pointIt->second;
3493 wxCHECK( items.find( aPin ) != items.end(),
false );
3495 return items.size() > 1;
3509 int unit = aSymbol->
GetUnit();
3511 std::vector<SCH_PIN*> pins = aSymbol->
GetLibSymbolRef()->GetAllLibPins();
3512 std::set<int> missingUnits;
3517 if(
pin->GetType() == ELECTRICAL_PINTYPE::PT_POWER_IN )
3519 bool pinInUnit = !unit ||
pin->GetUnit() == unit;
3533 switch(
pin->GetOrientation() )
3536 case PIN_ORIENTATION::PIN_RIGHT:
3539 case PIN_ORIENTATION::PIN_LEFT:
3542 case PIN_ORIENTATION::PIN_UP:
3545 case PIN_ORIENTATION::PIN_DOWN:
3550 aScreen->
Append( netLabel );
3553 else if( aUpdateSet )
3558 wxASSERT(
pin->GetUnit() );
3559 missingUnits.insert(
pin->GetUnit() );
3572 entry.
cmp = aSymbol;
3573 entry.
units.emplace( unit,
false );
3578 cmpIt->second.units[unit] =
false;
3581 if( !missingUnits.empty() )
3584 entry.
cmp = aSymbol;
3587 for(
int i : missingUnits )
3589 if( entry.
units.find( i ) != entry.
units.end() )
3590 entry.
units.emplace( i,
true );
3602 wxString ret = wxT(
"{" );
3604 wxStringTokenizer tokenizer( aEagleName, wxT(
"," ) );
3606 while( tokenizer.HasMoreTokens() )
3608 wxString member = tokenizer.GetNextToken();
3615 if( member.Freq(
'!' ) % 2 > 0 )
3616 member << wxT(
"!" );
3618 ret << member << wxS(
" " );
constexpr EDA_IU_SCALE schIUScale
const SizeVec & GetSize() const
size_type GetHeight() const
size_type GetWidth() const
coord_type GetLeft() const
coord_type GetBottom() const
BOX2< Vec > & Merge(const BOX2< Vec > &aRect)
Modify the position and size of the rectangle in order to contain aRect.
void SetFlags(EDA_ITEM_FLAGS aMask)
void SetCenter(const VECTOR2I &aCenter)
SHAPE_POLY_SET & GetPolyShape()
const VECTOR2I & GetEnd() const
Return the ending point of the graphic.
void SetStart(const VECTOR2I &aStart)
void SetEnd(const VECTOR2I &aEnd)
void SetArcAngleAndEnd(const EDA_ANGLE &aAngle, bool aCheckNegativeAngle=false)
Set the end point from the angle center and start.
void SetFillMode(FILL_T aFill)
A mix-in class (via multiple inheritance) that handles texts such as labels, parts,...
const EDA_ANGLE & GetTextAngle() const
void SetTextSize(VECTOR2I aNewSize, bool aEnforceMinTextSize=true)
virtual const wxString & GetText() const
Return the string associated with the text object.
virtual bool IsVisible() const
void SetTextPos(const VECTOR2I &aPoint)
void SetVertJustify(GR_TEXT_V_ALIGN_T aType)
GR_TEXT_H_ALIGN_T GetHorizJustify() const
virtual void SetVisible(bool aVisible)
GR_TEXT_V_ALIGN_T GetVertJustify() const
virtual void SetText(const wxString &aText)
virtual void SetTextAngle(const EDA_ANGLE &aAngle)
void SetItalic(bool aItalic)
VECTOR2I GetTextSize() const
void SetHorizJustify(GR_TEXT_H_ALIGN_T aType)
EE_TYPE Overlapping(const BOX2I &aRect) const
iterator end()
Returns a read/write iterator that points to one past the last element in the EE_RTREE.
iterator begin()
Returns a read/write iterator that points to the first element in the EE_RTREE N.B.
EE_TYPE OfType(KICAD_T aType) const
static std::shared_ptr< ERC_ITEM > Create(int aErrorCode)
Constructs an ERC_ITEM for the given error code.
REPORTER * m_reporter
Reporter to log errors/warnings to, may be nullptr.
PROGRESS_REPORTER * m_progressReporter
Progress reporter to track the progress of the operation, may be nullptr.
virtual bool CanReadLibrary(const wxString &aFileName) const
Checks if this IO object can read the specified library file/directory.
A logical library item identifier and consists of various portions much like a URI.
static UTF8 FixIllegalChars(const UTF8 &aLibItemName, bool aLib)
Replace illegal LIB_ID item name characters with underscores '_'.
Define a library symbol object.
bool IsPower() const override
void GetFields(std::vector< SCH_FIELD * > &aList)
Return a list of fields within this symbol.
SCH_FIELD * GetFieldById(int aId) const
Return pointer to the requested field.
bool HasLibrary(const wxString &aNickname, bool aCheckEnabled=false) const
Test for the existence of aNickname in the library table.
bool InsertRow(LIB_TABLE_ROW *aRow, bool doReplace=false)
Adds aRow if it does not already exist or if doReplace is true.
Instantiate the current locale within a scope in which you are expecting exceptions to be thrown.
static bool ParseBusVector(const wxString &aBus, wxString *aName, std::vector< wxString > *aMemberList)
Parse a bus vector (e.g.
const T & CGet() const
Return a constant reference to the value of the attribute assuming it is available.
T & Get()
Return a reference to the value of the attribute assuming it is available.
Describe the page size and margins of a paper page on which to eventually print or plot.
void SetHeightMils(double aHeightInMils)
const VECTOR2D GetSizeIU(double aIUScale) const
Gets the page size in internal units.
void SetWidthMils(double aWidthInMils)
virtual bool KeepRefreshing(bool aWait=false)=0
Update the UI (if any).
virtual void Report(const wxString &aMessage)=0
Display aMessage in the progress bar dialog.
virtual void SetCurrentProgress(double aProgress)=0
Set the progress value to aProgress (0..1).
static SYMBOL_LIB_TABLE * SchSymbolLibTable(PROJECT *aProject)
Accessor for project symbol library table.
virtual const wxString GetProjectPath() const
Return the full path of the project.
virtual const wxString GetProjectName() const
Return the short name of the project.
virtual void SetElem(ELEM_T aIndex, _ELEM *aElem)
virtual REPORTER & Report(const wxString &aText, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED)=0
Report a string with a given severity.
Holds all the data relating to one schematic.
void SetRoot(SCH_SHEET *aRootSheet)
Initialize the schematic with a new root sheet.
bool IsValid() const
A simple test if the schematic is loaded, not a complete one.
PROJECT & Prj() const override
Return a reference to the project this schematic is part of.
Class for a wire to bus entry.
Instances are attached to a symbol or sheet and provide a place for the symbol's value,...
VECTOR2I GetPosition() const override
void SetPosition(const VECTOR2I &aPosition) override
void SetName(const wxString &aName)
void SetText(const wxString &aText) override
void SetSpinStyle(SPIN_STYLE aSpinStyle) override
SCH_SHAPE * loadSymbolRectangle(wxXmlNode *aRectNode, int aGateNumber)
SCH_PIN * loadPin(std::unique_ptr< LIB_SYMBOL > &aSymbol, wxXmlNode *, EPIN *epin, int aGateNumber)
SCH_SHAPE * loadSymbolCircle(wxXmlNode *aCircleNode, int aGateNumber)
void ensureLoadedLibrary(const wxString &aLibraryPath)
SCH_JUNCTION * loadJunction(wxXmlNode *aJunction)
void loadSegments(wxXmlNode *aSegmentsNode, const wxString &aNetName, const wxString &aNetClass)
EAGLE_LIBRARY * loadLibrary(wxXmlNode *aLibraryNode, EAGLE_LIBRARY *aEagleLib)
std::unique_ptr< STRING_UTF8_MAP > m_properties
Library plugin properties.
wxXmlDocument loadXmlDocument(const wxString &aFileName)
void loadSheet(wxXmlNode *aSheetNode, int sheetcount)
wxString translateEagleBusName(const wxString &aEagleName) const
Translate an Eagle-style bus name into one that is KiCad-compatible.
void loadFieldAttributes(SCH_FIELD *aField, const SCH_TEXT *aText) const
Move net labels that are detached from any wire to the nearest wire.
std::map< wxString, wxString > m_powerPorts
map from symbol reference to global label equivalent
SCH_SHEET_PATH m_sheetPath
The current sheet path of the schematic being loaded.
wxString m_libName
Library name to save symbols.
LIB_SYMBOL * LoadSymbol(const wxString &aLibraryPath, const wxString &aAliasName, const STRING_UTF8_MAP *aProperties) override
Load a LIB_SYMBOL object having aPartName from the aLibraryPath containing a library format that this...
void loadInstance(wxXmlNode *aInstanceNode)
std::pair< VECTOR2I, const SEG * > findNearestLinePoint(const VECTOR2I &aPoint, const std::vector< SEG > &aLines) const
SCH_SHAPE * loadCircle(wxXmlNode *aCircleNode)
SCH_TEXT * loadLabel(wxXmlNode *aLabelNode, const wxString &aNetName)
const double ARC_ACCURACY
std::map< wxString, long long > m_timestamps
SCH_SHEET * LoadSchematicFile(const wxString &aFileName, SCHEMATIC *aSchematic, SCH_SHEET *aAppendToMe=nullptr, const STRING_UTF8_MAP *aProperties=nullptr) override
Load information from some input file format that this SCH_IO implementation knows about,...
void loadSymbolFrame(wxXmlNode *aFrameNode, std::vector< SCH_ITEM * > &aLines)
std::unordered_map< wxString, bool > m_userValue
deviceset/@uservalue for device.
int GetModifyHash() const override
Return the modification hash from the library cache.
std::map< wxString, int > m_netCounts
SCH_ITEM * loadWire(wxXmlNode *aWireNode, SEG &endpoints)
std::map< wxString, EAGLE_LIBRARY > m_eagleLibs
SCH_SHAPE * loadPolyLine(wxXmlNode *aPolygonNode)
void countNets(wxXmlNode *aSchematicNode)
SCH_SHEET * getCurrentSheet()
std::vector< VECTOR2I > m_wireIntersections
Wires and labels of a single connection (segment in Eagle nomenclature)
void loadSchematic(wxXmlNode *aSchematicNode)
std::map< VECTOR2I, std::set< const EDA_ITEM * > > m_connPoints
bool checkConnections(const SCH_SYMBOL *aSymbol, const SCH_PIN *aPin) const
IO_RELEASER< SCH_IO > m_pi
PI to create KiCad symbol library.
void addBusEntries()
This function finds best way to place a bus entry symbol for when an Eagle wire segment ends on an Ea...
SCH_SHAPE * loadSymbolPolyLine(wxXmlNode *aPolygonNode, int aGateNumber)
bool CanReadSchematicFile(const wxString &aFileName) const override
Checks if this SCH_IO can read the specified schematic file.
void addImplicitConnections(SCH_SYMBOL *aSymbol, SCH_SCREEN *aScreen, bool aUpdateSet)
Create net labels to emulate implicit connections in Eagle.
std::map< int, SCH_LAYER_ID > m_layerMap
SCH_LAYER_ID kiCadLayer(int aEagleLayer)
Return the matching layer or return LAYER_NOTES.
wxFileName getLibFileName()
Checks if there are other wires or pins at the position of the tested pin.
void EnumerateSymbolLib(wxArrayString &aSymbolNameList, const wxString &aLibraryPath, const STRING_UTF8_MAP *aProperties) override
Populate a list of LIB_SYMBOL alias names contained within the library aLibraryPath.
SCH_ITEM * loadSymbolWire(wxXmlNode *aWireNode, int aGateNumber)
wxString m_version
Eagle file version.
void loadTextAttributes(EDA_TEXT *aText, const ETEXT &aAttribs) const
SCH_SHAPE * loadRectangle(wxXmlNode *aRectNode)
void moveLabels(SCH_LINE *aWire, const VECTOR2I &aNewEndPoint)
Move any labels on the wire to the new end point of the wire.
bool checkHeader(const wxString &aFileName) const
SCHEMATIC * m_schematic
Passed to Load(), the schematic object being loaded.
bool loadSymbol(wxXmlNode *aSymbolNode, std::unique_ptr< LIB_SYMBOL > &aSymbol, EDEVICE *aDevice, int aGateNumber, const wxString &aGateName)
SCH_SHEET * m_rootSheet
The root sheet of the schematic being loaded.
SCH_SCREEN * getCurrentScreen()
unsigned m_lastProgressCount
bool CanReadLibrary(const wxString &aFileName) const override
Checks if this IO object can read the specified library file/directory.
std::map< wxString, EAGLE_MISSING_CMP > m_missingCmps
SCH_TEXT * loadPlainText(wxXmlNode *aSchText)
void loadFrame(wxXmlNode *aFrameNode, std::vector< SCH_ITEM * > &aItems)
SCH_TEXT * loadSymbolText(wxXmlNode *aLibText, int aGateNumber)
void loadLayerDefs(wxXmlNode *aLayers)
std::vector< SEG_DESC > m_segments
Nets as defined in the <nets> sections of an Eagle schematic file.
void loadDrawing(wxXmlNode *aDrawingNode)
unsigned m_totalCount
for progress reporting
long long getLibraryTimestamp(const wxString &aLibraryPath) const
static const char * PropBuffering
The property used internally by the plugin to enable cache buffering which prevents the library file ...
Base class that schematic file and library loading and saving plugins should derive from.
virtual bool CanReadSchematicFile(const wxString &aFileName) const
Checks if this SCH_IO can read the specified schematic file.
Base class for any item which can be embedded within the SCHEMATIC container class,...
virtual void SetUnit(int aUnit)
SCH_ITEM * Duplicate(bool doClone=false) const
Routine to create a new copy of given item.
void SetPosition(const VECTOR2I &aPosition) override
Segment description base class to describe items which have 2 end points (track, wire,...
bool IsWire() const
Return true if the line is a wire.
const BOX2I GetBoundingBox() const override
Return the orthogonal bounding box of this object for display purposes.
VECTOR2I GetEndPoint() const
VECTOR2I GetStartPoint() const
bool IsBus() const
Return true if the line is a bus.
void SetNumber(const wxString &aNumber)
Container class that holds multiple SCH_SCREEN objects in a hierarchy.
void UpdateSymbolLinks(REPORTER *aReporter=nullptr)
Initialize the LIB_SYMBOL reference for each SCH_SYMBOL found in the full schematic.
const PAGE_INFO & GetPageSettings() const
void Append(SCH_ITEM *aItem, bool aUpdateLibSymbol=true)
void SetPageSettings(const PAGE_INFO &aPageSettings)
EE_RTREE & Items()
Gets the full RTree, usually for iterating.
const KIID & GetUuid() const
void SetFileName(const wxString &aFileName)
Set the file name for this screen to aFileName.
void Update(SCH_ITEM *aItem, bool aUpdateLibSymbol=true)
Update aItem's bounding box in the tree.
void SetPosition(const VECTOR2I &aPos) override
void SetStroke(const STROKE_PARAMS &aStroke) override
VECTOR2I GetCenter() const
void AddPoint(const VECTOR2I &aPosition)
VECTOR2I GetPosition() const override
Handle access to a stack of flattened SCH_SHEET objects by way of a path for creating a flattened sch...
KIID_PATH Path() const
Get the sheet path as an KIID_PATH.
void SetPageNumber(const wxString &aPageNumber)
Set the sheet instance user definable page number.
SCH_SHEET * Last() const
Return a pointer to the last SCH_SHEET of the list.
void push_back(SCH_SHEET *aSheet)
Forwarded method from std::vector.
void pop_back()
Forwarded method from std::vector.
Sheet symbol placed in a schematic, and is the entry point for a sub schematic.
void SetFileName(const wxString &aFilename)
wxString GetFileName() const
Return the filename corresponding to this sheet.
std::vector< SCH_FIELD > & GetFields()
bool LocatePathOfScreen(SCH_SCREEN *aScreen, SCH_SHEET_PATH *aList)
Search the existing hierarchy for an instance of screen loaded from aFileName.
SCH_SCREEN * GetScreen() const
void SetScreen(SCH_SCREEN *aScreen)
Set the SCH_SCREEN associated with this sheet to aScreen.
void AutoplaceFields(SCH_SCREEN *aScreen, bool aManual) override
SCH_FIELD * GetField(MANDATORY_FIELD_T aFieldType)
Return a mandatory field in this symbol.
std::unique_ptr< LIB_SYMBOL > & GetLibSymbolRef()
VECTOR2I GetPinPhysicalPosition(const SCH_PIN *Pin) const
VECTOR2I GetPosition() const override
void SetPosition(const VECTOR2I &aPosition) override
OPT_VECTOR2I Intersect(const SEG &aSeg, bool aIgnoreEndpoints=false, bool aLines=false) const
Compute intersection point of segment (this) with segment aSeg.
bool Contains(const SEG &aSeg) const
SHAPE_ARC & ConstructFromStartEndAngle(const VECTOR2I &aStart, const VECTOR2I &aEnd, const EDA_ANGLE &aAngle, double aWidth=0)
Construct this arc from the given start, end and angle.
int Append(int x, int y, int aOutline=-1, int aHole=-1, bool aAllowDuplication=false)
Appends a vertex at the end of the given outline/hole (default: the last outline)
A name/value tuple with unique names and optional values.
Simple container to manage line stroke parameters.
Hold a record identifying a symbol library accessed by the appropriate symbol library SCH_IO object i...
static const wxString & GetSymbolLibTableFileName()
virtual void Format(OUTPUTFORMATTER *aOutput, int aIndentLevel) const override
Generate the table in s-expression format to aOutput with an indentation level of aIndentLevel.
LIB_SYMBOL * LoadSymbol(const wxString &aNickname, const wxString &aName)
Load a LIB_SYMBOL having aName from the library given by aNickname.
VECTOR2< T > Resize(T aNewLength) const
Return a vector of the same direction, but length specified in aNewLength.
static REPORTER & GetInstance()
#define DEFAULT_SCH_ENTRY_SIZE
The default text size in mils. (can be changed in preference menu)
NODE_MAP MapChildren(wxXmlNode *aCurrentNode)
Provide an easy access to the children of an XML node via their names.
wxString escapeName(const wxString &aNetName)
Interprets special characters in Eagle text and converts them to KiCAD notation.
wxString interpretText(const wxString &aText)
Translates Eagle special text reference to a KiCad variable reference.
VECTOR2I ConvertArcCenter(const VECTOR2I &aStart, const VECTOR2I &aEnd, double aAngle)
wxString convertDescription(wxString aDescr)
static wxXmlNode * getChildrenNodes(NODE_MAP &aMap, const wxString &aName)
std::unordered_map< wxString, wxXmlNode * > NODE_MAP
static constexpr EDA_ANGLE ANGLE_VERTICAL
#define IS_NEW
New item, just created.
@ ERCE_BUS_ENTRY_NEEDED
Importer failed to auto-place a bus entry.
static const std::string KiCadSchematicFileExtension
static const std::string KiCadSymbolLibFileExtension
#define THROW_IO_ERROR(msg)
SCH_LAYER_ID
Eeschema drawing layers.
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
@ PT_INPUT
usual pin input: must be connected
@ PT_NC
not connected (must be left open)
@ PT_TRISTATE
tris state bus pin
@ PT_BIDI
input or output (like port for a microprocessor)
@ PT_OPENCOLLECTOR
pin type open collector
@ PT_POWER_IN
power input (GND, VCC for ICs). Must be connected to a power output.
@ PT_PASSIVE
pin for passive symbols: must be connected, and can be connected to any pin
static int countChildren(wxXmlNode *aCurrentNode, const wxString &aName)
Provide an easy access to the children of an XML node via their names.
static wxString extractNetName(const wxString &aPinName)
static const std::map< wxString, ELECTRICAL_PINTYPE > pinDirectionsMap
Map of EAGLE pin type values to KiCad pin type values.
static SYMBOL_ORIENTATION_T kiCadComponentRotation(float eagleDegrees)
static void eagleToKicadAlignment(EDA_TEXT *aText, int aEagleAlignment, int aRelDegress, bool aMirror, bool aSpin, int aAbsDegress)
static BOX2I getSheetBbox(SCH_SHEET *aSheet)
Extract the net name part from a pin name (e.g. return 'GND' for pin named 'GND@2')
Definition of the SCH_SHEET_PATH and SCH_SHEET_LIST classes for Eeschema.
SYMBOL_ORIENTATION_T
enum used in RotationMiroir()
std::optional< VECTOR2I > OPT_VECTOR2I
wxString UnescapeString(const wxString &aSource)
bool ReplaceIllegalFileNameChars(std::string *aName, int aReplaceChar)
Checks aName for illegal file name characters.
wxString EscapeString(const wxString &aSource, ESCAPE_CONTEXT aContext)
The Escape/Unescape routines use HTML-entity-reference-style encoding to handle characters which are:...
wxString UnescapeHTML(const wxString &aString)
Return a new wxString unescaped from HTML format.
std::unordered_map< wxString, int > GateUnit
std::unordered_map< wxString, wxString > package
boost::ptr_map< wxString, LIB_SYMBOL > KiCadSymbols
std::unordered_map< wxString, wxXmlNode * > SymbolNodes
Parse an Eagle "attribute" XML element.
constexpr int IUToMils(int iu) const
constexpr int MilsToIU(int mils) const
std::vector< ECONNECT > connects
Parse an Eagle frame element.
std::map< std::string, std::string > variant
std::map< std::string, std::string > attribute
Eagle polygon, without vertices which are parsed as needed.
Eagle XML rectangle in binary.
VECTOR2I ConvertSize() const
Calculate text size based on font type and size.
opt_double curve
range is -359.9..359.9
opt_double curve
range is -359.9..359.9
Map references to missing symbol units data.
std::map< int, bool > units
Segments representing wires for intersection checking.
std::vector< SCH_TEXT * > labels
const SEG * LabelAttached(const SCH_TEXT *aLabel) const
< Test if a particular label is attached to any of the stored segments
@ FOOTPRINT_FIELD
Field Name Module PCB, i.e. "16DIP300".
@ VALUE_FIELD
Field Value of part, i.e. "3.3K".
@ REFERENCE_FIELD
Field Reference of part, i.e. "IC21".
bool TestSegmentHit(const VECTOR2I &aRefPoint, const VECTOR2I &aStart, const VECTOR2I &aEnd, int aDist)
Test if aRefPoint is with aDistance on the line defined by aStart and aEnd.
void RotatePoint(int *pX, int *pY, const EDA_ANGLE &aAngle)
Calculate the new point of coord coord pX, pY, for a rotation center 0, 0.
constexpr ret_type KiROUND(fp_type v)
Round a floating point number to an integer using "round halfway cases away from zero".
Definition of file extensions used in Kicad.