31#include <wx/filename.h>
33#include <wx/tokenzr.h>
34#include <wx/wfstream.h>
35#include <wx/txtstrm.h>
36#include <wx/xml/xml.h>
91 bbox.
Merge( item->GetBoundingBox() );
100 return aPinName.BeforeFirst(
'@' );
113 wxCHECK( currentSheet,
nullptr );
158 for(
const std::unique_ptr<ELAYER>& elayer : aLayers )
177 switch ( elayer->number)
207 int roti = int( eagleDegrees );
217 wxASSERT_MSG(
false, wxString::Format( wxT(
"Unhandled orientation (%d degrees)" ),
226 bool aMirror,
bool aSpin,
int aAbsDegress )
228 int align = aEagleAlignment;
230 if( aRelDegress == 90 )
234 else if( aRelDegress == 180 )
238 else if( aRelDegress == 270 )
244 if( aMirror ==
true )
246 if( aAbsDegress == 90 || aAbsDegress == 270 )
257 else if( aAbsDegress == 0 || aAbsDegress == 180 )
330 m_rootSheet( nullptr ),
331 m_schematic( nullptr ),
352 const std::map<std::string, UTF8>* aProperties )
354 wxASSERT( !aFileName || aSchematic !=
nullptr );
375 wxXmlNode* currentNode = xmlDocument.GetRoot();
381 unique_ptr<SCH_SHEET> deleter( aAppendToMe ?
nullptr :
m_rootSheet );
388 wxCHECK_MSG( aSchematic->
IsValid(),
nullptr,
389 wxT(
"Can't append to a schematic with no root!" ) );
412 wxCHECK_MSG( libTable,
nullptr, wxT(
"Could not load symbol lib table." ) );
414 m_pi.reset( SCH_IO_MGR::FindPlugin( SCH_IO_MGR::SCH_KICAD ) );
415 m_properties = std::make_unique<std::map<std::string, UTF8>>();
424 wxString libTableUri = wxT(
"${KIPRJMOD}/" ) +
getLibFileName().GetFullName();
437 libTable->
Format( &formatter, 0 );
445 m_eagleDoc = std::make_unique<EAGLE_DOC>( currentNode,
this );
464 const wxString& aLibraryPath,
465 const std::map<std::string, UTF8>* aProperties )
476 for(
const auto& [symName, libSymbol] : it->second.KiCadSymbols )
477 aSymbolNameList.push_back( symName );
483 const wxString& aLibraryPath,
484 const std::map<std::string, UTF8>* aProperties )
495 for(
const auto& [symName, libSymbol] : it->second.KiCadSymbols )
496 aSymbolList.push_back( libSymbol.get() );
502 const std::map<std::string, UTF8>* aProperties )
513 auto it2 = it->second.KiCadSymbols.find( aAliasName );
515 if( it2 != it->second.KiCadSymbols.end() )
516 return it2->second.get();
525 wxFileName fn( aLibraryPath );
527 if( fn.IsFileReadable() && fn.GetModificationTime().IsValid() )
528 return fn.GetModificationTime().GetValue().GetValue();
530 return wxDateTime( 0.0 ).GetValue().GetValue();
561 std::unique_ptr<EAGLE_DOC> doc = std::make_unique<EAGLE_DOC>( xmlDocument.GetRoot(),
this );
565 m_version = ( doc->version.IsEmpty() ) ? wxString( wxS(
"0.0" ) ) : doc->version;
577 wxXmlDocument xmlDocument;
578 wxFFileInputStream stream(
m_filename.GetFullPath() );
583 wxString::Format(
_(
"Unable to read file '%s'." ),
m_filename.GetFullPath() ) );
587 wxTextInputStream
text( stream );
588 wxString line =
text.ReadLine();
590 if( !line.StartsWith( wxT(
"<?xml" ) ) && !line.StartsWith( wxT(
"<!--" ) ) )
592 THROW_IO_ERROR( wxString::Format(
_(
"'%s' is an Eagle binary-format file; "
593 "only Eagle XML-format files can be imported." ),
597 if( !xmlDocument.Load( stream ) )
600 wxString::Format(
_(
"Unable to read file '%s'." ),
m_filename.GetFullPath() ) );
609 wxCHECK( aDrawing, );
613 if( aDrawing->library )
621 if( aDrawing->schematic )
628 for(
const std::unique_ptr<ESHEET>& esheet : aSchematic.
sheets )
630 for(
const std::unique_ptr<ENET>& enet : esheet->nets )
632 wxString netName = enet->netname;
641 for(
const auto& [modname, emodule] : aSchematic.
modules )
643 for(
const std::unique_ptr<ESHEET>& esheet : emodule->sheets )
645 for(
const std::unique_ptr<ENET>& enet : esheet->nets )
647 wxString netName = enet->netname;
662 if( aSchematic.
sheets.empty() )
666 for(
const auto& [
name, epart] : aSchematic.
parts )
669 for(
const auto& [modname, emodule] : aSchematic.
modules )
671 for(
const auto& [
name, epart] : emodule->parts )
680 elib->
name = elibrary->GetName();
696 size_t sheetCount = aSchematic.
sheets.size();
704 for(
const std::unique_ptr<ESHEET>& esheet : aSchematic.
sheets )
711 std::unique_ptr<SCH_SHEET> sheet = std::make_unique<SCH_SHEET>(
m_rootSheet, pos );
713 sheet->SetScreen( screen );
716 wxCHECK2( sheet && screen,
continue );
718 wxString pageNo = wxString::Format( wxT(
"%d" ),
m_sheetIndex );
728 wxCHECK2( currentScreen,
continue );
730 currentScreen->
Append( sheet.release() );
745 for(
const std::unique_ptr<ESHEET>& esheet : aSchematic.
sheets )
757 int maxY = sheetBbox.
GetY();
764 const SCH_SYMBOL* origSymbol = cmp.second.cmp;
766 for(
auto& unitEntry : cmp.second.units )
768 if( unitEntry.second ==
false )
772 int unit = unitEntry.first;
776 symbol->SetUnitSelection( &sheetpath, unit );
777 symbol->SetUnit( unit );
778 symbol->SetOrientation( 0 );
779 symbol->AddHierarchicalReference( sheetpath.
Path(), reference, unit );
782 BOX2I cmpBbox = symbol->GetBoundingBox();
783 int posY = newCmpPosition.
y + cmpBbox.
GetHeight();
784 symbol->SetPosition(
VECTOR2I( newCmpPosition.
x, posY ) );
786 maxY = std::max( maxY, posY );
788 if( newCmpPosition.
x >= pageSizeIU.
x )
806 wxCHECK( sheet && screen, );
810 std::string filename;
819 replace( filename.begin(), filename.end(),
' ',
'_' );
821 fn.SetName( filename );
831 for(
const std::unique_ptr<EPOLYGON>& epoly : aSheet->plain->polygons )
834 for(
const std::unique_ptr<EWIRE>& ewire : aSheet->plain->wires )
840 for(
const std::unique_ptr<ETEXT>& etext : aSheet->plain->texts )
843 for(
const std::unique_ptr<ECIRCLE>& ecircle : aSheet->plain->circles )
846 for(
const std::unique_ptr<ERECT>& erectangle : aSheet->plain->rectangles )
849 for(
const std::unique_ptr<EFRAME>& eframe : aSheet->plain->frames )
851 std::vector<SCH_ITEM*> frameItems;
862 for(
const auto& [
name, moduleinst] : aSheet->moduleinsts )
865 screen->
Append( modSheet );
868 for(
const std::unique_ptr<EINSTANCE>& einstance : aSheet->instances )
880 for(
const std::unique_ptr<EBUS>& ebus : aSheet->busses )
889 for(
const std::unique_ptr<ENET>& enet : aSheet->nets )
892 wxString netName = enet->netname;
893 wxString netClass = wxString::Format( wxS(
"%i" ), enet->netcode );
912 if( pageSizeIU.
x < targetSheetSize.
x )
915 if( pageSizeIU.
y < targetSheetSize.
y )
922 VECTOR2I sheetcentre( pageSizeIU.
x / 2, pageSizeIU.
y / 2 );
926 VECTOR2I translation = sheetcentre - itemsCentre;
940 std::vector<SCH_ITEM*> allItems;
942 std::copy( screen->
Items().
begin(), screen->
Items().
end(), std::back_inserter( allItems ) );
946 item->SetPosition( item->GetPosition() + translation );
964 wxCHECK( currentSheet &¤tScreen,
nullptr );
970 auto it =
m_eagleDoc->drawing->schematic->modules.find( aModuleInstance->moduleinst );
973 if( it ==
m_eagleDoc->drawing->schematic->modules.end() )
975 THROW_IO_ERROR( wxString::Format(
_(
"No module instance '%s' found in schematic "
977 aModuleInstance->name,
m_filename.GetFullPath() ) );
982 fn.SetName( aModuleInstance->name );
986 VECTOR2I size( it->second->dx.ToSchUnits(), it->second->dy.ToSchUnits() );
988 int halfX =
KiROUND( size.
x / 2.0 );
989 int halfY =
KiROUND( size.
y / 2.0 );
991 VECTOR2I pos( aModuleInstance->x.ToSchUnits() - halfX,
992 -aModuleInstance->y.ToSchUnits() - halfY );
994 std::unique_ptr<SCH_SHEET> newSheet = std::make_unique<SCH_SHEET>( currentSheet, pos, size );
998 wxCHECK( newSheet && newScreen,
nullptr );
1000 newSheet->SetScreen( newScreen );
1001 newSheet->SetFileName( fn.GetFullName() );
1002 newSheet->SetName( aModuleInstance->name );
1005 for(
const auto& [portName, port] : it->second->ports )
1008 int pinOffset = port->coord.ToSchUnits();
1011 if( port->side ==
"left" )
1013 side = SHEET_SIDE::LEFT;
1015 pinPos.
y = pos.
y + halfY - pinOffset;
1016 portExtWireEndpoint = pinPos;
1017 portExtWireEndpoint.
x -= portExtWireLength;
1019 else if( port->side ==
"right" )
1021 side = SHEET_SIDE::RIGHT;
1022 pinPos.
x = pos.
x + size.
x;
1023 pinPos.
y = pos.
y + halfY - pinOffset;
1024 portExtWireEndpoint = pinPos;
1025 portExtWireEndpoint.
x += portExtWireLength;
1027 else if( port->side ==
"top" )
1029 side = SHEET_SIDE::TOP;
1030 pinPos.
x = pos.
x + halfX + pinOffset;
1032 portExtWireEndpoint = pinPos;
1033 portExtWireEndpoint.
y -= portExtWireLength;
1035 else if( port->side ==
"bottom" )
1037 side = SHEET_SIDE::BOTTOM;
1038 pinPos.
x = pos.
x + halfX + pinOffset;
1039 pinPos.
y = pos.
y + size.
y;
1040 portExtWireEndpoint = pinPos;
1041 portExtWireEndpoint.
y += portExtWireLength;
1046 currentScreen->
Append( portExtWire );
1050 if( port->direction )
1052 if( *port->direction ==
"in" )
1053 pinType = LABEL_FLAG_SHAPE::L_INPUT;
1054 else if( *port->direction ==
"out" )
1055 pinType = LABEL_FLAG_SHAPE::L_OUTPUT;
1056 else if( *port->direction ==
"io" )
1057 pinType = LABEL_FLAG_SHAPE::L_BIDI;
1058 else if( *port->direction ==
"hiz" )
1059 pinType = LABEL_FLAG_SHAPE::L_TRISTATE;
1061 pinType = LABEL_FLAG_SHAPE::L_UNSPECIFIED;
1073 newSheet->AddPin( sheetPin );
1076 wxString pageNo = wxString::Format( wxT(
"%d" ),
m_sheetIndex );
1083 if( it->second->sheets.size() == 1 )
1085 loadSheet( it->second->sheets.at( 0 ) );
1093 for(
const std::unique_ptr<ESHEET>& esheet : it->second->sheets )
1098 std::unique_ptr<SCH_SHEET> sheet = std::make_unique<SCH_SHEET>( newSheet.get(), pos );
1100 sheet->SetScreen( screen );
1102 wxString newFileName = fn.GetName();
1104 newFileName += wxString::Format( wxS(
"_%d" ), i + 1 );
1105 fn.SetName( newFileName );
1107 sheet->SetFileName( fn.GetFullName() );
1109 wxCHECK2( sheet && screen,
continue );
1111 wxString subSheetPageNo = wxString::Format( wxT(
"%d" ),
m_sheetIndex );
1119 newScreen->
Append( sheet.release() );
1138 return newSheet.release();
1143 std::vector<SCH_ITEM*>& aItems )
1145 int xMin = aFrame->x1.ToSchUnits();
1146 int xMax = aFrame->x2.ToSchUnits();
1147 int yMin = -aFrame->y1.ToSchUnits();
1148 int yMax = -aFrame->y2.ToSchUnits();
1151 std::swap( xMin, xMax );
1154 std::swap( yMin, yMax );
1162 aItems.push_back( lines );
1164 if( !( aFrame->border_left ==
false ) )
1171 aItems.push_back( lines );
1174 int height = yMax - yMin;
1178 double rowSpacing = height / double( aFrame->rows );
1179 double legendPosY = yMin + ( rowSpacing / 2 );
1181 for( i = 1; i < aFrame->rows; i++ )
1183 int newY =
KiROUND( yMin + ( rowSpacing * (
double) i ) );
1187 aItems.push_back( lines );
1190 char legendChar =
'A';
1192 for( i = 0; i < aFrame->rows; i++ )
1198 legendText->
SetText( wxString( legendChar ) );
1201 aItems.push_back( legendText );
1203 legendPosY += rowSpacing;
1207 if( !( aFrame->border_right ==
false ) )
1214 aItems.push_back( lines );
1217 int height = yMax - yMin;
1221 double rowSpacing = height / double( aFrame->rows );
1222 double legendPosY = yMin + ( rowSpacing / 2 );
1224 for( i = 1; i < aFrame->rows; i++ )
1226 int newY =
KiROUND( yMin + ( rowSpacing * (
double) i ) );
1230 aItems.push_back( lines );
1233 char legendChar =
'A';
1235 for( i = 0; i < aFrame->rows; i++ )
1241 legendText->
SetText( wxString( legendChar ) );
1244 aItems.push_back( legendText );
1246 legendPosY += rowSpacing;
1250 if( !( aFrame->border_top ==
false ) )
1257 aItems.push_back( lines );
1260 int width = xMax - xMin;
1264 double columnSpacing = width / double( aFrame->columns );
1265 double legendPosX = xMin + ( columnSpacing / 2 );
1267 for( i = 1; i < aFrame->columns; i++ )
1269 int newX =
KiROUND( xMin + ( columnSpacing * (
double) i ) );
1273 aItems.push_back( lines );
1276 char legendChar =
'1';
1278 for( i = 0; i < aFrame->columns; i++ )
1284 legendText->
SetText( wxString( legendChar ) );
1287 aItems.push_back( legendText );
1289 legendPosX += columnSpacing;
1293 if( !( aFrame->border_bottom ==
false ) )
1300 aItems.push_back( lines );
1303 int width = xMax - xMin;
1307 double columnSpacing = width / double( aFrame->columns );
1308 double legendPosX = xMin + ( columnSpacing / 2 );
1310 for( i = 1; i < aFrame->columns; i++ )
1312 int newX =
KiROUND( xMin + ( columnSpacing * (
double) i ) );
1316 aItems.push_back( lines );
1319 char legendChar =
'1';
1321 for( i = 0; i < aFrame->columns; i++ )
1327 legendText->
SetText( wxString( legendChar ) );
1330 aItems.push_back( legendText );
1332 legendPosX += columnSpacing;
1339 const wxString& netName,
1340 const wxString& aNetClass )
1347 size_t segmentCount = aSegments.size();
1349 for(
const std::unique_ptr<ESEGMENT>& esegment : aSegments )
1351 bool labelled =
false;
1352 bool firstWireFound =
false;
1358 for(
const std::unique_ptr<EWIRE>& ewire : esegment->wires )
1367 if( !firstWireFound )
1369 firstWire = thisWire;
1370 firstWireFound =
true;
1376 if( !desc.labels.empty() && desc.labels.front()->GetText() == netName )
1379 for(
const SEG& seg : desc.segs )
1388 segDesc.
segs.push_back( thisWire );
1392 for(
const std::unique_ptr<EJUNCTION>& ejunction : esegment->junctions )
1395 for(
const std::unique_ptr<ELABEL>& elabel : esegment->labels )
1400 wxASSERT( segDesc.
labels.empty()
1403 segDesc.
labels.push_back( label );
1407 for(
const std::unique_ptr<EPINREF>& epinref : esegment->pinRefs )
1409 wxString part = epinref->part;
1410 wxString
pin = epinref->pin;
1412 auto powerPort =
m_powerPorts.find( wxT(
"#" ) + part );
1424 if( !labelled && firstWireFound )
1426 std::unique_ptr<SCH_LABEL_BASE> label;
1431 else if( segmentCount > 1 )
1436 label->SetPosition( firstWire.
A );
1441 if( firstWire.
B.
x > firstWire.
A.
x )
1446 screen->
Append( label.release() );
1455 std::unique_ptr<SCH_SHAPE> poly = std::make_unique<SCH_SHAPE>( SHAPE_T::POLY );
1459 for(
const std::unique_ptr<EVERTEX>& evertex : aPolygon->vertices )
1461 pt =
VECTOR2I( evertex->x.ToSchUnits(), -evertex->y.ToSchUnits() );
1467 poly->GetPolyShape().Append( arc, -1, -1,
ARC_ACCURACY );
1471 poly->AddPoint( pt );
1475 prev_curve = evertex->curve;
1478 poly->SetLayer(
kiCadLayer( aPolygon->layer ) );
1479 poly->SetStroke(
STROKE_PARAMS( aPolygon->width.ToSchUnits(), LINE_STYLE::SOLID ) );
1480 poly->SetFillMode( FILL_T::FILLED_SHAPE );
1482 return poly.release();
1490 start.
x = aWire->x1.ToSchUnits();
1491 start.
y = -aWire->y1.ToSchUnits();
1492 end.
x = aWire->x2.ToSchUnits();
1493 end.
y = -aWire->y2.ToSchUnits();
1496 endpoints =
SEG( start, end );
1500 std::unique_ptr<SCH_SHAPE> arc = std::make_unique<SCH_SHAPE>( SHAPE_T::ARC );
1503 arc->SetCenter( center );
1504 arc->SetStart( start );
1509 arc->SetStroke(
STROKE_PARAMS( aWire->width.ToSchUnits(), LINE_STYLE::SOLID ) );
1511 return arc.release();
1515 std::unique_ptr<SCH_LINE> line = std::make_unique<SCH_LINE>();
1517 line->SetStartPoint( start );
1518 line->SetEndPoint( end );
1519 line->SetLayer(
kiCadLayer( aWire->layer ) );
1520 line->SetStroke(
STROKE_PARAMS( aWire->width.ToSchUnits(), LINE_STYLE::SOLID ) );
1522 return line.release();
1529 std::unique_ptr<SCH_SHAPE> circle = std::make_unique<SCH_SHAPE>( SHAPE_T::CIRCLE );
1530 VECTOR2I center( aCircle->x.ToSchUnits(), -aCircle->y.ToSchUnits() );
1532 circle->SetLayer(
kiCadLayer( aCircle->layer ) );
1533 circle->SetPosition( center );
1534 circle->SetEnd(
VECTOR2I( center.
x + aCircle->radius.ToSchUnits(), center.
y ) );
1535 circle->SetStroke(
STROKE_PARAMS( aCircle->width.ToSchUnits(), LINE_STYLE::SOLID ) );
1537 return circle.release();
1543 std::unique_ptr<SCH_SHAPE> rectangle = std::make_unique<SCH_SHAPE>( SHAPE_T::RECTANGLE );
1545 rectangle->SetLayer(
kiCadLayer( aRectangle->layer ) );
1546 rectangle->SetPosition(
VECTOR2I( aRectangle->x1.ToSchUnits(), -aRectangle->y1.ToSchUnits() ) );
1547 rectangle->SetEnd(
VECTOR2I( aRectangle->x2.ToSchUnits(), -aRectangle->y2.ToSchUnits() ) );
1549 if( aRectangle->rot )
1551 VECTOR2I pos( rectangle->GetPosition() );
1552 VECTOR2I end( rectangle->GetEnd() );
1553 VECTOR2I center( rectangle->GetCenter() );
1558 rectangle->SetPosition( pos );
1559 rectangle->SetEnd( end );
1563 rectangle->SetFillMode( FILL_T::FILLED_SHAPE );
1565 return rectangle.release();
1571 std::unique_ptr<SCH_JUNCTION> junction = std::make_unique<SCH_JUNCTION>();
1573 VECTOR2I pos( aJunction->x.ToSchUnits(), -aJunction->y.ToSchUnits() );
1575 junction->SetPosition( pos );
1577 return junction.release();
1582 const wxString& aNetName )
1584 VECTOR2I elabelpos( aLabel->x.ToSchUnits(), -aLabel->y.ToSchUnits() );
1589 std::unique_ptr<SCH_LABEL_BASE> label;
1592 KiROUND( aLabel->size.ToSchUnits() * 0.7 ) );
1598 label = std::make_unique<SCH_HIERLABEL>();
1605 if( it->second->direction )
1607 wxString direction = *it->second->direction;
1609 if( direction ==
"in" )
1610 type = LABEL_SHAPE::LABEL_INPUT;
1611 else if( direction ==
"out" )
1612 type = LABEL_SHAPE::LABEL_OUTPUT;
1613 else if( direction ==
"io" )
1614 type = LABEL_SHAPE::LABEL_BIDI;
1615 else if( direction ==
"hiz" )
1616 type = LABEL_SHAPE::LABEL_TRISTATE;
1618 type = LABEL_SHAPE::LABEL_PASSIVE;
1623 label->SetLabelShape( type );
1628 label = std::make_unique<SCH_LABEL>();
1634 label = std::make_unique<SCH_GLOBALLABEL>();
1639 label = std::make_unique<SCH_LABEL>();
1643 label->SetPosition( elabelpos );
1644 label->SetTextSize( textSize );
1649 for(
int i = 0; i <
KiROUND( aLabel->rot->degrees / 90 ) %4; ++i )
1650 label->Rotate90(
false );
1652 if( aLabel->rot->mirror )
1653 label->MirrorSpinStyle(
false );
1656 return label.release();
1660std::pair<VECTOR2I, const SEG*>
1662 const std::vector<SEG>& aLines )
const
1665 const SEG* nearestLine =
nullptr;
1667 float d, mindistance = std::numeric_limits<float>::max();
1670 for(
const SEG& line : aLines )
1673 d = sqrt(
abs( ( ( aPoint.
x - testpoint.
x ) ^ 2 ) + ( ( aPoint.
y - testpoint.
y ) ^ 2 ) ) );
1675 if( d < mindistance )
1678 nearestPoint = testpoint;
1679 nearestLine = &line;
1682 testpoint = line.Center();
1683 d = sqrt(
abs( ( ( aPoint.
x - testpoint.
x ) ^ 2 ) + ( ( aPoint.
y - testpoint.
y ) ^ 2 ) ) );
1685 if( d < mindistance )
1688 nearestPoint = testpoint;
1689 nearestLine = &line;
1693 d = sqrt(
abs( ( ( aPoint.
x - testpoint.
x ) ^ 2 ) + ( ( aPoint.
y - testpoint.
y ) ^ 2 ) ) );
1695 if( d < mindistance )
1698 nearestPoint = testpoint;
1699 nearestLine = &line;
1703 return std::make_pair( nearestPoint, nearestLine );
1708 const std::map<wxString, std::unique_ptr<EPART>>& aParts )
1710 wxCHECK( aInstance, );
1716 const auto partIt = aParts.find( aInstance->part );
1718 if( partIt == aParts.end() )
1720 Report( wxString::Format(
_(
"Error parsing Eagle file. Could not find '%s' "
1721 "instance but it is referenced in the schematic." ),
1728 const std::unique_ptr<EPART>& epart = partIt->second;
1730 wxString libName = epart->library;
1733 if( epart->libraryUrn )
1734 libName += wxS(
"_" ) + epart->libraryUrn->assetId;
1736 wxString gatename = epart->deviceset + wxS(
"_" ) + epart->device + wxS(
"_" ) +
1738 wxString symbolname = wxString( epart->deviceset + epart->device );
1739 symbolname.Replace( wxT(
"*" ), wxEmptyString );
1747 wxString altSymbolName = libName + wxT(
"_" ) + symbolname;
1750 wxString libIdSymbolName = altSymbolName;
1756 Report( wxString::Format( wxS(
"Eagle library '%s' not found while looking up symbol for "
1757 "deviceset '%s', device '%s', and gate '%s." ),
1758 libName, epart->deviceset, epart->device, aInstance->gate ) );
1762 const auto gateIt = libIt->second.GateToUnitMap.find( gatename );
1764 if( gateIt == libIt->second.GateToUnitMap.end() )
1766 Report( wxString::Format( wxS(
"Symbol not found for deviceset '%s', device '%s', and "
1767 "gate '%s in library '%s'." ),
1768 epart->deviceset, epart->device, aInstance->gate, libName ) );
1772 int unit = gateIt->second;
1777 auto p = elib->
package.find( kisymbolname );
1779 if( p != elib->
package.end() )
1780 package = p->second;
1782 LIB_SYMBOL* part = m_pi->LoadSymbol( getLibFileName().GetFullPath(), altSymbolName,
1783 m_properties.get() );
1787 part = m_pi->LoadSymbol( getLibFileName().GetFullPath(), kisymbolname,
1788 m_properties.get() );
1789 libIdSymbolName = kisymbolname;
1794 Report( wxString::Format(
_(
"Could not find '%s' in the imported library." ),
1800 LIB_ID libId( getLibName(), libIdSymbolName );
1801 std::unique_ptr<SCH_SYMBOL> symbol = std::make_unique<SCH_SYMBOL>();
1802 symbol->SetLibId( libId );
1803 symbol->SetUnit( unit );
1804 symbol->SetPosition(
VECTOR2I( aInstance->x.ToSchUnits(), -aInstance->y.ToSchUnits() ) );
1807 if( !package.IsEmpty() )
1809 wxString footprint = m_schematic->Prj().GetProjectName() + wxT(
":" ) + package;
1813 if( aInstance->rot )
1817 if( aInstance->rot->mirror )
1818 symbol->MirrorHorizontally( aInstance->x.ToSchUnits() );
1821 std::vector<SCH_FIELD*> partFields;
1824 for(
const SCH_FIELD* field : partFields )
1826 symbol->GetFieldById( field->GetId() )->ImportValues( *field );
1827 symbol->GetFieldById( field->GetId() )->SetTextPos( (
VECTOR2I)symbol->GetPosition()
1828 + field->GetTextPos() );
1833 wxString reference = package.IsEmpty() ?
'#' + aInstance->part : aInstance->part;
1836 if( reference.find_last_not_of( wxT(
"0123456789" ) ) == ( reference.Length()-1 ) )
1837 reference.Append( wxT(
"0" ) );
1842 if( reference.find_first_not_of( wxT(
"0123456789" ) ) != 0 )
1843 reference.Prepend( wxT(
"UNK" ) );
1847 if( aInstance->part.find_first_not_of( wxT(
"#" ) ) != 0 )
1848 reference.Prepend( wxT(
"UNK" ) );
1851 referenceField->
SetText( reference );
1854 bool userValue = m_userValue.at( libIdSymbolName );
1858 getEagleSymbolFieldAttributes( aInstance, wxS(
">NAME" ), referenceField );
1859 getEagleSymbolFieldAttributes( aInstance, wxS(
">VALUE" ), valueField );
1862 if( epart->value && !epart->value.CGet().IsEmpty() )
1864 valueField->
SetText( *epart->value );
1868 valueField->
SetText( kisymbolname );
1874 for(
const auto& [ attrName, attr ] : epart->attributes )
1877 SCH_FIELD* lastField = symbol->GetFieldById( symbol->GetFieldCount() - 1 );
1882 SCH_FIELD newField( newFieldPosition, symbol->GetFieldCount(), symbol.get() );
1887 newField.
SetText( *attr->value );
1891 symbol->AddField( newField );
1894 for(
const auto& [variantName, variant] : epart->variants )
1897 field->
SetName( wxT(
"VARIANT_" ) + variant->name );
1899 if( variant->value )
1900 field->
SetText( *variant->value );
1905 bool valueAttributeFound =
false;
1906 bool nameAttributeFound =
false;
1909 for(
auto& [
name, eattr] : aInstance->attributes )
1913 if( eattr->name.Lower() == wxT(
"name" ) )
1916 nameAttributeFound =
true;
1918 else if( eattr->name.Lower() == wxT(
"value" ) )
1921 valueAttributeFound =
true;
1925 field = symbol->FindField( eattr->name );
1935 int absdegrees = eattr->rot ? eattr->rot->degrees : 0;
1936 bool mirror = eattr->rot ? eattr->rot->mirror :
false;
1938 if( aInstance->rot && aInstance->rot->mirror )
1941 bool spin = eattr->rot ? eattr->rot->spin :
false;
1946 int rotation = aInstance->rot ? aInstance->rot->degrees : 0;
1947 int reldegrees = ( absdegrees - rotation + 360.0 );
1955 if( aInstance->smashed && aInstance->smashed.Get() )
1957 symbol->GetField(
VALUE_FIELD )->SetVisible( valueAttributeFound );
1958 symbol->GetField(
REFERENCE_FIELD )->SetVisible( nameAttributeFound );
1961 symbol->AddHierarchicalReference( m_sheetPath.Path(), reference, unit );
1967 wxCHECK( libSymbol, );
1969 symbol->SetLibSymbol(
new LIB_SYMBOL( *libSymbol ) );
1971 for(
const SCH_PIN*
pin : symbol->GetLibPins() )
1972 m_connPoints[symbol->GetPinPhysicalPosition(
pin )].emplace(
pin );
1975 m_powerPorts[ reference ] = symbol->GetField(
VALUE_FIELD )->GetText();
1977 symbol->ClearFlags();
1979 screen->
Append( symbol.release() );
1985 wxCHECK( aLibrary && aEagleLibrary,
nullptr );
1991 wxString prefix = edeviceset->prefix ? edeviceset->prefix.Get() : wxString( wxT(
"" ) );
1992 wxString deviceSetDescr;
1994 if( edeviceset->description )
1998 for(
const std::unique_ptr<EDEVICE>& edevice : edeviceset->devices )
2001 wxString symbolName = edeviceset->name + edevice->name;
2002 symbolName.Replace( wxT(
"*" ), wxEmptyString );
2003 wxASSERT( !symbolName.IsEmpty() );
2006 if( edevice->package )
2007 aEagleLibrary->
package[symbolName] = edevice->package.Get();
2010 std::unique_ptr<LIB_SYMBOL> libSymbol = std::make_unique<LIB_SYMBOL>( symbolName );
2013 int gate_count =
static_cast<int>( edeviceset->gates.size() );
2014 libSymbol->SetUnitCount( gate_count );
2015 libSymbol->LockUnits(
true );
2019 if( prefix.length() == 0 )
2027 reference->
SetText( edevice->package ? prefix :
'#' + prefix );
2030 libSymbol->GetFieldById(
VALUE_FIELD )->SetVisible(
true );
2033 bool ispower =
false;
2035 for(
const auto& [gateName, egate] : edeviceset->gates )
2037 const auto it = aLibrary->
symbols.find( egate->symbol );
2039 if( it == aLibrary->
symbols.end() )
2041 Report( wxString::Format( wxS(
"Eagle symbol '%s' not found in library '%s'." ),
2042 egate->symbol, aLibrary->
GetName() ) );
2046 wxString gateMapName = edeviceset->name + wxS(
"_" ) + edevice->name +
2047 wxS(
"_" ) + egate->name;
2049 ispower =
loadSymbol( it->second, libSymbol, edevice, gateindex, egate->name );
2054 libSymbol->SetUnitCount( gate_count );
2056 if( gate_count == 1 && ispower )
2057 libSymbol->SetPower();
2060 if( edevice->package )
2074 wxString packageString = libName + wxT(
":" ) + aEagleLibrary->
package[symbolName];
2076 libSymbol->GetFootprintField().SetText( packageString );
2079 wxString libName = libSymbol->GetName();
2080 libSymbol->SetName( libName );
2081 libSymbol->SetDescription( deviceSetDescr );
2091 libName = aEagleLibrary->
name + wxT(
"_" ) + libName;
2093 libSymbol->SetName( libName );
2107 aEagleLibrary->
KiCadSymbols[ libName ] = std::move( libSymbol );
2111 m_userValue.emplace( std::make_pair( libName, edeviceset->uservalue ==
true ) );
2115 return aEagleLibrary;
2120 std::unique_ptr<LIB_SYMBOL>& aSymbol,
2121 const std::unique_ptr<EDEVICE>& aDevice,
int aGateNumber,
2122 const wxString& aGateName )
2124 wxCHECK( aEsymbol && aSymbol && aDevice,
false );
2126 wxString symbolName = aEsymbol->name;
2127 std::vector<SCH_ITEM*> items;
2129 bool showRefDes =
false;
2130 bool showValue =
false;
2131 bool ispower =
false;
2134 for(
const std::unique_ptr<ECIRCLE>& ecircle : aEsymbol->circles )
2137 for(
const std::unique_ptr<EPIN>& epin : aEsymbol->pins )
2139 std::unique_ptr<SCH_PIN>
pin(
loadPin( aSymbol, epin, aGateNumber ) );
2142 pin->SetType( ELECTRICAL_PINTYPE::PT_BIDI );
2144 if( epin->direction )
2148 if( epin->direction->Lower() == pinDir.first )
2150 pin->SetType( pinDir.second );
2152 if( pinDir.first == wxT(
"sup" ) )
2161 if( aDevice->connects.size() != 0 )
2163 for(
const std::unique_ptr<ECONNECT>& connect : aDevice->connects )
2165 if( connect->gate == aGateName &&
pin->GetName() == connect->pin )
2167 wxArrayString pads = wxSplit( wxString( connect->pad ),
' ' );
2169 pin->SetUnit( aGateNumber );
2172 if( pads.GetCount() > 1 )
2174 pin->SetNumberTextSize( 0 );
2177 for(
unsigned i = 0; i < pads.GetCount(); i++ )
2181 wxString padname( pads[i] );
2183 aSymbol->AddDrawItem( apin );
2192 pin->SetUnit( aGateNumber );
2193 pin->SetNumber( wxString::Format( wxT(
"%i" ), pincount ) );
2194 aSymbol->AddDrawItem(
pin.release() );
2198 for(
const std::unique_ptr<EPOLYGON>& epolygon : aEsymbol->polygons )
2201 for(
const std::unique_ptr<ERECT>& erectangle : aEsymbol->rectangles )
2204 for(
const std::unique_ptr<ETEXT>& etext : aEsymbol->texts )
2206 std::unique_ptr<SCH_TEXT> libtext(
loadSymbolText( aSymbol, etext, aGateNumber ) );
2208 if( libtext->GetText() == wxT(
"${REFERENCE}" ) )
2215 showRefDes = etext->text == wxT(
">NAME" );
2217 else if( libtext->GetText() == wxT(
"${VALUE}" ) )
2224 showValue = etext->text == wxT(
">VALUE" );
2228 aSymbol->AddDrawItem( libtext.release() );
2232 for(
const std::unique_ptr<EWIRE>& ewire : aEsymbol->wires )
2233 aSymbol->AddDrawItem(
loadSymbolWire( aSymbol, ewire, aGateNumber ) );
2235 for(
const std::unique_ptr<EFRAME>& eframe : aEsymbol->frames )
2237 std::vector<SCH_ITEM*> frameItems;
2243 item->SetParent( aSymbol.get() );
2244 item->SetUnit( aGateNumber );
2245 aSymbol->AddDrawItem( item );
2250 aSymbol->GetFieldById(
VALUE_FIELD )->SetVisible( showValue );
2252 return pincount == 1 ? ispower :
false;
2257 const std::unique_ptr<ECIRCLE>& aCircle,
2260 wxCHECK( aSymbol && aCircle,
nullptr );
2264 VECTOR2I center( aCircle->x.ToSchUnits(), -aCircle->y.ToSchUnits() );
2268 circle->
SetEnd(
VECTOR2I( center.
x + aCircle->radius.ToSchUnits(), center.
y ) );
2270 circle->
SetUnit( aGateNumber );
2277 const std::unique_ptr<ERECT>& aRectangle,
2280 wxCHECK( aSymbol && aRectangle,
nullptr );
2285 rectangle->
SetPosition(
VECTOR2I( aRectangle->x1.ToSchUnits(), -aRectangle->y1.ToSchUnits() ) );
2286 rectangle->
SetEnd(
VECTOR2I( aRectangle->x2.ToSchUnits(), -aRectangle->y2.ToSchUnits() ) );
2288 if( aRectangle->rot )
2298 rectangle->
SetEnd( end );
2301 rectangle->
SetUnit( aGateNumber );
2311 const std::unique_ptr<EWIRE>& aWire,
int aGateNumber )
2313 wxCHECK( aSymbol && aWire,
nullptr );
2317 begin.
x = aWire->x1.ToSchUnits();
2318 begin.
y = -aWire->y1.ToSchUnits();
2319 end.
x = aWire->x2.ToSchUnits();
2320 end.
y = -aWire->y2.ToSchUnits();
2330 double radius = sqrt( ( ( center.
x - begin.
x ) * ( center.
x - begin.
x ) ) +
2331 ( ( center.
y - begin.
y ) * ( center.
y - begin.
y ) ) );
2336 if( aWire->cap ==
EWIRE::FLAT && aWire->width.ToSchUnits() >= 2 * radius )
2338 VECTOR2I centerStartVector = ( begin - center ) *
2339 ( aWire->width.ToSchUnits() / radius );
2340 begin = center + centerStartVector;
2372 const std::unique_ptr<EPOLYGON>& aPolygon,
2375 wxCHECK( aSymbol && aPolygon,
nullptr );
2383 for(
const std::unique_ptr<EVERTEX>& evertex : aPolygon->vertices )
2385 pt =
VECTOR2I( evertex->x.ToSchUnits(), evertex->y.ToSchUnits() );
2399 prev_curve = evertex->curve;
2411 const std::unique_ptr<EPIN>& aPin,
int aGateNumber )
2413 wxCHECK( aSymbol && aPin,
nullptr );
2415 std::unique_ptr<SCH_PIN>
pin = std::make_unique<SCH_PIN>( aSymbol.get() );
2416 pin->SetPosition(
VECTOR2I( aPin->x.ToSchUnits(), -aPin->y.ToSchUnits() ) );
2417 pin->SetName( aPin->name );
2418 pin->SetUnit( aGateNumber );
2420 int roti = aPin->rot ? aPin->rot->degrees : 0;
2424 case 0:
pin->SetOrientation( PIN_ORIENTATION::PIN_RIGHT );
break;
2425 case 90:
pin->SetOrientation( PIN_ORIENTATION::PIN_UP );
break;
2426 case 180:
pin->SetOrientation( PIN_ORIENTATION::PIN_LEFT );
break;
2427 case 270:
pin->SetOrientation( PIN_ORIENTATION::PIN_DOWN );
break;
2428 default: wxFAIL_MSG( wxString::Format( wxT(
"Unhandled orientation (%d degrees)." ), roti ) );
2435 wxString length = aPin->length.Get();
2437 if( length == wxT(
"short" ) )
2439 else if( length == wxT(
"middle" ) )
2441 else if( length == wxT(
"long" ) )
2443 else if( length == wxT(
"point" ) )
2454 wxString visible = aPin->visible.Get();
2456 if( visible == wxT(
"off" ) )
2458 pin->SetNameTextSize( 0 );
2459 pin->SetNumberTextSize( 0 );
2461 else if( visible == wxT(
"pad" ) )
2463 pin->SetNameTextSize( 0 );
2465 else if( visible == wxT(
"pin" ) )
2467 pin->SetNumberTextSize( 0 );
2477 if( aPin->function )
2479 wxString function = aPin->function.Get();
2481 if( function == wxT(
"dot" ) )
2482 pin->SetShape( GRAPHIC_PINSHAPE::INVERTED );
2483 else if( function == wxT(
"clk" ) )
2484 pin->SetShape( GRAPHIC_PINSHAPE::CLOCK );
2485 else if( function == wxT(
"dotclk" ) )
2486 pin->SetShape( GRAPHIC_PINSHAPE::INVERTED_CLOCK );
2489 return pin.release();
2494 const std::unique_ptr<ETEXT>& aText,
int aGateNumber )
2496 wxCHECK( aSymbol && aText,
nullptr );
2498 std::unique_ptr<SCH_TEXT> libtext = std::make_unique<SCH_TEXT>();
2500 libtext->SetParent( aSymbol.get() );
2501 libtext->SetUnit( aGateNumber );
2502 libtext->SetPosition(
VECTOR2I( aText->x.ToSchUnits(), -aText->y.ToSchUnits() ) );
2504 const wxString& eagleText = aText->text;
2505 wxString adjustedText;
2506 wxStringTokenizer tokenizer( eagleText,
"\r\n" );
2509 while( tokenizer.HasMoreTokens() )
2511 wxString tmp =
interpretText( tokenizer.GetNextToken().Trim(
true ).Trim(
false ) );
2513 if( tokenizer.HasMoreTokens() )
2516 adjustedText += tmp;
2519 libtext->SetText( adjustedText.IsEmpty() ? wxString( wxS(
"~" ) ) : adjustedText );
2523 return libtext.release();
2529 wxCHECK( aText,
nullptr );
2531 std::unique_ptr<SCH_TEXT> schtext = std::make_unique<SCH_TEXT>();
2533 const wxString& eagleText = aText->text;
2534 wxString adjustedText;
2535 wxStringTokenizer tokenizer( eagleText,
"\r\n" );
2538 while( tokenizer.HasMoreTokens() )
2540 wxString tmp =
interpretText( tokenizer.GetNextToken().Trim(
true ).Trim(
false ) );
2542 if( tokenizer.HasMoreTokens() )
2545 adjustedText += tmp;
2548 schtext->SetText( adjustedText.IsEmpty() ? wxString( wxS(
"\" \"" ) )
2551 schtext->SetPosition(
VECTOR2I( aText->x.ToSchUnits(), -aText->y.ToSchUnits() ) );
2553 schtext->SetItalic(
false );
2555 return schtext.release();
2560 const std::unique_ptr<ETEXT>& aAttributes )
const
2562 wxCHECK( aText && aAttributes, );
2567 if( aAttributes->ratio && aAttributes->ratio.CGet() > 12 )
2571 int degrees = aAttributes->rot ? aAttributes->rot->degrees : 0;
2572 bool mirror = aAttributes->rot ? aAttributes->rot->mirror :
false;
2573 bool spin = aAttributes->rot ? aAttributes->rot->spin :
false;
2581 wxCHECK( aField && aText, );
2605 auto onIntersection =
2614 for(
SCH_TEXT* label : segDesc.labels )
2617 const SEG* segAttached = segDesc.LabelAttached( label );
2619 if( segAttached && !onIntersection( labelPos ) )
2633 VECTOR2I wireDirection( segAttached->
B - segAttached->
A );
2635 const VECTOR2I origPos( labelPos );
2638 bool checkPositive =
true, checkNegative =
true,
move =
false;
2642 while( ( !
move || onIntersection( labelPos ) ) && ( checkPositive || checkNegative ) )
2647 if( trial % 2 == 1 )
2649 labelPos =
VECTOR2I( origPos + wireDirection * trial / 2 );
2650 move = checkPositive = segAttached->
Contains( labelPos );
2654 labelPos =
VECTOR2I( origPos - wireDirection * trial / 2 );
2655 move = checkNegative = segAttached->
Contains( labelPos );
2691 wxFileInputStream input( aFileName );
2696 wxTextInputStream
text( input );
2698 for(
int i = 0; i < 8; i++ )
2703 if(
text.ReadLine().Contains( wxS(
"<eagle" ) ) )
2721 if( !item->IsType( { SCH_LABEL_LOCATE_ANY_T } ) )
2725 item->SetPosition( aNewEndPoint );
2738 std::vector<SCH_LINE*> buses;
2739 std::vector<SCH_LINE*> wires;
2750 buses.push_back( line );
2751 else if( line->
IsWire() )
2752 wires.push_back( line );
2757 VECTOR2I wireStart = wire->GetStartPoint();
2758 VECTOR2I wireEnd = wire->GetEndPoint();
2762 VECTOR2I busStart = bus->GetStartPoint();
2763 VECTOR2I busEnd = bus->GetEndPoint();
2766 [](
int signX,
int signY ) ->
VECTOR2I
2778 if( wireStart.
y == wireEnd.
y && busStart.
x == busEnd.
x )
2782 if( testBusHit( wireStart ) )
2786 if( wireEnd.
x < busStart.
x )
2793 VECTOR2I p = wireStart + entrySize( -1, 0 );
2795 if( testBusHit( wireStart + entrySize( 0, -1 ) ) )
2804 screen->
Append( busEntry );
2806 wire->SetStartPoint( p );
2808 else if( testBusHit( wireStart + entrySize( 0, 1 ) ) )
2817 screen->
Append( busEntry );
2819 wire->SetStartPoint( p );
2825 screen->
Append( marker );
2835 VECTOR2I p = wireStart + entrySize( 1, 0 );
2837 if( testBusHit( wireStart + entrySize( 0, -1 ) ) )
2846 screen->
Append( busEntry );
2848 wire->SetStartPoint( p );
2850 else if( testBusHit( wireStart + entrySize( 0, 1 ) ) )
2859 screen->
Append( busEntry );
2861 wire->SetStartPoint( p );
2867 screen->
Append( marker );
2873 else if( testBusHit( wireEnd ) )
2877 if( wireStart.
x < busStart.
x )
2884 VECTOR2I p = wireEnd + entrySize( -1, 0 );
2886 if( testBusHit( wireEnd + entrySize( 0, -1 ) ) )
2895 screen->
Append( busEntry );
2897 wire->SetEndPoint( p );
2899 else if( testBusHit( wireEnd + entrySize( 0, -1 ) ) )
2908 screen->
Append( busEntry );
2909 moveLabels( wire, wireEnd + entrySize( -1, 0 ) );
2910 wire->SetEndPoint( wireEnd + entrySize( -1, 0 ) );
2916 screen->
Append( marker );
2926 VECTOR2I p = wireEnd + entrySize( 1, 0 );
2928 if( testBusHit( wireEnd + entrySize( 0, -1 ) ) )
2937 screen->
Append( busEntry );
2939 wire->SetEndPoint( p );
2941 else if( testBusHit( wireEnd + entrySize( 0, 1 ) ) )
2950 screen->
Append( busEntry );
2952 wire->SetEndPoint( p );
2958 screen->
Append( marker );
2965 else if( wireStart.
x == wireEnd.
x && busStart.
y == busEnd.
y )
2969 if( testBusHit( wireStart ) )
2973 if( wireEnd.
y < busStart.
y )
2981 VECTOR2I p = wireStart + entrySize( 0, -1 );
2983 if( testBusHit( wireStart + entrySize( -1, 0 ) ) )
2993 screen->
Append( busEntry );
2995 wire->SetStartPoint( p );
2997 else if( testBusHit( wireStart + entrySize( 1, 0 ) ) )
3007 screen->
Append( busEntry );
3009 wire->SetStartPoint( p );
3015 screen->
Append( marker );
3026 VECTOR2I p = wireStart + entrySize( 0, 1 );
3028 if( testBusHit( wireStart + entrySize( -1, 0 ) ) )
3038 screen->
Append( busEntry );
3040 wire->SetStartPoint( p );
3042 else if( testBusHit( wireStart + entrySize( 1, 0 ) ) )
3052 screen->
Append( busEntry );
3054 wire->SetStartPoint( p );
3060 screen->
Append( marker );
3066 else if( testBusHit( wireEnd ) )
3070 if( wireStart.
y < busStart.
y )
3078 VECTOR2I p = wireEnd + entrySize( 0, -1 );
3080 if( testBusHit( wireEnd + entrySize( -1, 0 ) ) )
3090 screen->
Append( busEntry );
3092 wire->SetEndPoint( p );
3094 else if( testBusHit( wireEnd + entrySize( 1, 0 ) ) )
3104 screen->
Append( busEntry );
3106 wire->SetEndPoint( p );
3112 screen->
Append( marker );
3123 VECTOR2I p = wireEnd + entrySize( 0, 1 );
3125 if( testBusHit( wireEnd + entrySize( -1, 0 ) ) )
3135 screen->
Append( busEntry );
3137 wire->SetEndPoint( p );
3139 else if( testBusHit( wireEnd + entrySize( 1, 0 ) ) )
3149 screen->
Append( busEntry );
3151 wire->SetEndPoint( p );
3157 screen->
Append( marker );
3168 if( testBusHit( wireStart ) )
3170 VECTOR2I wirevector = wireStart - wireEnd;
3172 if( wirevector.
x > 0 )
3174 if( wirevector.
y > 0 )
3176 VECTOR2I p = wireStart + entrySize( -1, -1 );
3179 screen->
Append( busEntry );
3182 wire->SetStartPoint( p );
3186 VECTOR2I p = wireStart + entrySize( -1, 1 );
3189 screen->
Append( busEntry );
3192 wire->SetStartPoint( p );
3197 if( wirevector.
y > 0 )
3199 VECTOR2I p = wireStart + entrySize( 1, -1 );
3202 screen->
Append( busEntry );
3205 wire->SetStartPoint( p );
3209 VECTOR2I p = wireStart + entrySize( 1, 1 );
3212 screen->
Append( busEntry );
3215 wire->SetStartPoint( p );
3221 else if( testBusHit( wireEnd ) )
3223 VECTOR2I wirevector = wireStart - wireEnd;
3225 if( wirevector.
x > 0 )
3227 if( wirevector.
y > 0 )
3229 VECTOR2I p = wireEnd + entrySize( 1, 1 );
3232 screen->
Append( busEntry );
3235 wire->SetEndPoint( p );
3239 VECTOR2I p = wireEnd + entrySize( 1, -1 );
3242 screen->
Append( busEntry );
3245 wire->SetEndPoint( p );
3250 if( wirevector.
y > 0 )
3252 VECTOR2I p = wireEnd + entrySize( -1, 1 );
3255 screen->
Append( busEntry );
3258 wire->SetEndPoint( p );
3262 VECTOR2I p = wireEnd + entrySize( -1, -1 );
3265 screen->
Append( busEntry );
3268 wire->SetEndPoint( p );
3282 wxCHECK( aLabel,
nullptr );
3286 for(
const SEG& seg : segs )
3288 if( seg.Contains( labelPos ) )
3300 wxCHECK( aSymbol && aPin,
false );
3308 const auto& items = pointIt->second;
3310 wxCHECK( items.find( aPin ) != items.end(),
false );
3312 return items.size() > 1;
3326 int unit = aSymbol->
GetUnit();
3329 std::set<int> missingUnits;
3334 if(
pin->GetType() == ELECTRICAL_PINTYPE::PT_POWER_IN )
3336 bool pinInUnit = !unit ||
pin->GetUnit() == unit;
3350 switch(
pin->GetOrientation() )
3353 case PIN_ORIENTATION::PIN_RIGHT:
3356 case PIN_ORIENTATION::PIN_LEFT:
3359 case PIN_ORIENTATION::PIN_UP:
3362 case PIN_ORIENTATION::PIN_DOWN:
3367 aScreen->
Append( netLabel );
3370 else if( aUpdateSet )
3375 wxASSERT(
pin->GetUnit() );
3376 missingUnits.insert(
pin->GetUnit() );
3389 entry.
cmp = aSymbol;
3390 entry.
units.emplace( unit,
false );
3395 cmpIt->second.units[unit] =
false;
3398 if( !missingUnits.empty() )
3401 entry.
cmp = aSymbol;
3404 for(
int i : missingUnits )
3406 if( entry.
units.find( i ) != entry.
units.end() )
3407 entry.
units.emplace( i,
true );
3419 wxString ret = wxT(
"{" );
3421 wxStringTokenizer tokenizer( aEagleName, wxT(
"," ) );
3423 while( tokenizer.HasMoreTokens() )
3425 wxString member = tokenizer.GetNextToken();
3432 if( member.Freq(
'!' ) % 2 > 0 )
3433 member << wxT(
"!" );
3435 ret << member << wxS(
" " );
3450 std::unique_ptr<EPART>& epart =
m_eagleDoc->drawing->schematic->parts[aInstance->part];
3452 if( !epart || epart->deviceset.IsEmpty() )
3455 std::unique_ptr<ELIBRARY>& elibrary =
m_eagleDoc->drawing->schematic->libraries[epart->library];
3460 std::unique_ptr<EDEVICE_SET>& edeviceset = elibrary->devicesets[epart->deviceset];
3465 std::unique_ptr<EGATE>& egate = edeviceset->gates[aInstance->gate];
3470 std::unique_ptr<ESYMBOL>& esymbol = elibrary->symbols[egate->symbol];
3473 return esymbol.get();
3480 const wxString& aEagleFieldName,
3483 wxCHECK( aField && !aEagleFieldName.
IsEmpty(), );
3489 for(
const std::unique_ptr<ETEXT>&
text : esymbol->
texts )
3491 if(
text->text == aEagleFieldName )
3494 VECTOR2I pos(
text->x.ToSchUnits() + aInstance->x.ToSchUnits(),
3495 -
text->y.ToSchUnits() - aInstance->y.ToSchUnits() );
3497 bool mirror =
text->rot ?
text->rot->mirror :
false;
3499 if( aInstance->rot && aInstance->rot->mirror )
3503 pos.
y = -aInstance->y.ToSchUnits() +
text->y.ToSchUnits();
constexpr EDA_IU_SCALE schIUScale
constexpr BOX2I KiROUND(const BOX2D &aBoxD)
constexpr coord_type GetY() const
constexpr size_type GetWidth() const
constexpr Vec Centre() const
constexpr BOX2< Vec > & Merge(const BOX2< Vec > &aRect)
Modify the position and size of the rectangle in order to contain aRect.
constexpr size_type GetHeight() const
constexpr coord_type GetLeft() const
constexpr const SizeVec & GetSize() const
constexpr coord_type GetBottom() const
void SetFlags(EDA_ITEM_FLAGS aMask)
virtual void SetParent(EDA_ITEM *aParent)
void SetCenter(const VECTOR2I &aCenter)
SHAPE_POLY_SET & GetPolyShape()
const VECTOR2I & GetEnd() const
Return the ending point of the graphic.
void SetStart(const VECTOR2I &aStart)
void SetEnd(const VECTOR2I &aEnd)
void SetArcAngleAndEnd(const EDA_ANGLE &aAngle, bool aCheckNegativeAngle=false)
Set the end point from the angle center and start.
void SetFillMode(FILL_T aFill)
A mix-in class (via multiple inheritance) that handles texts such as labels, parts,...
const EDA_ANGLE & GetTextAngle() const
void SetTextSize(VECTOR2I aNewSize, bool aEnforceMinTextSize=true)
virtual const wxString & GetText() const
Return the string associated with the text object.
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 SetBold(bool aBold)
Set the text to be bold - this will also update the font if needed.
GR_TEXT_V_ALIGN_T GetVertJustify() const
virtual void SetText(const wxString &aText)
virtual void SetTextAngle(const EDA_ANGLE &aAngle)
void SetItalic(bool aItalic)
Set the text to be italic - this will also update the font if needed.
VECTOR2I GetTextSize() const
void SetHorizJustify(GR_TEXT_H_ALIGN_T aType)
EE_TYPE Overlapping(const BOX2I &aRect) const
iterator end()
Returns a read/write iterator that points to one past the last element in the EE_RTREE.
iterator begin()
Returns a read/write iterator that points to the first element in the EE_RTREE N.B.
EE_TYPE OfType(KICAD_T aType) const
static std::shared_ptr< ERC_ITEM > Create(int aErrorCode)
Constructs an ERC_ITEM for the given error code.
REPORTER * m_reporter
Reporter to log errors/warnings to, may be nullptr.
PROGRESS_REPORTER * m_progressReporter
Progress reporter to track the progress of the operation, may be nullptr.
virtual bool CanReadLibrary(const wxString &aFileName) const
Checks if this IO object can read the specified library file/directory.
virtual void Report(const wxString &aText, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED)
A logical library item identifier and consists of various portions much like a URI.
static UTF8 FixIllegalChars(const UTF8 &aLibItemName, bool aLib)
Replace illegal LIB_ID item name characters with underscores '_'.
Define a library symbol object.
bool IsPower() const override
void GetFields(std::vector< SCH_FIELD * > &aList, bool aVisibleOnly=false) override
Return a list of fields within this symbol.
int GetUnitCount() const override
bool HasLibrary(const wxString &aNickname, bool aCheckEnabled=false) const
Test for the existence of aNickname in the library table.
bool InsertRow(LIB_TABLE_ROW *aRow, bool doReplace=false)
Adds aRow if it does not already exist or if doReplace is true.
Instantiate the current locale within a scope in which you are expecting exceptions to be thrown.
static bool ParseBusVector(const wxString &aBus, wxString *aName, std::vector< wxString > *aMemberList)
Parse a bus vector (e.g.
Describe the page size and margins of a paper page on which to eventually print or plot.
void SetHeightMils(double aHeightInMils)
const VECTOR2D GetSizeIU(double aIUScale) const
Gets the page size in internal units.
void SetWidthMils(double aWidthInMils)
virtual bool KeepRefreshing(bool aWait=false)=0
Update the UI (if any).
virtual void SetNumPhases(int aNumPhases)=0
Set the number of phases.
virtual void Report(const wxString &aMessage)=0
Display aMessage in the progress bar dialog.
static SYMBOL_LIB_TABLE * SchSymbolLibTable(PROJECT *aProject)
Accessor for project symbol library table.
virtual void SetElem(PROJECT::ELEM aIndex, _ELEM *aElem)
virtual const wxString GetProjectPath() const
Return the full path of the project.
virtual const wxString GetProjectName() const
Return the short name of the project.
Holds all the data relating to one schematic.
void SetRoot(SCH_SHEET *aRootSheet)
Initialize the schematic with a new root sheet.
bool IsValid() const
A simple test if the schematic is loaded, not a complete one.
PROJECT & Prj() const override
Return a reference to the project this schematic is part of.
Class for a wire to bus entry.
Instances are attached to a symbol or sheet and provide a place for the symbol's value,...
VECTOR2I GetPosition() const override
bool IsEmpty()
Return true if both the name and value of the field are empty.
void SetPosition(const VECTOR2I &aPosition) override
void SetName(const wxString &aName)
void SetText(const wxString &aText) override
void SetSpinStyle(SPIN_STYLE aSpinStyle) override
std::unique_ptr< EAGLE_DOC > m_eagleDoc
SCH_ITEM * loadWire(const std::unique_ptr< EWIRE > &aWire, SEG &endpoints)
void loadTextAttributes(EDA_TEXT *aText, const std::unique_ptr< ETEXT > &aAttributes) const
SCH_TEXT * loadLabel(const std::unique_ptr< ELABEL > &aLabel, const wxString &aNetName)
void ensureLoadedLibrary(const wxString &aLibraryPath)
void loadSchematic(const ESCHEMATIC &aSchematic)
SCH_TEXT * loadPlainText(const std::unique_ptr< ETEXT > &aSchText)
void loadSheet(const std::unique_ptr< ESHEET > &aSheet)
void loadLayerDefs(const std::vector< std::unique_ptr< ELAYER > > &aLayers)
const ESYMBOL * getEagleSymbol(const std::unique_ptr< EINSTANCE > &aInstance)
EAGLE_LIBRARY * loadLibrary(const ELIBRARY *aLibrary, EAGLE_LIBRARY *aEagleLib)
wxXmlDocument loadXmlDocument(const wxString &aFileName)
wxString translateEagleBusName(const wxString &aEagleName) const
Translate an Eagle-style bus name into one that is KiCad-compatible.
void loadFieldAttributes(SCH_FIELD *aField, const SCH_TEXT *aText) const
Move net labels that are detached from any wire to the nearest wire.
std::map< wxString, wxString > m_powerPorts
map from symbol reference to global label equivalent
SCH_SHEET_PATH m_sheetPath
The current sheet path of the schematic being loaded.
wxString m_libName
Library name to save symbols.
EMODULE * m_module
The current module being loaded or nullptr.
SCH_TEXT * loadSymbolText(std::unique_ptr< LIB_SYMBOL > &aSymbol, const std::unique_ptr< ETEXT > &aText, int aGateNumber)
std::pair< VECTOR2I, const SEG * > findNearestLinePoint(const VECTOR2I &aPoint, const std::vector< SEG > &aLines) const
const double ARC_ACCURACY
std::map< wxString, long long > m_timestamps
void loadInstance(const std::unique_ptr< EINSTANCE > &aInstance, const std::map< wxString, std::unique_ptr< EPART > > &aParts)
LIB_SYMBOL * LoadSymbol(const wxString &aLibraryPath, const wxString &aAliasName, const std::map< std::string, UTF8 > *aProperties) override
Load a LIB_SYMBOL object having aPartName from the aLibraryPath containing a library format that this...
std::unordered_map< wxString, bool > m_userValue
deviceset/@uservalue for device.
int GetModifyHash() const override
Return the modification hash from the library cache.
std::map< wxString, int > m_netCounts
std::map< wxString, EAGLE_LIBRARY > m_eagleLibs
bool loadSymbol(const std::unique_ptr< ESYMBOL > &aEsymbol, std::unique_ptr< LIB_SYMBOL > &aSymbol, const std::unique_ptr< EDEVICE > &aDevice, int aGateNumber, const wxString &aGateName)
SCH_SHEET * getCurrentSheet()
void loadDrawing(const std::unique_ptr< EDRAWING > &aDrawing)
void EnumerateSymbolLib(wxArrayString &aSymbolNameList, const wxString &aLibraryPath, const std::map< std::string, UTF8 > *aProperties) override
Populate a list of LIB_SYMBOL alias names contained within the library aLibraryPath.
SCH_SHAPE * loadSymbolPolyLine(std::unique_ptr< LIB_SYMBOL > &aSymbol, const std::unique_ptr< EPOLYGON > &aPolygon, int aGateNumber)
std::vector< VECTOR2I > m_wireIntersections
Wires and labels of a single connection (segment in Eagle nomenclature)
std::map< VECTOR2I, std::set< const EDA_ITEM * > > m_connPoints
The fully parsed Eagle schematic file.
void loadSegments(const std::vector< std::unique_ptr< ESEGMENT > > &aSegments, const wxString &aNetName, const wxString &aNetClass)
bool checkConnections(const SCH_SYMBOL *aSymbol, const SCH_PIN *aPin) const
std::unique_ptr< std::map< std::string, UTF8 > > m_properties
Library plugin properties.
IO_RELEASER< SCH_IO > m_pi
PI to create KiCad symbol library.
SCH_SHAPE * loadRectangle(const std::unique_ptr< ERECT > &aRect)
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 * loadModuleInstance(const std::unique_ptr< EMODULEINST > &aModuleInstance)
bool CanReadSchematicFile(const wxString &aFileName) const override
Checks if this SCH_IO can read the specified schematic file.
void addImplicitConnections(SCH_SYMBOL *aSymbol, SCH_SCREEN *aScreen, bool aUpdateSet)
Create net labels to emulate implicit connections in Eagle.
std::map< int, SCH_LAYER_ID > m_layerMap
SCH_LAYER_ID kiCadLayer(int aEagleLayer)
Return the matching layer or return LAYER_NOTES.
SCH_SHEET * LoadSchematicFile(const wxString &aFileName, SCHEMATIC *aSchematic, SCH_SHEET *aAppendToMe=nullptr, const std::map< std::string, UTF8 > *aProperties=nullptr) override
Load information from some input file format that this SCH_IO implementation knows about,...
SCH_PIN * loadPin(std::unique_ptr< LIB_SYMBOL > &aSymbol, const std::unique_ptr< EPIN > &aPin, int aGateNumber)
SCH_SHAPE * loadCircle(const std::unique_ptr< ECIRCLE > &aCircle)
wxFileName getLibFileName()
Checks if there are other wires or pins at the position of the tested pin.
SCH_SHAPE * loadSymbolRectangle(std::unique_ptr< LIB_SYMBOL > &aSymbol, const std::unique_ptr< ERECT > &aRectangle, int aGateNumber)
SCH_JUNCTION * loadJunction(const std::unique_ptr< EJUNCTION > &aJunction)
wxString m_version
Eagle file version.
void getEagleSymbolFieldAttributes(const std::unique_ptr< EINSTANCE > &aInstance, const wxString &aEagleFieldName, SCH_FIELD *aField)
std::map< wxString, const EPART * > m_partlist
void moveLabels(SCH_LINE *aWire, const VECTOR2I &aNewEndPoint)
Move any labels on the wire to the new end point of the wire.
bool checkHeader(const wxString &aFileName) const
SCHEMATIC * m_schematic
Passed to Load(), the schematic object being loaded.
void countNets(const ESCHEMATIC &aSchematic)
SCH_SHEET * m_rootSheet
The root sheet of the schematic being loaded.
SCH_SHAPE * loadPolyLine(const std::unique_ptr< EPOLYGON > &aPolygon)
SCH_SHAPE * loadSymbolCircle(std::unique_ptr< LIB_SYMBOL > &aSymbol, const std::unique_ptr< ECIRCLE > &aCircle, int aGateNumber)
SCH_SCREEN * getCurrentScreen()
bool CanReadLibrary(const wxString &aFileName) const override
Checks if this IO object can read the specified library file/directory.
std::map< wxString, EAGLE_MISSING_CMP > m_missingCmps
void loadFrame(const std::unique_ptr< EFRAME > &aFrame, std::vector< SCH_ITEM * > &aItems)
std::vector< SEG_DESC > m_segments
Nets as defined in the <nets> sections of an Eagle schematic file.
SCH_ITEM * loadSymbolWire(std::unique_ptr< LIB_SYMBOL > &aSymbol, const std::unique_ptr< EWIRE > &aWire, int aGateNumber)
long long getLibraryTimestamp(const wxString &aLibraryPath) const
static const char * PropBuffering
The property used internally by the plugin to enable cache buffering which prevents the library file ...
Base class that schematic file and library loading and saving plugins should derive from.
virtual bool CanReadSchematicFile(const wxString &aFileName) const
Checks if this SCH_IO can read the specified schematic file.
Base class for any item which can be embedded within the SCHEMATIC container class,...
virtual void SetUnit(int aUnit)
SCH_ITEM * Duplicate(bool doClone=false) const
Routine to create a new copy of given item.
void SetShape(LABEL_FLAG_SHAPE aShape)
void SetPosition(const VECTOR2I &aPosition) override
Segment description base class to describe items which have 2 end points (track, wire,...
bool IsWire() const
Return true if the line is a wire.
const BOX2I GetBoundingBox() const override
Return the orthogonal bounding box of this object for display purposes.
VECTOR2I GetEndPoint() const
VECTOR2I GetStartPoint() const
bool IsBus() const
Return true if the line is a bus.
void SetEndPoint(const VECTOR2I &aPosition)
void SetNumber(const wxString &aNumber)
Container class that holds multiple SCH_SCREEN objects in a hierarchy.
void UpdateSymbolLinks(REPORTER *aReporter=nullptr)
Initialize the LIB_SYMBOL reference for each SCH_SYMBOL found in the full schematic.
const PAGE_INFO & GetPageSettings() const
void Append(SCH_ITEM *aItem, bool aUpdateLibSymbol=true)
void SetPageSettings(const PAGE_INFO &aPageSettings)
EE_RTREE & Items()
Gets the full RTree, usually for iterating.
const KIID & GetUuid() const
void SetFileName(const wxString &aFileName)
Set the file name for this screen to aFileName.
void Update(SCH_ITEM *aItem, bool aUpdateLibSymbol=true)
Update aItem's bounding box in the tree.
void SetPosition(const VECTOR2I &aPos) override
void SetStroke(const STROKE_PARAMS &aStroke) override
VECTOR2I GetCenter() const
void AddPoint(const VECTOR2I &aPosition)
VECTOR2I GetPosition() const override
Handle access to a stack of flattened SCH_SHEET objects by way of a path for creating a flattened sch...
KIID_PATH Path() const
Get the sheet path as an KIID_PATH.
void SetPageNumber(const wxString &aPageNumber)
Set the sheet instance user definable page number.
SCH_SHEET * Last() const
Return a pointer to the last SCH_SHEET of the list.
void push_back(SCH_SHEET *aSheet)
Forwarded method from std::vector.
void pop_back()
Forwarded method from std::vector.
Define a sheet pin (label) used in sheets to create hierarchical schematics.
void SetPosition(const VECTOR2I &aPosition) override
void SetSide(SHEET_SIDE aEdge)
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.
bool LocatePathOfScreen(SCH_SCREEN *aScreen, SCH_SHEET_PATH *aList)
Search the existing hierarchy for an instance of screen loaded from aFileName.
void SetName(const wxString &aName)
SCH_SCREEN * GetScreen() const
void SetScreen(SCH_SCREEN *aScreen)
Set the SCH_SCREEN associated with this sheet to aScreen.
void AutoplaceFields(SCH_SCREEN *aScreen, AUTOPLACE_ALGO aAlgo) override
SCH_FIELD * GetField(MANDATORY_FIELD_T aFieldType)
Return a mandatory field in this symbol.
std::unique_ptr< LIB_SYMBOL > & GetLibSymbolRef()
VECTOR2I GetPinPhysicalPosition(const SCH_PIN *Pin) const
VECTOR2I GetPosition() const override
void SetPosition(const VECTOR2I &aPosition) override
OPT_VECTOR2I Intersect(const SEG &aSeg, bool aIgnoreEndpoints=false, bool aLines=false) const
Compute intersection point of segment (this) with segment aSeg.
bool Contains(const SEG &aSeg) const
SHAPE_ARC & ConstructFromStartEndAngle(const VECTOR2I &aStart, const VECTOR2I &aEnd, const EDA_ANGLE &aAngle, double aWidth=0)
Construct this arc from the given start, end and angle.
int Append(int x, int y, int aOutline=-1, int aHole=-1, bool aAllowDuplication=false)
Appends a vertex at the end of the given outline/hole (default: the last outline)
Simple container to manage line stroke parameters.
Hold a record identifying a symbol library accessed by the appropriate symbol library SCH_IO object i...
static const wxString GetSymbolLibTableFileName()
virtual void Format(OUTPUTFORMATTER *aOutput, int aIndentLevel) const override
Generate the table in s-expression format to aOutput with an indentation level of aIndentLevel.
LIB_SYMBOL * LoadSymbol(const wxString &aNickname, const wxString &aName)
Load a LIB_SYMBOL having aName from the library given by aNickname.
VECTOR2< T > Resize(T aNewLength) const
Return a vector of the same direction, but length specified in aNewLength.
static REPORTER & GetInstance()
static void SetReporter(REPORTER *aReporter)
Set the reporter to use for reporting font substitution warnings.
#define DEFAULT_SCH_ENTRY_SIZE
The default text size in mils. (can be changed in preference menu)
wxString escapeName(const wxString &aNetName)
Translates Eagle special characters to their counterparts in KiCad.
wxString interpretText(const wxString &aText)
Interprets special characters in Eagle text and converts them to KiCAD notation.
size_t GetNodeCount(const wxXmlNode *aNode)
Fetch the number of XML nodes within aNode.
VECTOR2I ConvertArcCenter(const VECTOR2I &aStart, const VECTOR2I &aEnd, double aAngle)
Convert an Eagle curve end to a KiCad center for S_ARC.
wxString convertDescription(wxString aDescr)
Converts Eagle's HTML description into KiCad description format.
static constexpr EDA_ANGLE ANGLE_VERTICAL
#define IS_NEW
New item, just created.
@ ERCE_BUS_ENTRY_NEEDED
Importer failed to auto-place a bus entry.
static const std::string KiCadSchematicFileExtension
static const std::string KiCadSymbolLibFileExtension
#define THROW_IO_ERROR(msg)
SCH_LAYER_ID
Eeschema drawing layers.
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
@ PT_INPUT
usual pin input: must be connected
@ PT_NC
not connected (must be left open)
@ PT_TRISTATE
tris state bus pin
@ PT_BIDI
input or output (like port for a microprocessor)
@ PT_OPENCOLLECTOR
pin type open collector
@ PT_POWER_IN
power input (GND, VCC for ICs). Must be connected to a power output.
@ PT_PASSIVE
pin for passive symbols: must be connected, and can be connected to any pin
static wxString extractNetName(const wxString &aPinName)
static const std::map< wxString, ELECTRICAL_PINTYPE > pinDirectionsMap
Map of EAGLE pin type values to KiCad pin type values.
static SYMBOL_ORIENTATION_T kiCadComponentRotation(float eagleDegrees)
static void eagleToKicadAlignment(EDA_TEXT *aText, int aEagleAlignment, int aRelDegress, bool aMirror, bool aSpin, int aAbsDegress)
static BOX2I getSheetBbox(SCH_SHEET *aSheet)
Extract the net name part from a pin name (e.g. return 'GND' for pin named 'GND@2')
Definition of the SCH_SHEET_PATH and SCH_SHEET_LIST classes for Eeschema.
SHEET_SIDE
Define the edge of the sheet that the sheet pin is positioned.
std::optional< VECTOR2I > OPT_VECTOR2I
wxString UnescapeString(const wxString &aSource)
bool ReplaceIllegalFileNameChars(std::string *aName, int aReplaceChar)
Checks aName for illegal file name characters.
wxString EscapeString(const wxString &aSource, ESCAPE_CONTEXT aContext)
The Escape/Unescape routines use HTML-entity-reference-style encoding to handle characters which are:...
wxString UnescapeHTML(const wxString &aString)
Return a new wxString unescaped from HTML format.
std::map< wxString, std::unique_ptr< LIB_SYMBOL > > KiCadSymbols
std::unordered_map< wxString, wxString > package
std::unordered_map< wxString, int > GateToUnitMap
Map Eagle gate unit number (which are strings) to KiCad library symbol unit number.
constexpr int IUToMils(int iu) const
constexpr int MilsToIU(int mils) const
constexpr int mmToIU(double mm) const
std::map< wxString, std::unique_ptr< EDEVICE_SET > > devicesets
wxString GetName() const
Fetch the fully unique library name.
std::map< wxString, std::unique_ptr< ESYMBOL > > symbols
std::map< wxString, std::unique_ptr< EPART > > parts
std::map< wxString, std::unique_ptr< EPORT > > ports
std::map< wxString, std::unique_ptr< EMODULE > > modules
std::vector< std::unique_ptr< ESHEET > > sheets
std::map< wxString, std::unique_ptr< EPART > > parts
std::map< wxString, std::unique_ptr< ELIBRARY > > libraries
std::vector< std::unique_ptr< ETEXT > > texts
Map references to missing symbol units data.
std::map< int, bool > units
Segments representing wires for intersection checking.
std::vector< SCH_TEXT * > labels
const SEG * LabelAttached(const SCH_TEXT *aLabel) const
< Test if a particular label is attached to any of the stored segments
SYMBOL_ORIENTATION_T
enum used in RotationMiroir()
@ FOOTPRINT_FIELD
Field Name Module PCB, i.e. "16DIP300".
@ VALUE_FIELD
Field Value of part, i.e. "3.3K".
@ REFERENCE_FIELD
Field Reference of part, i.e. "IC21".
bool TestSegmentHit(const VECTOR2I &aRefPoint, const VECTOR2I &aStart, const VECTOR2I &aEnd, int aDist)
Test if aRefPoint is with aDistance on the line defined by aStart and aEnd.
void RotatePoint(int *pX, int *pY, const EDA_ANGLE &aAngle)
Calculate the new point of coord coord pX, pY, for a rotation center 0, 0.
VECTOR2< int32_t > VECTOR2I
Definition of file extensions used in Kicad.