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>
95static int countChildren( wxXmlNode* aCurrentNode,
const wxString& aName )
101 aCurrentNode = aCurrentNode->GetChildren();
103 while( aCurrentNode )
105 if( aCurrentNode->GetName() == aName )
109 aCurrentNode = aCurrentNode->GetNext();
122 bbox.
Merge( item->GetBoundingBox() );
131 return aPinName.BeforeFirst(
'@' );
144 wxCHECK( currentSheet,
nullptr );
183 std::vector<ELAYER> eagleLayers;
186 wxXmlNode* layerNode = aLayers->GetChildren();
190 ELAYER elayer( layerNode );
191 eagleLayers.push_back( elayer );
193 layerNode = layerNode->GetNext();
197 for(
const ELAYER& elayer : eagleLayers )
216 if( elayer.name == wxT(
"Nets" ) )
218 else if( elayer.name == wxT(
"Info" ) || elayer.name == wxT(
"Guide" ) )
220 else if( elayer.name == wxT(
"Busses" ) )
236 int roti = int( eagleDegrees );
246 wxASSERT_MSG(
false, wxString::Format( wxT(
"Unhandled orientation (%d degrees)" ), roti ) );
254 bool aMirror,
bool aSpin,
int aAbsDegress )
256 int align = aEagleAlignment;
258 if( aRelDegress == 90 )
262 else if( aRelDegress == 180 )
264 else if( aRelDegress == 270 )
270 if( aMirror ==
true )
272 if( aAbsDegress == 90 || aAbsDegress == 270 )
283 else if( aAbsDegress == 0 || aAbsDegress == 180 )
356 m_progressReporter( nullptr ),
358 m_lastProgressCount( 0 ),
375 return wxT(
"EAGLE" );
387 const unsigned PROGRESS_DELTA = 5;
409 wxASSERT( !aFileName || aSchematic !=
nullptr );
424 wxXmlDocument xmlDocument;
425 wxFFileInputStream stream(
m_filename.GetFullPath() );
428 wxTextInputStream
text( stream );
429 wxString line =
text.ReadLine();
430 if( !line.StartsWith( wxT(
"<?xml" ) ) )
432 THROW_IO_ERROR( wxString::Format(
_(
"'%s' is an Eagle binary-format schematic file; "
433 "only Eagle XML-format schematics can be imported." ),
437 if( !stream.IsOk() || !xmlDocument.Load( stream ) )
444 unique_ptr<SCH_SHEET> deleter( aAppendToMe ?
nullptr :
m_rootSheet );
451 wxCHECK_MSG( aSchematic->
IsValid(),
nullptr,
452 wxT(
"Can't append to a schematic with no root!" ) );
475 wxCHECK_MSG( libTable,
nullptr, wxT(
"Could not load symbol lib table." ) );
477 m_pi.
set( SCH_IO_MGR::FindPlugin( SCH_IO_MGR::SCH_KICAD ) );
487 wxString libTableUri = wxT(
"${KIPRJMOD}/" ) +
getLibFileName().GetFullName();
500 libTable->
Format( &formatter, 0 );
509 wxXmlNode* currentNode = xmlDocument.GetRoot();
513 m_version = currentNode->GetAttribute( wxT(
"version" ), wxT(
"0.0" ) );
540 auto layers = drawingChildren[
"layers"];
550 auto schematic = drawingChildren[
"schematic"];
563 wxXmlNode* sheetNode =
getChildrenNodes( schematicChildren, wxT(
"sheets" ) );
575 wxString netName = netNode->GetAttribute( wxT(
"name" ) );
583 netNode = netNode->GetNext();
586 sheetNode = sheetNode->GetNext();
595 wxXmlNode* partNode =
getChildrenNodes( schematicChildren, wxT(
"parts" ) );
596 wxXmlNode* libraryNode =
getChildrenNodes( schematicChildren, wxT(
"libraries" ) );
597 wxXmlNode* sheetNode =
getChildrenNodes( schematicChildren, wxT(
"sheets" ) );
603 []( wxXmlNode* aNode ) ->
unsigned
610 aNode = aNode->GetNext();
626 wxXmlNode* devicesetNode =
getChildrenNodes( libraryChildren, wxT(
"devicesets" ) );
628 while( devicesetNode )
631 wxXmlNode* deviceNode =
getChildrenNodes( deviceSetChildren, wxT(
"devices" ) );
632 wxXmlNode* gateNode =
getChildrenNodes( deviceSetChildren, wxT(
"gates" ) );
634 m_totalCount += count_nodes( deviceNode ) * count_nodes( gateNode );
636 devicesetNode = devicesetNode->GetNext();
639 libraryNode = libraryNode->GetNext();
654 sheetNode = sheetNode->GetNext();
665 std::unique_ptr<EPART> epart = std::make_unique<EPART>( partNode );
668 m_partlist[epart->name.Upper()] = std::move( epart );
669 partNode = partNode->GetNext();
677 wxString libName = libraryNode->GetAttribute( wxT(
"name" ) );
680 elib->
name = libName;
684 libraryNode = libraryNode->GetNext();
698 int sheetCount =
countChildren( sheetNode->GetParent(), wxT(
"sheet" ) );
714 std::unique_ptr<SCH_SHEET> sheet = std::make_unique<SCH_SHEET>(
m_rootSheet, pos );
716 sheet->SetScreen( screen );
719 wxCHECK2( sheet && screen,
continue );
721 wxString pageNo = wxString::Format( wxT(
"%d" ), i );
731 wxCHECK2( currentScreen,
continue );
733 currentScreen->
Append( sheet.release() );
735 sheetNode = sheetNode->GetNext();
753 sheetNode = sheetNode->GetNext();
765 int maxY = sheetBbox.
GetY();
772 const SCH_SYMBOL* origSymbol = cmp.second.cmp;
774 for(
auto& unitEntry : cmp.second.units )
776 if( unitEntry.second ==
false )
780 int unit = unitEntry.first;
784 symbol->SetUnitSelection( &sheetpath, unit );
785 symbol->SetUnit( unit );
786 symbol->SetOrientation( 0 );
787 symbol->AddHierarchicalReference( sheetpath.
Path(), reference, unit );
790 BOX2I cmpBbox = symbol->GetBoundingBox();
791 int posY = newCmpPosition.
y + cmpBbox.
GetHeight();
792 symbol->SetPosition(
VECTOR2I( newCmpPosition.
x, posY ) );
794 maxY = std::max( maxY, posY );
796 if( newCmpPosition.
x >= pageSizeIU.
x )
815 wxXmlNode* descriptionNode =
getChildrenNodes( sheetChildren, wxT(
"description" ) );
822 std::string filename;
826 if( descriptionNode )
828 des = descriptionNode->GetContent();
829 des.Replace( wxT(
"\n" ), wxT(
"_" ),
true );
831 filename = des.ToStdString();
835 filename = wxString::Format( wxT(
"%s_%d" ),
m_filename.GetName(), aSheetIndex );
836 sheetNameField.
SetText( filename );
840 replace( filename.begin(), filename.end(),
' ',
'_' );
843 fn.SetName( filename );
846 filenameField.
SetText( fn.GetFullName() );
856 wxXmlNode* instanceNode =
getChildrenNodes( sheetChildren, wxT(
"instances" ) );
858 while( instanceNode )
863 instanceNode = instanceNode->GetNext();
883 busNode = busNode->GetNext();
895 wxString netName = netNode->GetAttribute( wxT(
"name" ) );
896 wxString netClass = netNode->GetAttribute( wxT(
"class" ) );
902 netNode = netNode->GetNext();
926 wxString nodeName = plainNode->GetName();
928 if( nodeName == wxT(
"polygon" ) )
932 else if( nodeName == wxT(
"wire" ) )
937 else if( nodeName == wxT(
"text" ) )
941 else if( nodeName == wxT(
"circle" ) )
945 else if( nodeName == wxT(
"rectangle" ) )
949 else if( nodeName == wxT(
"frame" ) )
951 std::vector<SCH_ITEM*> frameItems;
959 plainNode = plainNode->GetNext();
972 if( pageSizeIU.
x < targetSheetSize.
x )
975 if( pageSizeIU.
y < targetSheetSize.
y )
982 VECTOR2I sheetcentre( pageSizeIU.
x / 2, pageSizeIU.
y / 2 );
986 VECTOR2I translation = sheetcentre - itemsCentre;
1000 std::vector<SCH_ITEM*> allItems;
1002 std::copy( screen->
Items().
begin(), screen->
Items().
end(), std::back_inserter( allItems ) );
1006 item->SetPosition( item->GetPosition() + translation );
1011 label->AutoplaceFields( screen,
false );
1022 EFRAME eframe( aFrameNode );
1030 std::swap( xMin, xMax );
1033 std::swap( yMin, yMax );
1041 aItems.push_back( lines );
1050 aItems.push_back( lines );
1053 int height = yMax - yMin;
1057 double rowSpacing = height / double( eframe.
rows );
1058 double legendPosY = yMin + ( rowSpacing / 2 );
1060 for( i = 1; i < eframe.
rows; i++ )
1062 int newY =
KiROUND( yMin + ( rowSpacing * (
double) i ) );
1066 aItems.push_back( lines );
1069 char legendChar =
'A';
1071 for( i = 0; i < eframe.
rows; i++ )
1077 legendText->
SetText( wxString( legendChar ) );
1080 aItems.push_back( legendText );
1082 legendPosY += rowSpacing;
1093 aItems.push_back( lines );
1096 int height = yMax - yMin;
1100 double rowSpacing = height / double( eframe.
rows );
1101 double legendPosY = yMin + ( rowSpacing / 2 );
1103 for( i = 1; i < eframe.
rows; i++ )
1105 int newY =
KiROUND( yMin + ( rowSpacing * (
double) i ) );
1109 aItems.push_back( lines );
1112 char legendChar =
'A';
1114 for( i = 0; i < eframe.
rows; i++ )
1120 legendText->
SetText( wxString( legendChar ) );
1123 aItems.push_back( legendText );
1125 legendPosY += rowSpacing;
1136 aItems.push_back( lines );
1139 int width = xMax - xMin;
1143 double columnSpacing = width / double( eframe.
columns );
1144 double legendPosX = xMin + ( columnSpacing / 2 );
1146 for( i = 1; i < eframe.
columns; i++ )
1148 int newX =
KiROUND( xMin + ( columnSpacing * (
double) i ) );
1152 aItems.push_back( lines );
1155 char legendChar =
'1';
1157 for( i = 0; i < eframe.
columns; i++ )
1163 legendText->
SetText( wxString( legendChar ) );
1166 aItems.push_back( legendText );
1168 legendPosX += columnSpacing;
1179 aItems.push_back( lines );
1182 int width = xMax - xMin;
1186 double columnSpacing = width / double( eframe.
columns );
1187 double legendPosX = xMin + ( columnSpacing / 2 );
1189 for( i = 1; i < eframe.
columns; i++ )
1191 int newX =
KiROUND( xMin + ( columnSpacing * (
double) i ) );
1195 aItems.push_back( lines );
1198 char legendChar =
'1';
1200 for( i = 0; i < eframe.
columns; i++ )
1206 legendText->
SetText( wxString( legendChar ) );
1209 aItems.push_back( legendText );
1211 legendPosX += columnSpacing;
1218 const wxString& aNetClass )
1221 wxXmlNode* currentSegment = aSegmentsNode->GetChildren();
1226 int segmentCount =
countChildren( aSegmentsNode, wxT(
"segment" ) );
1228 while( currentSegment )
1230 bool labelled =
false;
1232 bool firstWireFound =
false;
1238 wxXmlNode* segmentAttribute = currentSegment->GetChildren();
1240 while( segmentAttribute )
1242 if( segmentAttribute->GetName() == wxT(
"wire" ) )
1251 if( !firstWireFound )
1253 firstWire = thisWire;
1254 firstWireFound =
true;
1260 if( !desc.labels.empty() && desc.labels.front()->GetText() == netName )
1263 for(
const SEG& seg : desc.segs )
1272 segDesc.
segs.push_back( thisWire );
1276 segmentAttribute = segmentAttribute->GetNext();
1279 segmentAttribute = currentSegment->GetChildren();
1281 while( segmentAttribute )
1283 wxString nodeName = segmentAttribute->GetName();
1285 if( nodeName == wxT(
"junction" ) )
1289 else if( nodeName == wxT(
"label" ) )
1293 wxASSERT( segDesc.
labels.empty()
1295 segDesc.
labels.push_back( label );
1298 else if( nodeName == wxT(
"pinref" ) )
1300 segmentAttribute->GetAttribute( wxT(
"gate" ) );
1301 wxString part = segmentAttribute->GetAttribute( wxT(
"part" ) );
1302 wxString
pin = segmentAttribute->GetAttribute( wxT(
"pin" ) );
1304 auto powerPort =
m_powerPorts.find( wxT(
"#" ) + part );
1312 else if( nodeName == wxT(
"wire" ) )
1322 segmentAttribute = segmentAttribute->GetNext();
1328 if( !labelled && firstWireFound )
1330 std::unique_ptr<SCH_LABEL_BASE> label;
1335 else if( segmentCount > 1 )
1340 label->SetPosition( firstWire.
A );
1345 if( firstWire.
B.
x > firstWire.
A.
x )
1350 screen->
Append( label.release() );
1354 currentSegment = currentSegment->GetNext();
1361 std::unique_ptr<SCH_SHAPE> poly = std::make_unique<SCH_SHAPE>( SHAPE_T::POLY );
1363 wxXmlNode* vertex = aPolygonNode->GetChildren();
1369 if( vertex->GetName() == wxT(
"vertex" ) )
1378 poly->GetPolyShape().Append( arc, -1, -1,
ARC_ACCURACY );
1382 poly->AddPoint( pt );
1386 prev_curve = evertex.
curve;
1389 vertex = vertex->GetNext();
1394 poly->SetFillMode( FILL_T::FILLED_SHAPE );
1396 return poly.release();
1411 endpoints =
SEG( start, end );
1415 std::unique_ptr<SCH_SHAPE> arc = std::make_unique<SCH_SHAPE>( SHAPE_T::ARC );
1418 arc->SetCenter( center );
1419 arc->SetStart( start );
1424 return arc.release();
1428 std::unique_ptr<SCH_LINE> line = std::make_unique<SCH_LINE>();
1430 line->SetStartPoint( start );
1431 line->SetEndPoint( end );
1435 return line.release();
1442 std::unique_ptr<SCH_SHAPE> circle = std::make_unique<SCH_SHAPE>( SHAPE_T::CIRCLE );
1447 circle->SetPosition( center );
1451 return circle.release();
1457 std::unique_ptr<SCH_SHAPE> rectangle = std::make_unique<SCH_SHAPE>( SHAPE_T::RECTANGLE );
1458 ERECT rect( aRectNode );
1466 VECTOR2I pos( rectangle->GetPosition() );
1467 VECTOR2I end( rectangle->GetEnd() );
1468 VECTOR2I center( rectangle->GetCenter() );
1473 rectangle->SetPosition( pos );
1474 rectangle->SetEnd( end );
1478 rectangle->SetFillMode( FILL_T::FILLED_SHAPE );
1480 return rectangle.release();
1486 std::unique_ptr<SCH_JUNCTION> junction = std::make_unique<SCH_JUNCTION>();
1491 junction->SetPosition( pos );
1493 return junction.release();
1505 std::unique_ptr<SCH_LABEL_BASE> label;
1511 label = std::make_unique<SCH_GLOBALLABEL>();
1513 label = std::make_unique<SCH_LABEL>();
1515 label->SetPosition( elabelpos );
1517 label->SetTextSize( textSize );
1523 label->Rotate90(
false );
1526 label->MirrorSpinStyle(
false );
1529 return label.release();
1533std::pair<VECTOR2I, const SEG*>
1535 const std::vector<SEG>& aLines )
const
1538 const SEG* nearestLine =
nullptr;
1540 float d, mindistance = std::numeric_limits<float>::max();
1543 for(
const SEG& line : aLines )
1546 d = sqrt(
abs( ( ( aPoint.
x - testpoint.
x ) ^ 2 ) + ( ( aPoint.
y - testpoint.
y ) ^ 2 ) ) );
1548 if( d < mindistance )
1551 nearestPoint = testpoint;
1552 nearestLine = &line;
1555 testpoint = line.Center();
1556 d = sqrt(
abs( ( ( aPoint.
x - testpoint.
x ) ^ 2 ) + ( ( aPoint.
y - testpoint.
y ) ^ 2 ) ) );
1558 if( d < mindistance )
1561 nearestPoint = testpoint;
1562 nearestLine = &line;
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 return std::make_pair( nearestPoint, nearestLine );
1595 m_reporter->
Report( wxString::Format(
_(
"Error parsing Eagle file. Could not find '%s' "
1596 "instance but it is referenced in the schematic." ),
1603 EPART* epart = part_it->second.get();
1605 wxString libraryname = epart->
library;
1608 symbolname.Replace( wxT(
"*" ), wxEmptyString );
1616 wxString altSymbolName = libraryname + wxT(
"_" ) + symbolname;
1619 wxString libIdSymbolName = altSymbolName;
1621 int unit =
m_eagleLibs[libraryname].GateUnit[gatename];
1626 auto p = elib->
package.find( kisymbolname );
1628 if( p != elib->
package.end() )
1629 package = p->second;
1631 LIB_SYMBOL* part = m_pi->LoadSymbol( getLibFileName().GetFullPath(), altSymbolName,
1632 m_properties.get() );
1636 part = m_pi->LoadSymbol( getLibFileName().GetFullPath(), kisymbolname,
1637 m_properties.get() );
1638 libIdSymbolName = kisymbolname;
1643 m_reporter->Report( wxString::Format(
_(
"Could not find '%s' in the imported library." ),
1649 LIB_ID libId( getLibName(), libIdSymbolName );
1650 std::unique_ptr<SCH_SYMBOL> symbol = std::make_unique<SCH_SYMBOL>();
1651 symbol->SetLibId( libId );
1652 symbol->SetUnit( unit );
1656 if( !package.IsEmpty() )
1658 wxString footprint = m_schematic->Prj().GetProjectName() + wxT(
":" ) + package;
1667 symbol->MirrorHorizontally( einstance.
x.
ToSchUnits() );
1670 std::vector<LIB_FIELD*> partFields;
1673 for(
const LIB_FIELD* field : partFields )
1675 symbol->GetFieldById( field->GetId() )->ImportValues( *field );
1676 symbol->GetFieldById( field->GetId() )->SetTextPos( (
VECTOR2I)symbol->GetPosition()
1677 + field->GetTextPos() );
1682 wxString reference = package.IsEmpty() ?
'#' + einstance.
part : einstance.
part;
1685 if( reference.find_last_not_of( wxT(
"0123456789" ) ) == ( reference.Length()-1 ) )
1686 reference.Append( wxT(
"0" ) );
1691 if( reference.find_first_not_of( wxT(
"0123456789" ) ) != 0 )
1692 reference.Prepend( wxT(
"UNK" ) );
1696 if( einstance.
part.find_first_not_of( wxT(
"#" ) ) != 0 )
1697 reference.Prepend( wxT(
"UNK" ) );
1700 referenceField->
SetText( reference );
1704 bool userValue = m_userValue.at( libIdSymbolName );
1707 if( userValue && epart->
value )
1713 valueField->
SetText( kisymbolname );
1719 for(
const auto& [ attrName, attrValue ] : epart->
attribute )
1722 SCH_FIELD* lastField = symbol->GetFieldById( symbol->GetFieldCount() - 1 );
1727 SCH_FIELD newField( newFieldPosition, symbol->GetFieldCount(), symbol.get() );
1730 newField.
SetText( attrValue );
1733 symbol->AddField( newField );
1736 for(
const auto& a : epart->
variant )
1739 field->
SetName( wxT(
"VARIANT_" ) + a.first );
1744 bool valueAttributeFound =
false;
1745 bool nameAttributeFound =
false;
1747 wxXmlNode* attributeNode = aInstanceNode->GetChildren();
1750 while( attributeNode )
1752 if( attributeNode->GetName() == wxT(
"attribute" ) )
1757 if( attr.
name.Lower() == wxT(
"name" ) )
1760 nameAttributeFound =
true;
1762 else if( attr.
name.Lower() == wxT(
"value" ) )
1765 valueAttributeFound =
true;
1769 field = symbol->FindField( attr.
name );
1786 bool spin = attr.
rot ? attr.
rot->
spin :
false;
1792 int reldegrees = ( absdegrees - rotation + 360.0 );
1799 else if( attributeNode->GetName() == wxT(
"variant" ) )
1801 wxString variantName, fieldValue;
1803 if( attributeNode->GetAttribute( wxT(
"name" ), &variantName )
1804 && attributeNode->GetAttribute( wxT(
"value" ), &fieldValue ) )
1807 field.
SetName( wxT(
"VARIANT_" ) + variantName );
1810 symbol->AddField( field );
1814 attributeNode = attributeNode->GetNext();
1820 if( !valueAttributeFound )
1821 symbol->GetField(
VALUE_FIELD )->SetVisible(
false );
1823 if( !nameAttributeFound )
1827 symbol->AddHierarchicalReference( m_sheetPath.Path(), reference, unit );
1833 wxCHECK( libSymbol, );
1835 symbol->SetLibSymbol(
new LIB_SYMBOL( *libSymbol ) );
1837 std::vector<LIB_PIN*> pins;
1838 symbol->GetLibPins( pins );
1841 m_connPoints[symbol->GetPinPhysicalPosition(
pin )].emplace(
pin );
1844 m_powerPorts[ reference ] = symbol->GetField(
VALUE_FIELD )->GetText();
1846 symbol->ClearFlags();
1848 screen->
Append( symbol.release() );
1858 wxXmlNode* symbolNode =
getChildrenNodes( libraryChildren, wxT(
"symbols" ) );
1862 wxString symbolName = symbolNode->GetAttribute( wxT(
"name" ) );
1863 aEagleLibrary->
SymbolNodes[symbolName] = symbolNode;
1864 symbolNode = symbolNode->GetNext();
1868 wxXmlNode* devicesetNode =
getChildrenNodes( libraryChildren, wxT(
"devicesets" ) );
1870 while( devicesetNode )
1875 wxString prefix = edeviceset.
prefix ? edeviceset.
prefix.
Get() : wxString( wxT(
"" ) );
1878 wxXmlNode* deviceNode =
getChildrenNodes( deviceSetChildren, wxT(
"devices" ) );
1887 wxString symbolName = edeviceset.
name + edevice.
name;
1888 symbolName.Replace( wxT(
"*" ), wxEmptyString );
1889 wxASSERT( !symbolName.IsEmpty() );
1896 std::unique_ptr<LIB_SYMBOL> libSymbol = std::make_unique<LIB_SYMBOL>( symbolName );
1899 wxXmlNode* gateNode =
getChildrenNodes( deviceSetChildren, wxT(
"gates" ) );
1900 int gates_count =
countChildren( deviceSetChildren[
"gates"], wxT(
"gate" ) );
1901 libSymbol->SetUnitCount( gates_count );
1902 libSymbol->LockUnits(
true );
1906 if( prefix.length() == 0 )
1918 bool ispower =
false;
1928 gateindex, egate.
name );
1931 gateNode = gateNode->GetNext();
1934 libSymbol->SetUnitCount( gates_count );
1936 if( gates_count == 1 && ispower )
1937 libSymbol->SetPower();
1944 aEagleLibrary->
package[symbolName];
1945 libSymbol->GetFootprintField().SetText( packageString );
1948 wxString libName = libSymbol->GetName();
1949 libSymbol->SetName( libName );
1955 libName = aEagleLibrary->
name + wxT(
"_" ) + libName;
1957 libSymbol->SetName( libName );
1962 aEagleLibrary->
KiCadSymbols.insert( libName, libSymbol.release() );
1969 deviceNode = deviceNode->GetNext();
1972 devicesetNode = devicesetNode->GetNext();
1975 return aEagleLibrary;
1980 EDEVICE* aDevice,
int aGateNumber,
const wxString& aGateName )
1982 wxString symbolName = aSymbolNode->GetAttribute( wxT(
"name" ) );
1983 std::vector<LIB_ITEM*> items;
1985 wxXmlNode* currentNode = aSymbolNode->GetChildren();
1987 bool showRefDes =
false;
1988 bool showValue =
false;
1989 bool ispower =
false;
1992 while( currentNode )
1994 wxString nodeName = currentNode->GetName();
1996 if( nodeName == wxT(
"circle" ) )
1998 aSymbol->AddDrawItem(
loadSymbolCircle( aSymbol, currentNode, aGateNumber ) );
2000 else if( nodeName == wxT(
"pin" ) )
2003 std::unique_ptr<LIB_PIN>
pin(
loadPin( aSymbol, currentNode, &ePin, aGateNumber ) );
2006 pin->SetType( ELECTRICAL_PINTYPE::PT_BIDI );
2012 if( ePin.
direction->Lower() == pinDir.first )
2014 pin->SetType( pinDir.second );
2016 if( pinDir.first == wxT(
"sup" ) )
2024 if( aDevice->
connects.size() != 0 )
2028 if( connect.
gate == aGateName &&
pin->GetName() == connect.
pin )
2030 wxArrayString pads = wxSplit( wxString( connect.
pad ),
' ' );
2032 pin->SetUnit( aGateNumber );
2035 if( pads.GetCount() > 1 )
2037 pin->SetNumberTextSize( 0 );
2040 for(
unsigned i = 0; i < pads.GetCount(); i++ )
2044 wxString padname( pads[i] );
2046 aSymbol->AddDrawItem( apin );
2055 pin->SetUnit( aGateNumber );
2056 pin->SetNumber( wxString::Format( wxT(
"%i" ), pincount ) );
2057 aSymbol->AddDrawItem(
pin.release() );
2060 else if( nodeName == wxT(
"polygon" ) )
2064 else if( nodeName == wxT(
"rectangle" ) )
2068 else if( nodeName == wxT(
"text" ) )
2070 std::unique_ptr<LIB_TEXT> libtext(
loadSymbolText( aSymbol, currentNode, aGateNumber ) );
2072 if( libtext->GetText() == wxT(
"${REFERENCE}" ) )
2079 showRefDes = currentNode->GetNodeContent() == wxT(
">NAME" );
2081 else if( libtext->GetText() == wxT(
"${VALUE}" ) )
2088 showValue = currentNode->GetNodeContent() == wxT(
">VALUE" );
2092 aSymbol->AddDrawItem( libtext.release() );
2095 else if( nodeName == wxT(
"wire" ) )
2097 aSymbol->AddDrawItem(
loadSymbolWire( aSymbol, currentNode, aGateNumber ) );
2099 else if( nodeName == wxT(
"frame" ) )
2101 std::vector<LIB_ITEM*> frameItems;
2107 item->SetParent( aSymbol.get() );
2108 item->SetUnit( aGateNumber );
2109 aSymbol->AddDrawItem( item );
2122 currentNode = currentNode->GetNext();
2129 aSymbol->GetFieldById(
VALUE_FIELD )->SetVisible(
false );
2131 return pincount == 1 ? ispower :
false;
2136 wxXmlNode* aCircleNode,
int aGateNumber )
2146 circle->
SetUnit( aGateNumber );
2153 wxXmlNode* aRectNode,
int aGateNumber )
2155 ERECT rect( aRectNode );
2171 rectangle->
SetEnd( end );
2174 rectangle->
SetUnit( aGateNumber );
2184 wxXmlNode* aWireNode,
int aGateNumber )
2203 double radius = sqrt( ( ( center.
x - begin.
x ) * ( center.
x - begin.
x ) ) +
2204 ( ( center.
y - begin.
y ) * ( center.
y - begin.
y ) ) );
2210 begin = center + centerStartVector;
2242 wxXmlNode* aPolygonNode,
int aGateNumber )
2246 wxXmlNode* vertex = aPolygonNode->GetChildren();
2252 if( vertex->GetName() == wxT(
"vertex" ) )
2269 prev_curve = evertex.
curve;
2272 vertex = vertex->GetNext();
2284 EPIN* aEPin,
int aGateNumber )
2286 std::unique_ptr<LIB_PIN>
pin = std::make_unique<LIB_PIN>( aSymbol.get() );
2289 pin->SetUnit( aGateNumber );
2295 case 0:
pin->SetOrientation( PIN_ORIENTATION::PIN_RIGHT );
break;
2296 case 90:
pin->SetOrientation( PIN_ORIENTATION::PIN_UP );
break;
2297 case 180:
pin->SetOrientation( PIN_ORIENTATION::PIN_LEFT );
break;
2298 case 270:
pin->SetOrientation( PIN_ORIENTATION::PIN_DOWN );
break;
2299 default: wxFAIL_MSG( wxString::Format( wxT(
"Unhandled orientation (%d degrees)." ), roti ) );
2308 if( length == wxT(
"short" ) )
2310 else if( length == wxT(
"middle" ) )
2312 else if( length == wxT(
"long" ) )
2314 else if( length == wxT(
"point" ) )
2323 if( visible == wxT(
"off" ) )
2325 pin->SetNameTextSize( 0 );
2326 pin->SetNumberTextSize( 0 );
2328 else if( visible == wxT(
"pad" ) )
2330 pin->SetNameTextSize( 0 );
2332 else if( visible == wxT(
"pin" ) )
2334 pin->SetNumberTextSize( 0 );
2348 if( function == wxT(
"dot" ) )
2349 pin->SetShape( GRAPHIC_PINSHAPE::INVERTED );
2350 else if( function == wxT(
"clk" ) )
2351 pin->SetShape( GRAPHIC_PINSHAPE::CLOCK );
2352 else if( function == wxT(
"dotclk" ) )
2353 pin->SetShape( GRAPHIC_PINSHAPE::INVERTED_CLOCK );
2356 return pin.release();
2361 wxXmlNode* aLibText,
int aGateNumber )
2363 std::unique_ptr<LIB_TEXT> libtext = std::make_unique<LIB_TEXT>( aSymbol.get() );
2364 ETEXT etext( aLibText );
2366 libtext->SetUnit( aGateNumber );
2369 const wxString& eagleText = aLibText->GetNodeContent();
2370 wxString adjustedText;
2371 wxStringTokenizer tokenizer( eagleText,
"\r\n" );
2374 while( tokenizer.HasMoreTokens() )
2376 wxString tmp =
interpretText( tokenizer.GetNextToken().Trim(
true ).Trim(
false ) );
2378 if( tokenizer.HasMoreTokens() )
2381 adjustedText += tmp;
2384 libtext->SetText( adjustedText.IsEmpty() ? wxString( wxT(
"~" ) ) : adjustedText );
2387 return libtext.release();
2393 EFRAME eframe( aFrameNode );
2401 std::swap( xMin, xMax );
2404 std::swap( yMin, yMax );
2412 aItems.push_back( lines );
2416 lines =
new LIB_SHAPE(
nullptr, SHAPE_T::POLY );
2421 aItems.push_back( lines );
2424 int height = yMax - yMin;
2428 double rowSpacing = height / double( eframe.
rows );
2429 double legendPosY = yMax - ( rowSpacing / 2 );
2431 for( i = 1; i < eframe.
rows; i++ )
2433 int newY =
KiROUND( yMin + ( rowSpacing * (
double) i ) );
2434 lines =
new LIB_SHAPE(
nullptr, SHAPE_T::POLY );
2437 aItems.push_back( lines );
2440 char legendChar =
'A';
2442 for( i = 0; i < eframe.
rows; i++ )
2446 legendText->
SetText( wxString( legendChar ) );
2449 aItems.push_back( legendText );
2451 legendPosY -= rowSpacing;
2457 lines =
new LIB_SHAPE(
nullptr, SHAPE_T::POLY );
2462 aItems.push_back( lines );
2465 int height = yMax - yMin;
2469 double rowSpacing = height / double( eframe.
rows );
2470 double legendPosY = yMax - ( rowSpacing / 2 );
2472 for( i = 1; i < eframe.
rows; i++ )
2474 int newY =
KiROUND( yMin + ( rowSpacing * (
double) i ) );
2475 lines =
new LIB_SHAPE(
nullptr, SHAPE_T::POLY );
2478 aItems.push_back( lines );
2481 char legendChar =
'A';
2483 for( i = 0; i < eframe.
rows; i++ )
2487 legendText->
SetText( wxString( legendChar ) );
2490 aItems.push_back( legendText );
2492 legendPosY -= rowSpacing;
2498 lines =
new LIB_SHAPE(
nullptr, SHAPE_T::POLY );
2503 aItems.push_back( lines );
2506 int width = xMax - xMin;
2510 double columnSpacing = width / double( eframe.
columns );
2511 double legendPosX = xMin + ( columnSpacing / 2 );
2513 for( i = 1; i < eframe.
columns; i++ )
2515 int newX =
KiROUND( xMin + ( columnSpacing * (
double) i ) );
2516 lines =
new LIB_SHAPE(
nullptr, SHAPE_T::POLY );
2519 aItems.push_back( lines );
2522 char legendChar =
'1';
2524 for( i = 0; i < eframe.
columns; i++ )
2528 legendText->
SetText( wxString( legendChar ) );
2531 aItems.push_back( legendText );
2533 legendPosX += columnSpacing;
2539 lines =
new LIB_SHAPE(
nullptr, SHAPE_T::POLY );
2544 aItems.push_back( lines );
2547 int width = xMax - xMin;
2551 double columnSpacing = width / double( eframe.
columns );
2552 double legendPosX = xMin + ( columnSpacing / 2 );
2554 for( i = 1; i < eframe.
columns; i++ )
2556 int newX =
KiROUND( xMin + ( columnSpacing * (
double) i ) );
2557 lines =
new LIB_SHAPE(
nullptr, SHAPE_T::POLY );
2560 aItems.push_back( lines );
2563 char legendChar =
'1';
2565 for( i = 0; i < eframe.
columns; i++ )
2569 legendText->
SetText( wxString( legendChar ) );
2572 aItems.push_back( legendText );
2574 legendPosX += columnSpacing;
2582 std::unique_ptr<SCH_TEXT> schtext = std::make_unique<SCH_TEXT>();
2585 const wxString& eagleText = aSchText->GetNodeContent();
2586 wxString adjustedText;
2587 wxStringTokenizer tokenizer( eagleText,
"\r\n" );
2590 while( tokenizer.HasMoreTokens() )
2592 wxString tmp =
interpretText( tokenizer.GetNextToken().Trim(
true ).Trim(
false ) );
2594 if( tokenizer.HasMoreTokens() )
2597 adjustedText += tmp;
2600 schtext->SetText( adjustedText.IsEmpty() ? wxString( wxT(
"\" \"" ) ) :
escapeName( adjustedText ) );
2603 schtext->SetItalic(
false );
2605 return schtext.release();
2613 if( aAttribs.
ratio )
2624 bool mirror = aAttribs.
rot ? aAttribs.
rot->
mirror :
false;
2625 bool spin = aAttribs.
rot ? aAttribs.
rot->
spin :
false;
2651 auto onIntersection =
2660 for(
SCH_TEXT* label : segDesc.labels )
2663 const SEG* segAttached = segDesc.LabelAttached( label );
2665 if( segAttached && !onIntersection( labelPos ) )
2679 VECTOR2I wireDirection( segAttached->
B - segAttached->
A );
2681 const VECTOR2I origPos( labelPos );
2684 bool checkPositive =
true, checkNegative =
true,
move =
false;
2688 while( ( !
move || onIntersection( labelPos ) ) && ( checkPositive || checkNegative ) )
2693 if( trial % 2 == 1 )
2695 labelPos =
VECTOR2I( origPos + wireDirection * trial / 2 );
2696 move = checkPositive = segAttached->
Contains( labelPos );
2700 labelPos =
VECTOR2I( origPos - wireDirection * trial / 2 );
2701 move = checkNegative = segAttached->
Contains( labelPos );
2737 wxFileInputStream input( aFileName );
2742 wxTextInputStream
text( input );
2744 for(
int i = 0; i < 3; i++ )
2749 if(
text.ReadLine().Contains( wxS(
"<!DOCTYPE eagle" ) ) )
2765 if( !item->IsType( { SCH_LABEL_LOCATE_ANY_T } ) )
2769 item->SetPosition( aNewEndPoint );
2782 std::vector<SCH_LINE*> buses;
2783 std::vector<SCH_LINE*> wires;
2794 buses.push_back( line );
2795 else if( line->
IsWire() )
2796 wires.push_back( line );
2801 VECTOR2I wireStart = wire->GetStartPoint();
2802 VECTOR2I wireEnd = wire->GetEndPoint();
2806 VECTOR2I busStart = bus->GetStartPoint();
2807 VECTOR2I busEnd = bus->GetEndPoint();
2810 [](
int signX,
int signY ) ->
VECTOR2I
2822 if( wireStart.
y == wireEnd.
y && busStart.
x == busEnd.
x )
2826 if( testBusHit( wireStart ) )
2830 if( wireEnd.
x < busStart.
x )
2837 VECTOR2I p = wireStart + entrySize( -1, 0 );
2839 if( testBusHit( wireStart + entrySize( 0, -1 ) ) )
2848 screen->
Append( busEntry );
2850 wire->SetStartPoint( p );
2852 else if( testBusHit( wireStart + entrySize( 0, 1 ) ) )
2861 screen->
Append( busEntry );
2863 wire->SetStartPoint( p );
2869 screen->
Append( marker );
2879 VECTOR2I p = wireStart + entrySize( 1, 0 );
2881 if( testBusHit( wireStart + entrySize( 0, -1 ) ) )
2890 screen->
Append( busEntry );
2892 wire->SetStartPoint( p );
2894 else if( testBusHit( wireStart + entrySize( 0, 1 ) ) )
2903 screen->
Append( busEntry );
2905 wire->SetStartPoint( p );
2911 screen->
Append( marker );
2917 else if( testBusHit( wireEnd ) )
2921 if( wireStart.
x < busStart.
x )
2928 VECTOR2I p = wireEnd + entrySize( -1, 0 );
2930 if( testBusHit( wireEnd + entrySize( 0, -1 ) ) )
2939 screen->
Append( busEntry );
2941 wire->SetEndPoint( p );
2943 else if( testBusHit( wireEnd + entrySize( 0, -1 ) ) )
2952 screen->
Append( busEntry );
2953 moveLabels( wire, wireEnd + entrySize( -1, 0 ) );
2954 wire->SetEndPoint( wireEnd + entrySize( -1, 0 ) );
2960 screen->
Append( marker );
2970 VECTOR2I p = wireEnd + entrySize( 1, 0 );
2972 if( testBusHit( wireEnd + entrySize( 0, -1 ) ) )
2981 screen->
Append( busEntry );
2983 wire->SetEndPoint( p );
2985 else if( testBusHit( wireEnd + entrySize( 0, 1 ) ) )
2994 screen->
Append( busEntry );
2996 wire->SetEndPoint( p );
3002 screen->
Append( marker );
3009 else if( wireStart.
x == wireEnd.
x && busStart.
y == busEnd.
y )
3013 if( testBusHit( wireStart ) )
3017 if( wireEnd.
y < busStart.
y )
3025 VECTOR2I p = wireStart + entrySize( 0, -1 );
3027 if( testBusHit( wireStart + entrySize( -1, 0 ) ) )
3037 screen->
Append( busEntry );
3039 wire->SetStartPoint( p );
3041 else if( testBusHit( wireStart + entrySize( 1, 0 ) ) )
3051 screen->
Append( busEntry );
3053 wire->SetStartPoint( p );
3059 screen->
Append( marker );
3070 VECTOR2I p = wireStart + entrySize( 0, 1 );
3072 if( testBusHit( wireStart + entrySize( -1, 0 ) ) )
3082 screen->
Append( busEntry );
3084 wire->SetStartPoint( p );
3086 else if( testBusHit( wireStart + entrySize( 1, 0 ) ) )
3096 screen->
Append( busEntry );
3098 wire->SetStartPoint( p );
3104 screen->
Append( marker );
3110 else if( testBusHit( wireEnd ) )
3114 if( wireStart.
y < busStart.
y )
3122 VECTOR2I p = wireEnd + entrySize( 0, -1 );
3124 if( testBusHit( wireEnd + entrySize( -1, 0 ) ) )
3134 screen->
Append( busEntry );
3136 wire->SetEndPoint( p );
3138 else if( testBusHit( wireEnd + entrySize( 1, 0 ) ) )
3148 screen->
Append( busEntry );
3150 wire->SetEndPoint( p );
3156 screen->
Append( marker );
3167 VECTOR2I p = wireEnd + entrySize( 0, 1 );
3169 if( testBusHit( wireEnd + entrySize( -1, 0 ) ) )
3179 screen->
Append( busEntry );
3181 wire->SetEndPoint( p );
3183 else if( testBusHit( wireEnd + entrySize( 1, 0 ) ) )
3193 screen->
Append( busEntry );
3195 wire->SetEndPoint( p );
3201 screen->
Append( marker );
3212 if( testBusHit( wireStart ) )
3214 VECTOR2I wirevector = wireStart - wireEnd;
3216 if( wirevector.
x > 0 )
3218 if( wirevector.
y > 0 )
3220 VECTOR2I p = wireStart + entrySize( -1, -1 );
3223 screen->
Append( busEntry );
3226 wire->SetStartPoint( p );
3230 VECTOR2I p = wireStart + entrySize( -1, 1 );
3233 screen->
Append( busEntry );
3236 wire->SetStartPoint( p );
3241 if( wirevector.
y > 0 )
3243 VECTOR2I p = wireStart + entrySize( 1, -1 );
3246 screen->
Append( busEntry );
3249 wire->SetStartPoint( p );
3253 VECTOR2I p = wireStart + entrySize( 1, 1 );
3256 screen->
Append( busEntry );
3259 wire->SetStartPoint( p );
3265 else if( testBusHit( wireEnd ) )
3267 VECTOR2I wirevector = wireStart - wireEnd;
3269 if( wirevector.
x > 0 )
3271 if( wirevector.
y > 0 )
3273 VECTOR2I p = wireEnd + entrySize( 1, 1 );
3276 screen->
Append( busEntry );
3279 wire->SetEndPoint( p );
3283 VECTOR2I p = wireEnd + entrySize( 1, -1 );
3286 screen->
Append( busEntry );
3289 wire->SetEndPoint( p );
3294 if( wirevector.
y > 0 )
3296 VECTOR2I p = wireEnd + entrySize( -1, 1 );
3299 screen->
Append( busEntry );
3302 wire->SetEndPoint( p );
3306 VECTOR2I p = wireEnd + entrySize( -1, -1 );
3309 screen->
Append( busEntry );
3312 wire->SetEndPoint( p );
3328 for(
const SEG& seg : segs )
3330 if( seg.Contains( labelPos ) )
3342 wxCHECK( aSymbol && aPin,
false );
3350 const auto& items = pointIt->second;
3352 wxCHECK( items.find( aPin ) != items.end(),
false );
3354 return items.size() > 1;
3368 int unit = aSymbol->
GetUnit();
3370 std::vector<LIB_PIN*> pins;
3372 std::set<int> missingUnits;
3377 if(
pin->GetType() == ELECTRICAL_PINTYPE::PT_POWER_IN )
3379 bool pinInUnit = !unit ||
pin->GetUnit() == unit;
3393 switch(
pin->GetOrientation() )
3401 aScreen->
Append( netLabel );
3404 else if( aUpdateSet )
3409 wxASSERT(
pin->GetUnit() );
3410 missingUnits.insert(
pin->GetUnit() );
3423 entry.
cmp = aSymbol;
3424 entry.
units.emplace( unit,
false );
3429 cmpIt->second.units[unit] =
false;
3432 if( !missingUnits.empty() )
3435 entry.
cmp = aSymbol;
3438 for(
int i : missingUnits )
3440 if( entry.
units.find( i ) != entry.
units.end() )
3441 entry.
units.emplace( i,
true );
3453 wxString ret = wxT(
"{" );
3455 wxStringTokenizer tokenizer( aEagleName, wxT(
"," ) );
3457 while( tokenizer.HasMoreTokens() )
3459 wxString member = tokenizer.GetNextToken();
3466 if( member.Freq(
'!' ) % 2 > 0 )
3467 member << wxT(
"!" );
3469 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,...
void SetTextSize(VECTOR2I aNewSize)
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
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).
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.
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)
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)
bool CanReadSchematicFile(const wxString &aFileName) const override
Checks if this SCH_PLUGIN can read the specified schematic file.
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()
bool checkHeader(const wxString &aFileName) const
bool CanReadLibrary(const wxString &aFileName) const override
Checks if this SCH_PLUGIN can read the specified symbol library file.
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)
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_PLUGIN implementation knows about,...
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)
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_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)
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 SetText(const wxString &aText) override
void SetSpinStyle(SPIN_STYLE aSpinStyle) override
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 bool CanReadSchematicFile(const wxString &aFileName) const
Checks if this SCH_PLUGIN can read the specified schematic file.
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.
virtual bool CanReadLibrary(const wxString &aFileName) const
Checks if this SCH_PLUGIN can read the specified symbol library file.
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 'GND@2')
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.