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>
94static int countChildren( wxXmlNode* aCurrentNode,
const wxString& aName )
100 aCurrentNode = aCurrentNode->GetChildren();
102 while( aCurrentNode )
104 if( aCurrentNode->GetName() == aName )
108 aCurrentNode = aCurrentNode->GetNext();
121 bbox.
Merge( item->GetBoundingBox() );
130 return aPinName.BeforeFirst(
'@' );
143 wxCHECK( currentSheet,
nullptr );
182 std::vector<ELAYER> eagleLayers;
185 wxXmlNode* layerNode = aLayers->GetChildren();
189 ELAYER elayer( layerNode );
190 eagleLayers.push_back( elayer );
192 layerNode = layerNode->GetNext();
196 for(
const ELAYER& elayer : eagleLayers )
215 if( elayer.name == wxT(
"Nets" ) )
217 else if( elayer.name == wxT(
"Info" ) || elayer.name == wxT(
"Guide" ) )
219 else if( elayer.name == wxT(
"Busses" ) )
235 int roti = int( eagleDegrees );
245 wxASSERT_MSG(
false, wxString::Format( wxT(
"Unhandled orientation (%d degrees)" ), roti ) );
253 bool aMirror,
bool aSpin,
int aAbsDegress )
255 int align = aEagleAlignment;
257 if( aRelDegress == 90 )
261 else if( aRelDegress == 180 )
263 else if( aRelDegress == 270 )
269 if( aMirror ==
true )
271 if( aAbsDegress == 90 || aAbsDegress == 270 )
282 else if( aAbsDegress == 0 || aAbsDegress == 180 )
355 m_progressReporter( nullptr ),
357 m_lastProgressCount( 0 ),
374 return wxT(
"EAGLE" );
398 const unsigned PROGRESS_DELTA = 5;
419 wxASSERT( !aFileName || aSchematic !=
nullptr );
434 wxXmlDocument xmlDocument;
435 wxFFileInputStream stream(
m_filename.GetFullPath() );
438 wxTextInputStream
text( stream );
439 wxString line =
text.ReadLine();
440 if( !line.StartsWith( wxT(
"<?xml" ) ) )
442 THROW_IO_ERROR( wxString::Format(
_(
"'%s' is an Eagle binary-format schematic file; "
443 "only Eagle XML-format schematics can be imported." ),
447 if( !stream.IsOk() || !xmlDocument.Load( stream ) )
454 unique_ptr<SCH_SHEET> deleter( aAppendToMe ?
nullptr :
m_rootSheet );
461 wxCHECK_MSG( aSchematic->
IsValid(),
nullptr,
462 wxT(
"Can't append to a schematic with no root!" ) );
485 wxCHECK_MSG( libTable,
nullptr, wxT(
"Could not load symbol lib table." ) );
487 m_pi.
set( SCH_IO_MGR::FindPlugin( SCH_IO_MGR::SCH_KICAD ) );
497 wxString libTableUri = wxT(
"${KIPRJMOD}/" ) +
getLibFileName().GetFullName();
510 libTable->
Format( &formatter, 0 );
519 wxXmlNode* currentNode = xmlDocument.GetRoot();
523 m_version = currentNode->GetAttribute( wxT(
"version" ), wxT(
"0.0" ) );
550 auto layers = drawingChildren[
"layers"];
560 auto schematic = drawingChildren[
"schematic"];
573 wxXmlNode* sheetNode =
getChildrenNodes( schematicChildren, wxT(
"sheets" ) );
585 wxString netName = netNode->GetAttribute( wxT(
"name" ) );
593 netNode = netNode->GetNext();
596 sheetNode = sheetNode->GetNext();
605 wxXmlNode* partNode =
getChildrenNodes( schematicChildren, wxT(
"parts" ) );
606 wxXmlNode* libraryNode =
getChildrenNodes( schematicChildren, wxT(
"libraries" ) );
607 wxXmlNode* sheetNode =
getChildrenNodes( schematicChildren, wxT(
"sheets" ) );
613 []( wxXmlNode* aNode ) ->
unsigned
620 aNode = aNode->GetNext();
636 wxXmlNode* devicesetNode =
getChildrenNodes( libraryChildren, wxT(
"devicesets" ) );
638 while( devicesetNode )
641 wxXmlNode* deviceNode =
getChildrenNodes( deviceSetChildren, wxT(
"devices" ) );
642 wxXmlNode* gateNode =
getChildrenNodes( deviceSetChildren, wxT(
"gates" ) );
644 m_totalCount += count_nodes( deviceNode ) * count_nodes( gateNode );
646 devicesetNode = devicesetNode->GetNext();
649 libraryNode = libraryNode->GetNext();
664 sheetNode = sheetNode->GetNext();
675 std::unique_ptr<EPART> epart = std::make_unique<EPART>( partNode );
678 m_partlist[epart->name.Upper()] = std::move( epart );
679 partNode = partNode->GetNext();
687 wxString libName = libraryNode->GetAttribute( wxT(
"name" ) );
690 elib->
name = libName;
694 libraryNode = libraryNode->GetNext();
708 int sheetCount =
countChildren( sheetNode->GetParent(), wxT(
"sheet" ) );
724 std::unique_ptr<SCH_SHEET> sheet = std::make_unique<SCH_SHEET>(
m_rootSheet, pos );
726 sheet->SetScreen( screen );
729 wxCHECK2( sheet && screen,
continue );
731 wxString pageNo = wxString::Format( wxT(
"%d" ), i );
741 wxCHECK2( currentScreen,
continue );
743 currentScreen->
Append( sheet.release() );
745 sheetNode = sheetNode->GetNext();
763 sheetNode = sheetNode->GetNext();
775 int maxY = sheetBbox.
GetY();
782 const SCH_SYMBOL* origSymbol = cmp.second.cmp;
784 for(
auto& unitEntry : cmp.second.units )
786 if( unitEntry.second ==
false )
790 int unit = unitEntry.first;
794 symbol->SetUnitSelection( &sheetpath, unit );
795 symbol->SetUnit( unit );
796 symbol->SetOrientation( 0 );
797 symbol->AddHierarchicalReference( sheetpath.
Path(), reference, unit );
800 BOX2I cmpBbox = symbol->GetBoundingBox();
801 int posY = newCmpPosition.
y + cmpBbox.
GetHeight();
802 symbol->SetPosition(
VECTOR2I( newCmpPosition.
x, posY ) );
804 maxY = std::max( maxY, posY );
806 if( newCmpPosition.
x >= pageSizeIU.
x )
825 wxXmlNode* descriptionNode =
getChildrenNodes( sheetChildren, wxT(
"description" ) );
832 std::string filename;
836 if( descriptionNode )
838 des = descriptionNode->GetContent();
839 des.Replace( wxT(
"\n" ), wxT(
"_" ),
true );
841 filename = des.ToStdString();
845 filename = wxString::Format( wxT(
"%s_%d" ),
m_filename.GetName(), aSheetIndex );
846 sheetNameField.
SetText( filename );
850 replace( filename.begin(), filename.end(),
' ',
'_' );
853 fn.SetName( filename );
856 filenameField.
SetText( fn.GetFullName() );
866 wxXmlNode* instanceNode =
getChildrenNodes( sheetChildren, wxT(
"instances" ) );
868 while( instanceNode )
873 instanceNode = instanceNode->GetNext();
893 busNode = busNode->GetNext();
905 wxString netName = netNode->GetAttribute( wxT(
"name" ) );
906 wxString netClass = netNode->GetAttribute( wxT(
"class" ) );
912 netNode = netNode->GetNext();
936 wxString nodeName = plainNode->GetName();
938 if( nodeName == wxT(
"polygon" ) )
942 else if( nodeName == wxT(
"wire" ) )
947 else if( nodeName == wxT(
"text" ) )
951 else if( nodeName == wxT(
"circle" ) )
955 else if( nodeName == wxT(
"rectangle" ) )
959 else if( nodeName == wxT(
"frame" ) )
961 std::vector<SCH_ITEM*> frameItems;
969 plainNode = plainNode->GetNext();
982 if( pageSizeIU.
x < targetSheetSize.
x )
985 if( pageSizeIU.
y < targetSheetSize.
y )
992 VECTOR2I sheetcentre( pageSizeIU.
x / 2, pageSizeIU.
y / 2 );
996 VECTOR2I translation = sheetcentre - itemsCentre;
1010 std::vector<SCH_ITEM*> allItems;
1012 std::copy( screen->
Items().
begin(), screen->
Items().
end(), std::back_inserter( allItems ) );
1016 item->SetPosition( item->GetPosition() + translation );
1021 label->AutoplaceFields( screen,
false );
1032 EFRAME eframe( aFrameNode );
1040 std::swap( xMin, xMax );
1043 std::swap( yMin, yMax );
1051 aItems.push_back( lines );
1060 aItems.push_back( lines );
1063 int height = yMax - yMin;
1067 double rowSpacing = height / double( eframe.
rows );
1068 double legendPosY = yMin + ( rowSpacing / 2 );
1070 for( i = 1; i < eframe.
rows; i++ )
1072 int newY =
KiROUND( yMin + ( rowSpacing * (
double) i ) );
1076 aItems.push_back( lines );
1079 char legendChar =
'A';
1081 for( i = 0; i < eframe.
rows; i++ )
1087 legendText->
SetText( wxString( legendChar ) );
1090 aItems.push_back( legendText );
1092 legendPosY += rowSpacing;
1103 aItems.push_back( lines );
1106 int height = yMax - yMin;
1110 double rowSpacing = height / double( eframe.
rows );
1111 double legendPosY = yMin + ( rowSpacing / 2 );
1113 for( i = 1; i < eframe.
rows; i++ )
1115 int newY =
KiROUND( yMin + ( rowSpacing * (
double) i ) );
1119 aItems.push_back( lines );
1122 char legendChar =
'A';
1124 for( i = 0; i < eframe.
rows; i++ )
1130 legendText->
SetText( wxString( legendChar ) );
1133 aItems.push_back( legendText );
1135 legendPosY += rowSpacing;
1146 aItems.push_back( lines );
1149 int width = xMax - xMin;
1153 double columnSpacing = width / double( eframe.
columns );
1154 double legendPosX = xMin + ( columnSpacing / 2 );
1156 for( i = 1; i < eframe.
columns; i++ )
1158 int newX =
KiROUND( xMin + ( columnSpacing * (
double) i ) );
1162 aItems.push_back( lines );
1165 char legendChar =
'1';
1167 for( i = 0; i < eframe.
columns; i++ )
1173 legendText->
SetText( wxString( legendChar ) );
1176 aItems.push_back( legendText );
1178 legendPosX += columnSpacing;
1189 aItems.push_back( lines );
1192 int width = xMax - xMin;
1196 double columnSpacing = width / double( eframe.
columns );
1197 double legendPosX = xMin + ( columnSpacing / 2 );
1199 for( i = 1; i < eframe.
columns; i++ )
1201 int newX =
KiROUND( xMin + ( columnSpacing * (
double) i ) );
1205 aItems.push_back( lines );
1208 char legendChar =
'1';
1210 for( i = 0; i < eframe.
columns; i++ )
1216 legendText->
SetText( wxString( legendChar ) );
1219 aItems.push_back( legendText );
1221 legendPosX += columnSpacing;
1228 const wxString& aNetClass )
1231 wxXmlNode* currentSegment = aSegmentsNode->GetChildren();
1236 int segmentCount =
countChildren( aSegmentsNode, wxT(
"segment" ) );
1238 while( currentSegment )
1240 bool labelled =
false;
1242 bool firstWireFound =
false;
1248 wxXmlNode* segmentAttribute = currentSegment->GetChildren();
1250 while( segmentAttribute )
1252 if( segmentAttribute->GetName() == wxT(
"wire" ) )
1261 if( !firstWireFound )
1263 firstWire = thisWire;
1264 firstWireFound =
true;
1270 if( !desc.labels.empty() && desc.labels.front()->GetText() == netName )
1273 for(
const SEG& seg : desc.segs )
1282 segDesc.
segs.push_back( thisWire );
1286 segmentAttribute = segmentAttribute->GetNext();
1289 segmentAttribute = currentSegment->GetChildren();
1291 while( segmentAttribute )
1293 wxString nodeName = segmentAttribute->GetName();
1295 if( nodeName == wxT(
"junction" ) )
1299 else if( nodeName == wxT(
"label" ) )
1303 wxASSERT( segDesc.
labels.empty()
1305 segDesc.
labels.push_back( label );
1308 else if( nodeName == wxT(
"pinref" ) )
1310 segmentAttribute->GetAttribute( wxT(
"gate" ) );
1311 wxString part = segmentAttribute->GetAttribute( wxT(
"part" ) );
1312 wxString
pin = segmentAttribute->GetAttribute( wxT(
"pin" ) );
1314 auto powerPort =
m_powerPorts.find( wxT(
"#" ) + part );
1322 else if( nodeName == wxT(
"wire" ) )
1332 segmentAttribute = segmentAttribute->GetNext();
1338 if( !labelled && firstWireFound )
1340 std::unique_ptr<SCH_TEXT> label;
1345 else if( segmentCount > 1 )
1350 label->SetPosition( firstWire.
A );
1355 if( firstWire.
B.
x > firstWire.
A.
x )
1360 screen->
Append( label.release() );
1364 currentSegment = currentSegment->GetNext();
1371 std::unique_ptr<SCH_SHAPE> poly = std::make_unique<SCH_SHAPE>( SHAPE_T::POLY );
1373 wxXmlNode* vertex = aPolygonNode->GetChildren();
1379 if( vertex->GetName() == wxT(
"vertex" ) )
1388 poly->GetPolyShape().Append( arc, -1, -1,
ARC_ACCURACY );
1392 poly->AddPoint( pt );
1396 prev_curve = evertex.
curve;
1399 vertex = vertex->GetNext();
1404 poly->SetFillMode( FILL_T::FILLED_SHAPE );
1406 return poly.release();
1421 endpoints =
SEG( start, end );
1425 std::unique_ptr<SCH_SHAPE> arc = std::make_unique<SCH_SHAPE>( SHAPE_T::ARC );
1428 arc->SetCenter( center );
1429 arc->SetStart( start );
1434 return arc.release();
1438 std::unique_ptr<SCH_LINE> line = std::make_unique<SCH_LINE>();
1440 line->SetStartPoint( start );
1441 line->SetEndPoint( end );
1445 return line.release();
1452 std::unique_ptr<SCH_SHAPE> circle = std::make_unique<SCH_SHAPE>( SHAPE_T::CIRCLE );
1457 circle->SetPosition( center );
1461 return circle.release();
1467 std::unique_ptr<SCH_SHAPE> rectangle = std::make_unique<SCH_SHAPE>( SHAPE_T::RECT );
1468 ERECT rect( aRectNode );
1476 VECTOR2I pos( rectangle->GetPosition() );
1477 VECTOR2I end( rectangle->GetEnd() );
1478 VECTOR2I center( rectangle->GetCenter() );
1483 rectangle->SetPosition( pos );
1484 rectangle->SetEnd( end );
1488 rectangle->SetFillMode( FILL_T::FILLED_SHAPE );
1490 return rectangle.release();
1496 std::unique_ptr<SCH_JUNCTION> junction = std::make_unique<SCH_JUNCTION>();
1501 junction->SetPosition( pos );
1503 return junction.release();
1515 std::unique_ptr<SCH_TEXT> label;
1521 label = std::make_unique<SCH_GLOBALLABEL>();
1523 label = std::make_unique<SCH_LABEL>();
1525 label->SetPosition( elabelpos );
1527 label->SetTextSize( textSize );
1533 label->Rotate90(
false );
1536 label->MirrorSpinStyle(
false );
1539 return label.release();
1543std::pair<VECTOR2I, const SEG*>
1545 const std::vector<SEG>& aLines )
const
1548 const SEG* nearestLine =
nullptr;
1550 float d, mindistance = std::numeric_limits<float>::max();
1553 for(
const SEG& line : aLines )
1556 d = sqrt(
abs( ( ( aPoint.
x - testpoint.
x ) ^ 2 ) + ( ( aPoint.
y - testpoint.
y ) ^ 2 ) ) );
1558 if( d < mindistance )
1561 nearestPoint = testpoint;
1562 nearestLine = &line;
1565 testpoint = line.Center();
1566 d = sqrt(
abs( ( ( aPoint.
x - testpoint.
x ) ^ 2 ) + ( ( aPoint.
y - testpoint.
y ) ^ 2 ) ) );
1568 if( d < mindistance )
1571 nearestPoint = testpoint;
1572 nearestLine = &line;
1576 d = sqrt(
abs( ( ( aPoint.
x - testpoint.
x ) ^ 2 ) + ( ( aPoint.
y - testpoint.
y ) ^ 2 ) ) );
1578 if( d < mindistance )
1581 nearestPoint = testpoint;
1582 nearestLine = &line;
1586 return std::make_pair( nearestPoint, nearestLine );
1605 m_reporter->
Report( wxString::Format(
_(
"Error parsing Eagle file. Could not find '%s' "
1606 "instance but it is referenced in the schematic." ),
1613 EPART* epart = part_it->second.get();
1615 wxString libraryname = epart->
library;
1618 symbolname.Replace( wxT(
"*" ), wxEmptyString );
1626 wxString altSymbolName = libraryname + wxT(
"_" ) + symbolname;
1629 wxString libIdSymbolName = altSymbolName;
1631 int unit =
m_eagleLibs[libraryname].GateUnit[gatename];
1636 auto p = elib->
package.find( kisymbolname );
1638 if( p != elib->
package.end() )
1639 package = p->second;
1641 LIB_SYMBOL* part = m_pi->LoadSymbol( getLibFileName().GetFullPath(), altSymbolName,
1642 m_properties.get() );
1646 part = m_pi->LoadSymbol( getLibFileName().GetFullPath(), kisymbolname,
1647 m_properties.get() );
1648 libIdSymbolName = kisymbolname;
1653 m_reporter->Report( wxString::Format(
_(
"Could not find '%s' in the imported library." ),
1659 LIB_ID libId( getLibName(), libIdSymbolName );
1660 std::unique_ptr<SCH_SYMBOL> symbol = std::make_unique<SCH_SYMBOL>();
1661 symbol->SetLibId( libId );
1662 symbol->SetUnit( unit );
1666 if( !package.IsEmpty() )
1668 wxString footprint = m_schematic->Prj().GetProjectName() + wxT(
":" ) + package;
1677 symbol->MirrorHorizontally( einstance.
x.
ToSchUnits() );
1680 std::vector<LIB_FIELD*> partFields;
1683 for(
const LIB_FIELD* field : partFields )
1685 symbol->GetFieldById( field->GetId() )->ImportValues( *field );
1686 symbol->GetFieldById( field->GetId() )->SetTextPos( (
VECTOR2I)symbol->GetPosition()
1687 + field->GetTextPos() );
1692 wxString reference = package.IsEmpty() ?
'#' + einstance.
part : einstance.
part;
1695 if( reference.find_last_not_of( wxT(
"0123456789" ) ) == ( reference.Length()-1 ) )
1696 reference.Append( wxT(
"0" ) );
1701 if( reference.find_first_not_of( wxT(
"0123456789" ) ) != 0 )
1702 reference.Prepend( wxT(
"UNK" ) );
1706 if( einstance.
part.find_first_not_of( wxT(
"#" ) ) != 0 )
1707 reference.Prepend( wxT(
"UNK" ) );
1710 referenceField->
SetText( reference );
1714 bool userValue = m_userValue.at( libIdSymbolName );
1717 if( userValue && epart->
value )
1723 valueField->
SetText( kisymbolname );
1729 for(
const auto& [ attrName, attrValue ] : epart->
attribute )
1732 SCH_FIELD* lastField = symbol->GetFieldById( symbol->GetFieldCount() - 1 );
1737 SCH_FIELD newField( newFieldPosition, symbol->GetFieldCount(), symbol.get() );
1740 newField.
SetText( attrValue );
1743 symbol->AddField( newField );
1746 for(
const auto& a : epart->
variant )
1749 field->
SetName( wxT(
"VARIANT_" ) + a.first );
1754 bool valueAttributeFound =
false;
1755 bool nameAttributeFound =
false;
1757 wxXmlNode* attributeNode = aInstanceNode->GetChildren();
1760 while( attributeNode )
1762 if( attributeNode->GetName() == wxT(
"attribute" ) )
1767 if( attr.
name.Lower() == wxT(
"name" ) )
1770 nameAttributeFound =
true;
1772 else if( attr.
name.Lower() == wxT(
"value" ) )
1775 valueAttributeFound =
true;
1779 field = symbol->FindField( attr.
name );
1796 bool spin = attr.
rot ? attr.
rot->
spin :
false;
1802 int reldegrees = ( absdegrees - rotation + 360.0 );
1809 else if( attributeNode->GetName() == wxT(
"variant" ) )
1811 wxString variantName, fieldValue;
1813 if( attributeNode->GetAttribute( wxT(
"name" ), &variantName )
1814 && attributeNode->GetAttribute( wxT(
"value" ), &fieldValue ) )
1817 field.
SetName( wxT(
"VARIANT_" ) + variantName );
1820 symbol->AddField( field );
1824 attributeNode = attributeNode->GetNext();
1830 if( !valueAttributeFound )
1831 symbol->GetField(
VALUE_FIELD )->SetVisible(
false );
1833 if( !nameAttributeFound )
1837 symbol->AddHierarchicalReference( m_sheetPath.Path(), reference, unit );
1843 wxCHECK( libSymbol, );
1845 symbol->SetLibSymbol(
new LIB_SYMBOL( *libSymbol ) );
1847 std::vector<LIB_PIN*> pins;
1848 symbol->GetLibPins( pins );
1851 m_connPoints[symbol->GetPinPhysicalPosition(
pin )].emplace(
pin );
1854 m_powerPorts[ reference ] = symbol->GetField(
VALUE_FIELD )->GetText();
1856 symbol->ClearFlags();
1858 screen->
Append( symbol.release() );
1868 wxXmlNode* symbolNode =
getChildrenNodes( libraryChildren, wxT(
"symbols" ) );
1872 wxString symbolName = symbolNode->GetAttribute( wxT(
"name" ) );
1873 aEagleLibrary->
SymbolNodes[symbolName] = symbolNode;
1874 symbolNode = symbolNode->GetNext();
1878 wxXmlNode* devicesetNode =
getChildrenNodes( libraryChildren, wxT(
"devicesets" ) );
1880 while( devicesetNode )
1885 wxString prefix = edeviceset.
prefix ? edeviceset.
prefix.
Get() : wxString( wxT(
"" ) );
1888 wxXmlNode* deviceNode =
getChildrenNodes( deviceSetChildren, wxT(
"devices" ) );
1897 wxString symbolName = edeviceset.
name + edevice.
name;
1898 symbolName.Replace( wxT(
"*" ), wxEmptyString );
1899 wxASSERT( !symbolName.IsEmpty() );
1906 std::unique_ptr<LIB_SYMBOL> libSymbol = std::make_unique<LIB_SYMBOL>( symbolName );
1909 wxXmlNode* gateNode =
getChildrenNodes( deviceSetChildren, wxT(
"gates" ) );
1910 int gates_count =
countChildren( deviceSetChildren[
"gates"], wxT(
"gate" ) );
1911 libSymbol->SetUnitCount( gates_count );
1912 libSymbol->LockUnits(
true );
1916 if( prefix.length() == 0 )
1928 bool ispower =
false;
1938 gateindex, egate.
name );
1941 gateNode = gateNode->GetNext();
1944 libSymbol->SetUnitCount( gates_count );
1946 if( gates_count == 1 && ispower )
1947 libSymbol->SetPower();
1954 aEagleLibrary->
package[symbolName];
1955 libSymbol->GetFootprintField().SetText( packageString );
1958 wxString libName = libSymbol->GetName();
1959 libSymbol->SetName( libName );
1965 libName = aEagleLibrary->
name + wxT(
"_" ) + libName;
1967 libSymbol->SetName( libName );
1972 aEagleLibrary->
KiCadSymbols.insert( libName, libSymbol.release() );
1979 deviceNode = deviceNode->GetNext();
1982 devicesetNode = devicesetNode->GetNext();
1985 return aEagleLibrary;
1990 EDEVICE* aDevice,
int aGateNumber,
const wxString& aGateName )
1992 wxString symbolName = aSymbolNode->GetAttribute( wxT(
"name" ) );
1993 std::vector<LIB_ITEM*> items;
1995 wxXmlNode* currentNode = aSymbolNode->GetChildren();
1997 bool showRefDes =
false;
1998 bool showValue =
false;
1999 bool ispower =
false;
2002 while( currentNode )
2004 wxString nodeName = currentNode->GetName();
2006 if( nodeName == wxT(
"circle" ) )
2008 aSymbol->AddDrawItem(
loadSymbolCircle( aSymbol, currentNode, aGateNumber ) );
2010 else if( nodeName == wxT(
"pin" ) )
2013 std::unique_ptr<LIB_PIN>
pin(
loadPin( aSymbol, currentNode, &ePin, aGateNumber ) );
2016 pin->SetType( ELECTRICAL_PINTYPE::PT_BIDI );
2022 if( ePin.
direction->Lower() == pinDir.first )
2024 pin->SetType( pinDir.second );
2026 if( pinDir.first == wxT(
"sup" ) )
2034 if( aDevice->
connects.size() != 0 )
2038 if( connect.
gate == aGateName &&
pin->GetName() == connect.
pin )
2040 wxArrayString pads = wxSplit( wxString( connect.
pad ),
' ' );
2042 pin->SetUnit( aGateNumber );
2045 if( pads.GetCount() > 1 )
2047 pin->SetNumberTextSize( 0 );
2050 for(
unsigned i = 0; i < pads.GetCount(); i++ )
2054 wxString padname( pads[i] );
2056 aSymbol->AddDrawItem( apin );
2065 pin->SetUnit( aGateNumber );
2066 pin->SetNumber( wxString::Format( wxT(
"%i" ), pincount ) );
2067 aSymbol->AddDrawItem(
pin.release() );
2070 else if( nodeName == wxT(
"polygon" ) )
2074 else if( nodeName == wxT(
"rectangle" ) )
2078 else if( nodeName == wxT(
"text" ) )
2080 std::unique_ptr<LIB_TEXT> libtext(
loadSymbolText( aSymbol, currentNode, aGateNumber ) );
2082 if( libtext->GetText() == wxT(
"${REFERENCE}" ) )
2089 showRefDes = currentNode->GetNodeContent() == wxT(
">NAME" );
2091 else if( libtext->GetText() == wxT(
"${VALUE}" ) )
2098 showValue = currentNode->GetNodeContent() == wxT(
">VALUE" );
2102 aSymbol->AddDrawItem( libtext.release() );
2105 else if( nodeName == wxT(
"wire" ) )
2107 aSymbol->AddDrawItem(
loadSymbolWire( aSymbol, currentNode, aGateNumber ) );
2109 else if( nodeName == wxT(
"frame" ) )
2111 std::vector<LIB_ITEM*> frameItems;
2117 item->SetParent( aSymbol.get() );
2118 item->SetUnit( aGateNumber );
2119 aSymbol->AddDrawItem( item );
2132 currentNode = currentNode->GetNext();
2139 aSymbol->GetFieldById(
VALUE_FIELD )->SetVisible(
false );
2141 return pincount == 1 ? ispower :
false;
2146 wxXmlNode* aCircleNode,
int aGateNumber )
2156 circle->
SetUnit( aGateNumber );
2163 wxXmlNode* aRectNode,
int aGateNumber )
2165 ERECT rect( aRectNode );
2181 rectangle->
SetEnd( end );
2184 rectangle->
SetUnit( aGateNumber );
2194 wxXmlNode* aWireNode,
int aGateNumber )
2213 double radius = sqrt( ( ( center.
x - begin.
x ) * ( center.
x - begin.
x ) ) +
2214 ( ( center.
y - begin.
y ) * ( center.
y - begin.
y ) ) );
2220 begin = center + centerStartVector;
2252 wxXmlNode* aPolygonNode,
int aGateNumber )
2256 wxXmlNode* vertex = aPolygonNode->GetChildren();
2262 if( vertex->GetName() == wxT(
"vertex" ) )
2279 prev_curve = evertex.
curve;
2282 vertex = vertex->GetNext();
2294 EPIN* aEPin,
int aGateNumber )
2296 std::unique_ptr<LIB_PIN>
pin = std::make_unique<LIB_PIN>( aSymbol.get() );
2299 pin->SetUnit( aGateNumber );
2305 case 0:
pin->SetOrientation(
'R' );
break;
2306 case 90:
pin->SetOrientation(
'U' );
break;
2307 case 180:
pin->SetOrientation(
'L' );
break;
2308 case 270:
pin->SetOrientation(
'D' );
break;
2309 default: wxFAIL_MSG( wxString::Format( wxT(
"Unhandled orientation (%d degrees)." ), roti ) );
2318 if( length == wxT(
"short" ) )
2320 else if( length == wxT(
"middle" ) )
2322 else if( length == wxT(
"long" ) )
2324 else if( length == wxT(
"point" ) )
2333 if( visible == wxT(
"off" ) )
2335 pin->SetNameTextSize( 0 );
2336 pin->SetNumberTextSize( 0 );
2338 else if( visible == wxT(
"pad" ) )
2340 pin->SetNameTextSize( 0 );
2342 else if( visible == wxT(
"pin" ) )
2344 pin->SetNumberTextSize( 0 );
2358 if( function == wxT(
"dot" ) )
2359 pin->SetShape( GRAPHIC_PINSHAPE::INVERTED );
2360 else if( function == wxT(
"clk" ) )
2361 pin->SetShape( GRAPHIC_PINSHAPE::CLOCK );
2362 else if( function == wxT(
"dotclk" ) )
2363 pin->SetShape( GRAPHIC_PINSHAPE::INVERTED_CLOCK );
2366 return pin.release();
2371 wxXmlNode* aLibText,
int aGateNumber )
2373 std::unique_ptr<LIB_TEXT> libtext = std::make_unique<LIB_TEXT>( aSymbol.get() );
2374 ETEXT etext( aLibText );
2376 libtext->SetUnit( aGateNumber );
2379 const wxString& eagleText = aLibText->GetNodeContent();
2380 wxString adjustedText;
2381 wxStringTokenizer tokenizer( eagleText,
"\r\n" );
2384 while( tokenizer.HasMoreTokens() )
2386 wxString tmp =
interpretText( tokenizer.GetNextToken().Trim(
true ).Trim(
false ) );
2388 if( tokenizer.HasMoreTokens() )
2391 adjustedText += tmp;
2394 libtext->SetText( adjustedText.IsEmpty() ? wxString( wxT(
"~" ) ) : adjustedText );
2397 return libtext.release();
2403 EFRAME eframe( aFrameNode );
2411 std::swap( xMin, xMax );
2414 std::swap( yMin, yMax );
2422 aItems.push_back( lines );
2426 lines =
new LIB_SHAPE(
nullptr, SHAPE_T::POLY );
2431 aItems.push_back( lines );
2434 int height = yMax - yMin;
2438 double rowSpacing = height / double( eframe.
rows );
2439 double legendPosY = yMax - ( rowSpacing / 2 );
2441 for( i = 1; i < eframe.
rows; i++ )
2443 int newY =
KiROUND( yMin + ( rowSpacing * (
double) i ) );
2444 lines =
new LIB_SHAPE(
nullptr, SHAPE_T::POLY );
2447 aItems.push_back( lines );
2450 char legendChar =
'A';
2452 for( i = 0; i < eframe.
rows; i++ )
2456 legendText->
SetText( wxString( legendChar ) );
2459 aItems.push_back( legendText );
2461 legendPosY -= rowSpacing;
2467 lines =
new LIB_SHAPE(
nullptr, SHAPE_T::POLY );
2472 aItems.push_back( lines );
2475 int height = yMax - yMin;
2479 double rowSpacing = height / double( eframe.
rows );
2480 double legendPosY = yMax - ( rowSpacing / 2 );
2482 for( i = 1; i < eframe.
rows; i++ )
2484 int newY =
KiROUND( yMin + ( rowSpacing * (
double) i ) );
2485 lines =
new LIB_SHAPE(
nullptr, SHAPE_T::POLY );
2488 aItems.push_back( lines );
2491 char legendChar =
'A';
2493 for( i = 0; i < eframe.
rows; i++ )
2497 legendText->
SetText( wxString( legendChar ) );
2500 aItems.push_back( legendText );
2502 legendPosY -= rowSpacing;
2508 lines =
new LIB_SHAPE(
nullptr, SHAPE_T::POLY );
2513 aItems.push_back( lines );
2516 int width = xMax - xMin;
2520 double columnSpacing = width / double( eframe.
columns );
2521 double legendPosX = xMin + ( columnSpacing / 2 );
2523 for( i = 1; i < eframe.
columns; i++ )
2525 int newX =
KiROUND( xMin + ( columnSpacing * (
double) i ) );
2526 lines =
new LIB_SHAPE(
nullptr, SHAPE_T::POLY );
2529 aItems.push_back( lines );
2532 char legendChar =
'1';
2534 for( i = 0; i < eframe.
columns; i++ )
2538 legendText->
SetText( wxString( legendChar ) );
2541 aItems.push_back( legendText );
2543 legendPosX += columnSpacing;
2549 lines =
new LIB_SHAPE(
nullptr, SHAPE_T::POLY );
2554 aItems.push_back( lines );
2557 int width = xMax - xMin;
2561 double columnSpacing = width / double( eframe.
columns );
2562 double legendPosX = xMin + ( columnSpacing / 2 );
2564 for( i = 1; i < eframe.
columns; i++ )
2566 int newX =
KiROUND( xMin + ( columnSpacing * (
double) i ) );
2567 lines =
new LIB_SHAPE(
nullptr, SHAPE_T::POLY );
2570 aItems.push_back( lines );
2573 char legendChar =
'1';
2575 for( i = 0; i < eframe.
columns; i++ )
2579 legendText->
SetText( wxString( legendChar ) );
2582 aItems.push_back( legendText );
2584 legendPosX += columnSpacing;
2592 std::unique_ptr<SCH_TEXT> schtext = std::make_unique<SCH_TEXT>();
2595 const wxString& eagleText = aSchText->GetNodeContent();
2596 wxString adjustedText;
2597 wxStringTokenizer tokenizer( eagleText,
"\r\n" );
2600 while( tokenizer.HasMoreTokens() )
2602 wxString tmp =
interpretText( tokenizer.GetNextToken().Trim(
true ).Trim(
false ) );
2604 if( tokenizer.HasMoreTokens() )
2607 adjustedText += tmp;
2610 schtext->SetText( adjustedText.IsEmpty() ? wxString( wxT(
"\" \"" ) ) :
escapeName( adjustedText ) );
2613 schtext->SetItalic(
false );
2615 return schtext.release();
2623 if( aAttribs.
ratio )
2634 bool mirror = aAttribs.
rot ? aAttribs.
rot->
mirror :
false;
2635 bool spin = aAttribs.
rot ? aAttribs.
rot->
spin :
false;
2661 auto onIntersection =
2670 for(
SCH_TEXT* label : segDesc.labels )
2673 const SEG* segAttached = segDesc.LabelAttached( label );
2675 if( segAttached && !onIntersection( labelPos ) )
2689 VECTOR2I wireDirection( segAttached->
B - segAttached->
A );
2691 const VECTOR2I origPos( labelPos );
2694 bool checkPositive =
true, checkNegative =
true,
move =
false;
2698 while( ( !
move || onIntersection( labelPos ) ) && ( checkPositive || checkNegative ) )
2703 if( trial % 2 == 1 )
2705 labelPos =
VECTOR2I( origPos + wireDirection * trial / 2 );
2706 move = checkPositive = segAttached->
Contains( labelPos );
2710 labelPos =
VECTOR2I( origPos - wireDirection * trial / 2 );
2711 move = checkNegative = segAttached->
Contains( labelPos );
2730 wxTextFile tempFile;
2732 tempFile.Open( aFileName );
2736 firstline = tempFile.GetFirstLine();
2737 wxString secondline = tempFile.GetNextLine();
2738 wxString thirdline = tempFile.GetNextLine();
2741 return firstline.StartsWith( wxT(
"<?xml" ) )
2742 && secondline.StartsWith( wxT(
"<!DOCTYPE eagle SYSTEM" ) )
2743 && thirdline.StartsWith( wxT(
"<eagle version" ) );
2755 if( !item->IsType( { SCH_LABEL_LOCATE_ANY_T } ) )
2759 item->SetPosition( aNewEndPoint );
2772 std::vector<SCH_LINE*> buses;
2773 std::vector<SCH_LINE*> wires;
2784 buses.push_back( line );
2785 else if( line->
IsWire() )
2786 wires.push_back( line );
2791 VECTOR2I wireStart = wire->GetStartPoint();
2792 VECTOR2I wireEnd = wire->GetEndPoint();
2796 VECTOR2I busStart = bus->GetStartPoint();
2797 VECTOR2I busEnd = bus->GetEndPoint();
2800 [](
int signX,
int signY ) ->
VECTOR2I
2812 if( wireStart.
y == wireEnd.
y && busStart.
x == busEnd.
x )
2816 if( testBusHit( wireStart ) )
2820 if( wireEnd.
x < busStart.
x )
2827 VECTOR2I p = wireStart + entrySize( -1, 0 );
2829 if( testBusHit( wireStart + entrySize( 0, -1 ) ) )
2838 screen->
Append( busEntry );
2840 wire->SetStartPoint( p );
2842 else if( testBusHit( wireStart + entrySize( 0, 1 ) ) )
2851 screen->
Append( busEntry );
2853 wire->SetStartPoint( p );
2859 screen->
Append( marker );
2869 VECTOR2I p = wireStart + entrySize( 1, 0 );
2871 if( testBusHit( wireStart + entrySize( 0, -1 ) ) )
2880 screen->
Append( busEntry );
2882 wire->SetStartPoint( p );
2884 else if( testBusHit( wireStart + entrySize( 0, 1 ) ) )
2893 screen->
Append( busEntry );
2895 wire->SetStartPoint( p );
2901 screen->
Append( marker );
2907 else if( testBusHit( wireEnd ) )
2911 if( wireStart.
x < busStart.
x )
2918 VECTOR2I p = wireEnd + entrySize( -1, 0 );
2920 if( testBusHit( wireEnd + entrySize( 0, -1 ) ) )
2929 screen->
Append( busEntry );
2931 wire->SetEndPoint( p );
2933 else if( testBusHit( wireEnd + entrySize( 0, -1 ) ) )
2942 screen->
Append( busEntry );
2943 moveLabels( wire, wireEnd + entrySize( -1, 0 ) );
2944 wire->SetEndPoint( wireEnd + entrySize( -1, 0 ) );
2950 screen->
Append( marker );
2960 VECTOR2I p = wireEnd + entrySize( 1, 0 );
2962 if( testBusHit( wireEnd + entrySize( 0, -1 ) ) )
2971 screen->
Append( busEntry );
2973 wire->SetEndPoint( p );
2975 else if( testBusHit( wireEnd + entrySize( 0, 1 ) ) )
2984 screen->
Append( busEntry );
2986 wire->SetEndPoint( p );
2992 screen->
Append( marker );
2999 else if( wireStart.
x == wireEnd.
x && busStart.
y == busEnd.
y )
3003 if( testBusHit( wireStart ) )
3007 if( wireEnd.
y < busStart.
y )
3015 VECTOR2I p = wireStart + entrySize( 0, -1 );
3017 if( testBusHit( wireStart + entrySize( -1, 0 ) ) )
3027 screen->
Append( busEntry );
3029 wire->SetStartPoint( p );
3031 else if( testBusHit( wireStart + entrySize( 1, 0 ) ) )
3041 screen->
Append( busEntry );
3043 wire->SetStartPoint( p );
3049 screen->
Append( marker );
3060 VECTOR2I p = wireStart + entrySize( 0, 1 );
3062 if( testBusHit( wireStart + entrySize( -1, 0 ) ) )
3072 screen->
Append( busEntry );
3074 wire->SetStartPoint( p );
3076 else if( testBusHit( wireStart + entrySize( 1, 0 ) ) )
3086 screen->
Append( busEntry );
3088 wire->SetStartPoint( p );
3094 screen->
Append( marker );
3100 else if( testBusHit( wireEnd ) )
3104 if( wireStart.
y < busStart.
y )
3112 VECTOR2I p = wireEnd + entrySize( 0, -1 );
3114 if( testBusHit( wireEnd + entrySize( -1, 0 ) ) )
3124 screen->
Append( busEntry );
3126 wire->SetEndPoint( p );
3128 else if( testBusHit( wireEnd + entrySize( 1, 0 ) ) )
3138 screen->
Append( busEntry );
3140 wire->SetEndPoint( p );
3146 screen->
Append( marker );
3157 VECTOR2I p = wireEnd + entrySize( 0, 1 );
3159 if( testBusHit( wireEnd + entrySize( -1, 0 ) ) )
3169 screen->
Append( busEntry );
3171 wire->SetEndPoint( p );
3173 else if( testBusHit( wireEnd + entrySize( 1, 0 ) ) )
3183 screen->
Append( busEntry );
3185 wire->SetEndPoint( p );
3191 screen->
Append( marker );
3202 if( testBusHit( wireStart ) )
3204 VECTOR2I wirevector = wireStart - wireEnd;
3206 if( wirevector.
x > 0 )
3208 if( wirevector.
y > 0 )
3210 VECTOR2I p = wireStart + entrySize( -1, -1 );
3213 screen->
Append( busEntry );
3216 wire->SetStartPoint( p );
3220 VECTOR2I p = wireStart + entrySize( -1, 1 );
3223 screen->
Append( busEntry );
3226 wire->SetStartPoint( p );
3231 if( wirevector.
y > 0 )
3233 VECTOR2I p = wireStart + entrySize( 1, -1 );
3236 screen->
Append( busEntry );
3239 wire->SetStartPoint( p );
3243 VECTOR2I p = wireStart + entrySize( 1, 1 );
3246 screen->
Append( busEntry );
3249 wire->SetStartPoint( p );
3255 else if( testBusHit( wireEnd ) )
3257 VECTOR2I wirevector = wireStart - wireEnd;
3259 if( wirevector.
x > 0 )
3261 if( wirevector.
y > 0 )
3263 VECTOR2I p = wireEnd + entrySize( 1, 1 );
3266 screen->
Append( busEntry );
3269 wire->SetEndPoint( p );
3273 VECTOR2I p = wireEnd + entrySize( 1, -1 );
3276 screen->
Append( busEntry );
3279 wire->SetEndPoint( p );
3284 if( wirevector.
y > 0 )
3286 VECTOR2I p = wireEnd + entrySize( -1, 1 );
3289 screen->
Append( busEntry );
3292 wire->SetEndPoint( p );
3296 VECTOR2I p = wireEnd + entrySize( -1, -1 );
3299 screen->
Append( busEntry );
3302 wire->SetEndPoint( p );
3318 for(
const SEG& seg : segs )
3320 if( seg.Contains( labelPos ) )
3332 wxCHECK( aSymbol && aPin,
false );
3340 const auto& items = pointIt->second;
3342 wxCHECK( items.find( aPin ) != items.end(),
false );
3344 return items.size() > 1;
3358 int unit = aSymbol->
GetUnit();
3360 std::vector<LIB_PIN*> pins;
3362 std::set<int> missingUnits;
3367 if(
pin->GetType() == ELECTRICAL_PINTYPE::PT_POWER_IN )
3369 bool pinInUnit = !unit ||
pin->GetUnit() == unit;
3383 switch(
pin->GetOrientation() )
3391 aScreen->
Append( netLabel );
3394 else if( aUpdateSet )
3399 wxASSERT(
pin->GetUnit() );
3400 missingUnits.insert(
pin->GetUnit() );
3413 entry.
cmp = aSymbol;
3414 entry.
units.emplace( unit,
false );
3419 cmpIt->second.units[unit] =
false;
3422 if( !missingUnits.empty() )
3425 entry.
cmp = aSymbol;
3428 for(
int i : missingUnits )
3430 if( entry.
units.find( i ) != entry.
units.end() )
3431 entry.
units.emplace( i,
true );
3443 wxString ret = wxT(
"{" );
3445 wxStringTokenizer tokenizer( aEagleName, wxT(
"," ) );
3447 while( tokenizer.HasMoreTokens() )
3449 wxString member = tokenizer.GetNextToken();
3456 if( member.Freq(
'!' ) % 2 > 0 )
3457 member << wxT(
"!" );
3459 ret << member << wxS(
" " );
constexpr EDA_IU_SCALE schIUScale
coord_type GetHeight() const
coord_type GetWidth() const
coord_type GetLeft() const
const Vec & GetSize() 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
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)
void SetTextThickness(int aWidth)
The TextThickness is that set by the user.
GR_TEXT_V_ALIGN_T GetVertJustify() const
void SetTextSize(const VECTOR2I &aNewSize)
virtual void SetText(const wxString &aText)
virtual void SetTextAngle(const EDA_ANGLE &aAngle)
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.
Field object used in symbol libraries.
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 '_'.
The base class for drawable items used by schematic library symbols.
void SetPosition(const VECTOR2I &aPosition) override
void SetNumber(const wxString &aNumber)
void SetStroke(const STROKE_PARAMS &aStroke)
void AddPoint(const VECTOR2I &aPosition)
void SetPosition(const VECTOR2I &aPosition) override
VECTOR2I GetCenter() const
VECTOR2I GetPosition() const override
Define a library symbol object.
LIB_FIELD * GetFieldById(int aId) const
Return pointer to the requested field.
void GetFields(std::vector< LIB_FIELD * > &aList)
Return a list of fields within this symbol.
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.
Define a symbol library graphical text item.
VECTOR2I GetPosition() const override
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 SetWidthMils(int aWidthInMils)
void SetHeightMils(int aHeightInMils)
const VECTOR2I GetSizeIU(double aIUScale) const
Gets the page size in internal units.
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).
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.
void loadTextAttributes(EDA_TEXT *aText, const ETEXT &aAttribs) const
std::map< wxString, EAGLE_MISSING_CMP > m_missingCmps
LIB_SHAPE * loadSymbolPolyLine(std::unique_ptr< LIB_SYMBOL > &aSymbol, wxXmlNode *aPolygonNode, int aGateNumber)
SCH_TEXT * loadLabel(wxXmlNode *aLabelNode, const wxString &aNetName)
void addBusEntries()
This function finds best way to place a bus entry symbol for when an Eagle wire segment ends on an Ea...
SCH_SHEET * m_rootSheet
The root sheet of the schematic being loaded.
LIB_ITEM * loadSymbolWire(std::unique_ptr< LIB_SYMBOL > &aSymbol, wxXmlNode *aWireNode, int aGateNumber)
const wxString GetLibraryFileExtension() const override
Return the library file extension for the SCH_PLUGIN object.
unsigned m_totalCount
for progress reporting
std::unique_ptr< STRING_UTF8_MAP > m_properties
Library plugin properties.
std::vector< SEG_DESC > m_segments
Nets as defined in the <nets> sections of an Eagle schematic file.
void loadSchematic(wxXmlNode *aSchematicNode)
SCH_SHEET * getCurrentSheet()
void countNets(wxXmlNode *aSchematicNode)
SCH_SHAPE * loadCircle(wxXmlNode *aCircleNode)
SCH_TEXT * loadPlainText(wxXmlNode *aSchText)
int GetModifyHash() const override
Return the modification hash from the library cache.
SCH_SCREEN * getCurrentScreen()
const double ARC_ACCURACY
void loadFieldAttributes(LIB_FIELD *aField, const LIB_TEXT *aText) const
Move net labels that are detached from any wire to the nearest wire.
const wxString GetName() const override
Return a brief hard coded name for this SCH_PLUGIN.
std::map< wxString, int > m_netCounts
wxString m_version
Eagle file version.
void loadInstance(wxXmlNode *aInstanceNode)
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.
std::vector< VECTOR2I > m_wireIntersections
Wires and labels of a single connection (segment in Eagle nomenclature)
void loadDrawing(wxXmlNode *aDrawingNode)
LIB_SHAPE * loadSymbolRectangle(std::unique_ptr< LIB_SYMBOL > &aSymbol, wxXmlNode *aRectNode, int aGateNumber)
SCH_JUNCTION * loadJunction(wxXmlNode *aJunction)
void loadFrame(wxXmlNode *aFrameNode, std::vector< SCH_ITEM * > &aItems)
const wxString GetFileExtension() const override
Return the file extension for the SCH_PLUGIN.
REPORTER * m_reporter
Reporter for warnings/errors.
EAGLE_LIBRARY * loadLibrary(wxXmlNode *aLibraryNode, EAGLE_LIBRARY *aEagleLib)
LIB_PIN * loadPin(std::unique_ptr< LIB_SYMBOL > &aSymbol, wxXmlNode *, EPIN *epin, int aGateNumber)
std::map< VECTOR2I, std::set< const EDA_ITEM * > > m_connPoints
wxString translateEagleBusName(const wxString &aEagleName) const
Translate an Eagle-style bus name into one that is KiCad-compatible.
bool loadSymbol(wxXmlNode *aSymbolNode, std::unique_ptr< LIB_SYMBOL > &aSymbol, EDEVICE *aDevice, int aGateNumber, const wxString &aGateName)
std::unordered_map< wxString, bool > m_userValue
deviceset/@uservalue for device.
wxString m_libName
Library name to save symbols.
wxFileName getLibFileName()
Checks if there are other wires or pins at the position of the tested pin.
void loadLayerDefs(wxXmlNode *aLayers)
LIB_SHAPE * loadSymbolCircle(std::unique_ptr< LIB_SYMBOL > &aSymbol, wxXmlNode *aCircleNode, int aGateNumber)
LIB_TEXT * loadSymbolText(std::unique_ptr< LIB_SYMBOL > &aSymbol, wxXmlNode *aLibText, int aGateNumber)
std::map< wxString, EAGLE_LIBRARY > m_eagleLibs
void addImplicitConnections(SCH_SYMBOL *aSymbol, SCH_SCREEN *aScreen, bool aUpdateSet)
Create net labels to emulate implicit connections in Eagle.
unsigned m_lastProgressCount
void loadSegments(wxXmlNode *aSegmentsNode, const wxString &aNetName, const wxString &aNetClass)
std::pair< VECTOR2I, const SEG * > findNearestLinePoint(const VECTOR2I &aPoint, const std::vector< SEG > &aLines) const
std::map< int, SCH_LAYER_ID > m_layerMap
SCH_SHEET * Load(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_PLUGIN implementation knows about,...
SCH_SHAPE * loadRectangle(wxXmlNode *aRectNode)
SCH_LAYER_ID kiCadLayer(int aEagleLayer)
Return the matching layer or return LAYER_NOTES.
bool checkConnections(const SCH_SYMBOL *aSymbol, const LIB_PIN *aPin) const
SCH_PLUGIN::SCH_PLUGIN_RELEASER m_pi
PI to create KiCad symbol library.
void loadSheet(wxXmlNode *aSheetNode, int sheetcount)
SCHEMATIC * m_schematic
Passed to Load(), the schematic object being loaded.
PROGRESS_REPORTER * m_progressReporter
optional; may be nullptr
SCH_SHAPE * loadPolyLine(wxXmlNode *aPolygonNode)
SCH_ITEM * loadWire(wxXmlNode *aWireNode, SEG &endpoints)
bool CheckHeader(const wxString &aFileName) override
Return true if the first line in aFileName begins with the expected header.
void moveLabels(SCH_LINE *aWire, const VECTOR2I &aNewEndPoint)
Move any labels on the wire to the new end point of the wire.
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 SetTextSpinStyle(TEXT_SPIN_STYLE aSpinStyle) override
Set a spin or rotation angle, along with specific horizontal and vertical justification styles with e...
Base class for any item which can be embedded within the SCHEMATIC container class,...
SCH_ITEM * Duplicate(bool doClone=false) const
Routine to create a new copy of given item.
void SetPosition(const VECTOR2I &aPosition) override
static const char * PropBuffering
The property used internally by the plugin to enable cache buffering which prevents the library file ...
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 set(SCH_PLUGIN *aPlugin)
virtual void SaveSymbol(const wxString &aLibraryPath, const LIB_SYMBOL *aSymbol, const STRING_UTF8_MAP *aProperties=nullptr)
Write aSymbol to an existing library located at aLibraryPath.
virtual void SaveLibrary(const wxString &aFileName, const STRING_UTF8_MAP *aProperties=nullptr)
virtual LIB_SYMBOL * LoadSymbol(const wxString &aLibraryPath, const wxString &aPartName, const STRING_UTF8_MAP *aProperties=nullptr)
Load a LIB_SYMBOL object having aPartName from the aLibraryPath containing a library format that this...
virtual void CreateSymbolLib(const wxString &aLibraryPath, const STRING_UTF8_MAP *aProperties=nullptr)
Create a new empty symbol library at aLibraryPath.
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 AddPoint(const VECTOR2I &aPosition)
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.
VECTOR2I GetPinPhysicalPosition(const LIB_PIN *Pin) const
std::unique_ptr< LIB_SYMBOL > & GetLibSymbolRef()
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_PLUGIN obje...
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)
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.
int GetPenSizeForBold(int aTextSize)
const std::string KiCadSymbolLibFileExtension
const std::string KiCadSchematicFileExtension
#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 '
[email protected]')
SYMBOL_ORIENTATION_T
enum used in RotationMiroir()
Definition of the SCH_SHEET_PATH and SCH_SHEET_LIST classes for Eeschema.
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:...
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
std::map< int, bool > units
Segments representing wires for intersection checking.
const SEG * LabelAttached(const SCH_TEXT *aLabel) const
< Test if a particular label is attached to any of the stored segments
std::vector< SCH_TEXT * > labels
Definition for symbol library class.
@ 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)
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.