64#include <wx/filename.h>
65#include <wx/txtstrm.h>
66#include <wx/wfstream.h>
67#include <boost/ptr_container/ptr_map.hpp>
71static inline long parseInt(
const wxString& aValue,
double aScalar )
73 double value = std::numeric_limits<double>::max();
96 if( aValue.EndsWith( wxT(
"mm" ) ) )
98 aScalar *= 100000.0 / 25.4;
100 else if( aValue.EndsWith( wxT(
"mil" ) ) )
107 aValue.ToCDouble(&value);
109 if( value == std::numeric_limits<double>::max() )
111 THROW_IO_ERROR( wxString::Format(
_(
"Cannot convert '%s' to an integer." ),
112 aValue.GetData() ) );
115 return KiROUND( value * aScalar );
119#define TEXT_DEFAULT_SIZE ( 40 * pcbIUScale.IU_PER_MILS )
120#define OLD_GPCB_UNIT_CONV pcbIUScale.IU_PER_MILS
121#define NEW_GPCB_UNIT_CONV ( 0.01 * pcbIUScale.IU_PER_MILS )
166 void Remove(
const wxString& aFootprintName );
174 static long long GetTimestamp(
const wxString& aLibPath );
194 bool testFlags(
const wxString& aFlag,
long aMask,
const wxChar* aName );
245 if( !dir.IsOpened() )
247 THROW_IO_ERROR( wxString::Format(
_(
"Footprint library '%s' not found." ),
258 if( !dir.GetFirst( &fullName, fileSpec ) )
261 wxString cacheErrorMsg;
281 if( !cacheErrorMsg.IsEmpty() )
282 cacheErrorMsg += wxT(
"\n\n" );
284 cacheErrorMsg += ioe.
What();
286 }
while( dir.GetNext( &fullName ) );
288 if( !cacheErrorMsg.IsEmpty() )
295 std::string footprintName =
TO_UTF8( aFootprintName );
301 THROW_IO_ERROR( wxString::Format(
_(
"Library '%s' has no footprint '%s'." ),
303 aFootprintName.GetData() ) );
307 wxString fullPath = it->second->GetFileName().GetFullPath();
309 wxRemoveFile( fullPath );
336 wxArrayString parameters;
337 std::unique_ptr<FOOTPRINT> footprint = std::make_unique<FOOTPRINT>(
nullptr );
339 if( aLineReader->
ReadLine() ==
nullptr )
341 msg = aLineReader->
GetSource() + wxT(
": empty file" );
347 paramCnt = parameters.GetCount();
357 if( parameters[0].CmpNoCase( wxT(
"Element" ) ) != 0 )
359 msg.Printf(
_(
"Unknown token '%s'" ), parameters[0] );
364 if( paramCnt < 10 || paramCnt > 14 )
366 msg.Printf(
_(
"Element token contains %d parameters." ), paramCnt );
372 if( parameters[1] == wxT(
"(" ) )
377 footprint->SetLibDescription( parameters[3] );
378 footprint->SetReference( parameters[4] );
382 footprint->SetLibDescription( parameters[2] );
383 footprint->SetReference( parameters[3] );
388 footprint->SetValue( parameters[5] );
392 if( footprint->Value().GetText().IsEmpty() )
393 footprint->Value().SetText( wxT(
"VAL**" ) );
395 if( footprint->Reference().GetText().IsEmpty() )
396 footprint->Reference().SetText( wxT(
"REF**" ) );
403 if( parameters.IsEmpty() || parameters[0] == wxT(
"(" ) )
406 if( parameters[0] == wxT(
")" ) )
409 paramCnt = parameters.GetCount();
414 if( parameters[1] == wxT(
"(" ) )
421 parameters[0], paramCnt );
424 if( parameters[0].CmpNoCase( wxT(
"ElementLine" ) ) == 0 )
428 msg.Printf( wxT(
"ElementLine token contains %d parameters." ), paramCnt );
436 static_cast<int>(
parseInt( parameters[3], conv_unit ) ) ) );
438 static_cast<int>(
parseInt( parameters[5], conv_unit ) ) ) );
442 shape->
Rotate( { 0, 0 }, footprint->GetOrientation() );
443 shape->
Move( footprint->GetPosition() );
445 footprint->Add( shape );
450 if( parameters[0].CmpNoCase( wxT(
"ElementArc" ) ) == 0 )
454 msg.Printf( wxT(
"ElementArc token contains %d parameters." ), paramCnt );
462 footprint->Add( shape );
465 int radius =
static_cast<int>( (
parseInt( parameters[4], conv_unit ) +
466 parseInt( parameters[5], conv_unit ) ) / 2 );
469 static_cast<int>(
parseInt( parameters[3], conv_unit ) ) );
493 shape->
SetStart( arcStart + centre );
502 shape->
Rotate( { 0, 0 }, footprint->GetOrientation() );
503 shape->
Move( footprint->GetPosition() );
512 if( parameters[0].CmpNoCase( wxT(
"Pad" ) ) == 0 )
514 if( paramCnt < 10 || paramCnt > 13 )
516 msg.Printf( wxT(
"Pad token contains %d parameters." ), paramCnt );
521 std::unique_ptr<PAD>
pad = std::make_unique<PAD>( footprint.get() );
528 pad->SetLayerSet( pad_front );
530 if(
testFlags( parameters[paramCnt-2], 0x0080, wxT(
"onsolder" ) ) )
531 pad->SetLayerSet( pad_back );
541 pad->SetNumber( parameters[paramCnt-3] );
543 int x1 =
static_cast<int>(
parseInt( parameters[2], conv_unit ) );
544 int x2 =
static_cast<int>(
parseInt( parameters[4], conv_unit ) );
545 int y1 =
static_cast<int>(
parseInt( parameters[3], conv_unit ) );
546 int y2 =
static_cast<int>(
parseInt( parameters[5], conv_unit ) );
547 int width =
static_cast<int>(
parseInt( parameters[6], conv_unit ) );
549 double angle = atan2( (
double)
delta.y, (
double)
delta.x );
563 int maskMargin =
static_cast<int>(
parseInt( parameters[8], conv_unit ) );
564 maskMargin = ( maskMargin - width ) / 2;
565 pad->SetLocalSolderMaskMargin( maskMargin );
570 pad->SetOrientation( orient );
572 VECTOR2I padPos( ( x1 + x2 ) / 2, ( y1 + y2 ) / 2 );
576 padPos += footprint->GetPosition();
577 pad->SetPosition( padPos );
579 if( !
testFlags( parameters[paramCnt-2], 0x0100, wxT(
"square" ) ) )
587 if(
pad->GetSizeX() > 0 &&
pad->GetSizeY() > 0 )
589 footprint->Add(
pad.release() );
593 wxLogError(
_(
"Invalid zero-sized pad ignored in\nfile: %s" ),
606 if( parameters[0].CmpNoCase( wxT(
"Pin" ) ) == 0 )
608 if( paramCnt < 8 || paramCnt > 12 )
610 msg.Printf( wxT(
"Pin token contains %d parameters." ), paramCnt );
621 pad->SetLayerSet( pad_set );
623 if(
testFlags( parameters[paramCnt-2], 0x0100, wxT(
"square" ) ) )
630 pad->SetNumber( parameters[paramCnt-3] );
633 static_cast<int>(
parseInt( parameters[3], conv_unit ) ) );
635 int padSize =
static_cast<int>(
parseInt( parameters[4], conv_unit ) );
653 int maskMargin =
static_cast<int>(
parseInt( parameters[6], conv_unit ) );
654 maskMargin = ( maskMargin - padSize ) / 2;
655 pad->SetLocalSolderMaskMargin( maskMargin );
657 drillSize =
static_cast<int>(
parseInt( parameters[7], conv_unit ) );
661 drillSize =
static_cast<int>(
parseInt( parameters[5], conv_unit ) );
664 pad->SetDrillSize(
VECTOR2I( drillSize, drillSize ) );
666 padPos += footprint->GetPosition();
667 pad->SetPosition( padPos );
675 footprint->Add(
pad );
680 footprint->AutoPositionFields();
682 return footprint.release();
690 char* line = aLineReader->
Line();
704 aParameterList.Add( tmp );
709 aParameterList.Add( tmp );
714 if( aParameterList.GetCount() == 1 )
726 aParameterList.Add( tmp );
731 aParameterList.Add( tmp );
745 aParameterList.Add( tmp );
757 aParameterList.Add( wxEmptyString );
768 aParameterList.Add( tmp );
800 if( aFlag.StartsWith( wxT(
"0x" ), &number ) || aFlag.StartsWith( wxT(
"0X" ), &number ) )
804 if( number.ToLong( &lflags, 16 ) && ( lflags & aMask ) )
807 else if( aFlag.Contains( aName ) )
828 m_ctl( aControlFlags ),
864 wxString& aFootprintNameOut,
865 const std::map<std::string, UTF8>* aProperties )
867 wxFileName fn( aFootprintPath );
873 char* line = reader.
Line();
878 if( strncasecmp( line,
"Element", strlen(
"Element" ) ) != 0 )
881 aFootprintNameOut = fn.GetName();
888 bool aBestEfforts,
const std::map<std::string, UTF8>* aProperties )
890 wxDir dir( aLibraryPath );
893 if( !dir.IsOpened() )
898 THROW_IO_ERROR( wxString::Format(
_(
"Footprint library '%s' not found." ), aLibraryPath ) );
909 errorMsg = ioe.
What();
915 for(
const auto& footprint :
m_cache->GetFootprints() )
916 aFootprintNames.Add(
From_UTF8( footprint.first.c_str() ) );
918 if( !errorMsg.IsEmpty() && !aBestEfforts )
924 const wxString& aFootprintName,
925 const std::map<std::string, UTF8>* aProperties,
932 auto it =
m_cache->GetFootprints().find(
TO_UTF8( aFootprintName ) );
934 if( it ==
m_cache->GetFootprints().end() )
937 return it->second->GetFootprint().get();
942 const wxString& aFootprintName,
944 const std::map<std::string, UTF8>* aProperties )
954 copy->SetParent(
nullptr );
963 const std::map<std::string, UTF8>* aProperties )
972 aLibraryPath.GetData() ) );
975 m_cache->Remove( aFootprintName );
982 fn.SetPath( aLibraryPath );
985 if( !fn.DirExists() )
988 if( !fn.IsDirWritable() )
990 THROW_IO_ERROR( wxString::Format(
_(
"Insufficient permissions to delete folder '%s'." ),
991 aLibraryPath.GetData() ) );
994 wxDir dir( aLibraryPath );
996 if( dir.HasSubDirs() )
998 THROW_IO_ERROR( wxString::Format(
_(
"Library folder '%s' has unexpected sub-folders." ),
999 aLibraryPath.GetData() ) );
1003 if( dir.HasFiles() )
1007 wxArrayString files;
1011 for( i = 0; i < files.GetCount(); i++ )
1017 THROW_IO_ERROR( wxString::Format(
_(
"Unexpected file '%s' found in library '%s'." ),
1019 aLibraryPath.GetData() ) );
1023 for( i = 0; i < files.GetCount(); i++ )
1025 wxRemoveFile( files[i] );
1030 aLibraryPath.GetData() );
1034 if( !wxRmdir( aLibraryPath ) )
1036 THROW_IO_ERROR( wxString::Format(
_(
"Footprint library '%s' cannot be deleted." ),
1037 aLibraryPath.GetData() ) );
1044 wxMilliSleep( 250L );
1082 char* line = aLineReader->
Line();
1093 if( !tmp.IsEmpty() )
1095 aParameterList.Add( tmp );
1100 aParameterList.Add( tmp );
1103 if( aParameterList.GetCount() == 1 )
1113 if( !tmp.IsEmpty() )
1115 aParameterList.Add( tmp );
1120 aParameterList.Add( tmp );
1135 if( !tmp.IsEmpty() )
1137 aParameterList.Add( tmp );
1148 aParameterList.Add( wxEmptyString );
1159 aParameterList.Add( tmp );
1191 if( aFlag.StartsWith( wxT(
"0x" ), &number ) || aFlag.StartsWith( wxT(
"0X" ), &number ) )
1195 if( number.ToLong( &lflags, 16 ) && ( lflags & aMask ) )
1198 else if( aFlag.Contains( aName ) )
1212 wxFileInputStream input( aFileName );
1217 wxTextInputStream
text( input );
1219 for(
int i = 0; i < 20; i++ )
1224 wxString line =
text.ReadLine();
1226 if( line.Contains( wxS(
"PCB[" ) ) || line.Contains( wxS(
"PCB(" ) ) )
1236 wxString
name = aLayerName.Lower();
1238 if(
name.Contains( wxT(
"outline" ) ) ||
name.Contains( wxT(
"route" ) ) )
1241 if(
name.Contains( wxT(
"silk" ) ) )
1243 if(
name.Contains( wxT(
"solder" ) ) ||
name.Contains( wxT(
"bottom" ) ) )
1249 if(
name.Contains( wxT(
"mask" ) ) )
1251 if(
name.Contains( wxT(
"solder" ) ) ||
name.Contains( wxT(
"bottom" ) ) )
1257 if(
name.Contains( wxT(
"paste" ) ) )
1259 if(
name.Contains( wxT(
"solder" ) ) ||
name.Contains( wxT(
"bottom" ) ) )
1265 if(
name.Contains( wxT(
"fab" ) ) )
1269 if(
name.Contains( wxT(
"component" ) ) ||
name.Contains( wxT(
"top" ) )
1270 || ( aGedaLayer == 1 && !
name.Contains( wxT(
"solder" ) ) ) )
1275 if(
name.Contains( wxT(
"solder" ) ) ||
name.Contains( wxT(
"bottom" ) )
1276 || aGedaLayer == 2 )
1282 if( aGedaLayer >= 3 && aGedaLayer <= 16 )
1284 int innerIdx = aGedaLayer - 3;
1290 return innerLayers[innerIdx];
1300 int paramCnt = aParameters.GetCount();
1305 _(
"Via token contains %d parameters, expected at least 10." ), paramCnt ) );
1310 int x =
static_cast<int>(
parseInt( aParameters[2], aConvUnit ) );
1311 int y =
static_cast<int>(
parseInt( aParameters[3], aConvUnit ) );
1312 int thickness =
static_cast<int>(
parseInt( aParameters[4], aConvUnit ) );
1313 int drill =
static_cast<int>(
parseInt( aParameters[7], aConvUnit ) );
1317 via->SetDrill( drill );
1329 int paramCnt = aParameters.GetCount();
1330 double conv_unit = aConvUnit;
1333 std::unique_ptr<FOOTPRINT> footprint = std::make_unique<FOOTPRINT>(
m_board );
1335 if( paramCnt < 10 || paramCnt > 14 )
1337 msg.Printf(
_(
"Element token contains %d parameters." ), paramCnt );
1344 int descIdx, nameIdx, valueIdx, mxIdx;
1361 footprint->SetLibDescription( aParameters[descIdx] );
1362 footprint->SetReference( aParameters[nameIdx] );
1365 footprint->SetValue( aParameters[valueIdx] );
1367 if( footprint->Value().GetText().IsEmpty() )
1368 footprint->Value().SetText( wxT(
"VAL**" ) );
1370 if( footprint->Reference().GetText().IsEmpty() )
1371 footprint->Reference().SetText( wxT(
"REF**" ) );
1374 if( mxIdx > 0 && paramCnt > 12 )
1376 int mx =
static_cast<int>(
parseInt( aParameters[mxIdx], conv_unit ) );
1377 int my =
static_cast<int>(
parseInt( aParameters[mxIdx + 1], conv_unit ) );
1378 footprint->SetPosition(
VECTOR2I( mx, my ) );
1381 wxArrayString parameters;
1388 if( parameters.IsEmpty() || parameters[0] == wxT(
"(" ) )
1391 if( parameters[0] == wxT(
")" ) )
1394 paramCnt = parameters.GetCount();
1398 if( parameters[1] == wxT(
"(" ) )
1405 if( parameters[0].CmpNoCase( wxT(
"ElementLine" ) ) == 0 )
1413 static_cast<int>(
parseInt( parameters[3], conv_unit ) ) ) );
1415 static_cast<int>(
parseInt( parameters[5], conv_unit ) ) ) );
1419 shape->
Rotate( { 0, 0 }, footprint->GetOrientation() );
1420 shape->
Move( footprint->GetPosition() );
1422 footprint->Add( shape );
1427 if( parameters[0].CmpNoCase( wxT(
"ElementArc" ) ) == 0 )
1429 if( paramCnt != 10 )
1434 footprint->Add( shape );
1436 int radius =
static_cast<int>( (
parseInt( parameters[4], conv_unit )
1437 +
parseInt( parameters[5], conv_unit ) ) / 2 );
1440 static_cast<int>(
parseInt( parameters[3], conv_unit ) ) );
1460 shape->
SetStart( arcStart + centre );
1467 shape->
Rotate( { 0, 0 }, footprint->GetOrientation() );
1468 shape->
Move( footprint->GetPosition() );
1473 if( parameters[0].CmpNoCase( wxT(
"Pad" ) ) == 0 )
1475 if( paramCnt < 10 || paramCnt > 13 )
1478 std::unique_ptr<PAD>
pad = std::make_unique<PAD>( footprint.get() );
1485 pad->SetLayerSet( pad_front );
1487 if(
testFlags( parameters[paramCnt - 2], 0x0080, wxT(
"onsolder" ) ) )
1488 pad->SetLayerSet( pad_back );
1490 pad->SetNumber( parameters[paramCnt - 3] );
1492 int x1 =
static_cast<int>(
parseInt( parameters[2], conv_unit ) );
1493 int x2 =
static_cast<int>(
parseInt( parameters[4], conv_unit ) );
1494 int y1 =
static_cast<int>(
parseInt( parameters[3], conv_unit ) );
1495 int y2 =
static_cast<int>(
parseInt( parameters[5], conv_unit ) );
1496 int width =
static_cast<int>(
parseInt( parameters[6], conv_unit ) );
1498 double angle = atan2( (
double)
delta.y, (
double)
delta.x );
1500 if( paramCnt == 13 )
1505 int maskMargin =
static_cast<int>(
parseInt( parameters[8], conv_unit ) );
1506 maskMargin = ( maskMargin - width ) / 2;
1507 pad->SetLocalSolderMaskMargin( maskMargin );
1511 pad->SetOrientation( orient );
1513 VECTOR2I padPos( ( x1 + x2 ) / 2, ( y1 + y2 ) / 2 );
1518 padPos += footprint->GetPosition();
1519 pad->SetPosition( padPos );
1521 if( !
testFlags( parameters[paramCnt - 2], 0x0100, wxT(
"square" ) ) )
1534 if(
pad->GetSizeX() > 0 &&
pad->GetSizeY() > 0 )
1535 footprint->Add(
pad.release() );
1541 if( parameters[0].CmpNoCase( wxT(
"Pin" ) ) == 0 )
1543 if( paramCnt < 8 || paramCnt > 12 )
1553 pad->SetLayerSet( pad_set );
1555 if(
testFlags( parameters[paramCnt - 2], 0x0100, wxT(
"square" ) ) )
1558 pad->SetNumber( parameters[paramCnt - 3] );
1561 static_cast<int>(
parseInt( parameters[3], conv_unit ) ) );
1563 int padSize =
static_cast<int>(
parseInt( parameters[4], conv_unit ) );
1568 if( paramCnt == 12 )
1573 int maskMargin =
static_cast<int>(
parseInt( parameters[6], conv_unit ) );
1574 maskMargin = ( maskMargin - padSize ) / 2;
1575 pad->SetLocalSolderMaskMargin( maskMargin );
1577 drillSize =
static_cast<int>(
parseInt( parameters[7], conv_unit ) );
1581 drillSize =
static_cast<int>(
parseInt( parameters[5], conv_unit ) );
1584 pad->SetDrillSize(
VECTOR2I( drillSize, drillSize ) );
1586 padPos += footprint->GetPosition();
1587 pad->SetPosition( padPos );
1596 footprint->Add(
pad );
1603 wxString elementFlags = aParameters[2];
1605 if( elementFlags.Contains( wxT(
"onsolder" ) ) )
1608 footprint->AutoPositionFields();
1610 return footprint.release();
1619 int paramCnt = aParameters.GetCount();
1625 aParameters[2].ToLong( &layerNum );
1630 layerName = aParameters[3];
1639 int layerCount =
static_cast<int>( layerNum );
1645 wxArrayString parameters;
1646 double conv_unit = aConvUnit;
1653 if( parameters.IsEmpty() || parameters[0] == wxT(
"(" ) )
1656 if( parameters[0] == wxT(
")" ) )
1659 paramCnt = parameters.GetCount();
1663 if( parameters[1] == wxT(
"(" ) )
1670 if( parameters[0].CmpNoCase( wxT(
"Line" ) ) == 0 )
1675 int x1 =
static_cast<int>(
parseInt( parameters[2], conv_unit ) );
1676 int y1 =
static_cast<int>(
parseInt( parameters[3], conv_unit ) );
1677 int x2 =
static_cast<int>(
parseInt( parameters[4], conv_unit ) );
1678 int y2 =
static_cast<int>(
parseInt( parameters[5], conv_unit ) );
1679 int thickness =
static_cast<int>(
parseInt( parameters[6], conv_unit ) );
1705 if( parameters[0].CmpNoCase( wxT(
"Arc" ) ) == 0 )
1710 int cx =
static_cast<int>(
parseInt( parameters[2], conv_unit ) );
1711 int cy =
static_cast<int>(
parseInt( parameters[3], conv_unit ) );
1712 int arcWidth =
static_cast<int>(
parseInt( parameters[4], conv_unit ) );
1713 int arcHeight =
static_cast<int>(
parseInt( parameters[5], conv_unit ) );
1714 int thickness =
static_cast<int>(
parseInt( parameters[6], conv_unit ) );
1715 int radius = ( arcWidth + arcHeight ) / 2;
1735 arc->
SetStart( arcStart + centre );
1738 RotatePoint( arcMid, -start_angle - sweep_angle / 2 );
1739 arc->
SetMid( arcMid + centre );
1742 RotatePoint( arcEnd, -start_angle - sweep_angle );
1743 arc->
SetEnd( arcEnd + centre );
1763 shape->
SetStart( arcStart + centre );
1775 if( parameters[0].CmpNoCase( wxT(
"Polygon" ) ) == 0 )
1783 const int outlineIdx = -1;
1784 bool parsingPoints =
false;
1788 wxArrayString polyParams;
1791 if( polyParams.IsEmpty() )
1794 if( polyParams[0] == wxT(
")" ) )
1797 if( polyParams[0] == wxT(
"(" ) )
1799 parsingPoints =
true;
1803 if( !parsingPoints )
1807 for(
size_t i = 0; i < polyParams.GetCount(); i++ )
1809 if( polyParams[i] == wxT(
"[" ) && i + 2 < polyParams.GetCount() )
1811 int px =
static_cast<int>(
parseInt( polyParams[i + 1], conv_unit ) );
1812 int py =
static_cast<int>(
parseInt( polyParams[i + 2], conv_unit ) );
1833 if( parameters[0].CmpNoCase( wxT(
"Text" ) ) == 0 )
1839 text->SetLayer( kicadLayer );
1841 int tx =
static_cast<int>(
parseInt( parameters[2], conv_unit ) );
1842 int ty =
static_cast<int>(
parseInt( parameters[3], conv_unit ) );
1846 parameters[4].ToLong( &direction );
1849 text->SetTextAngle( textAngle );
1852 parameters[5].ToLong( &
scale );
1857 text->SetText( parameters[6] );
1874 std::map<wxString, FOOTPRINT*> fpByRef;
1877 fpByRef[fp->GetReference()] = fp;
1879 wxArrayString parameters;
1886 if( parameters.IsEmpty() )
1889 if( parameters[0] == wxT(
")" ) )
1892 if( parameters[0] == wxT(
"(" ) )
1896 if( parameters[0].CmpNoCase( wxT(
"Net" ) ) == 0 )
1900 if( parameters.GetCount() > 3 )
1901 netName = parameters[2];
1905 auto it =
m_netMap.find( netName );
1909 netInfo = it->second;
1921 wxArrayString netParams;
1924 if( netParams.IsEmpty() )
1927 if( netParams[0] == wxT(
")" ) )
1930 if( netParams[0] == wxT(
"(" ) )
1934 if( netParams[0].CmpNoCase( wxT(
"Connect" ) ) == 0 && netParams.GetCount() > 3 )
1936 wxString connectStr = netParams[2];
1939 int lastDash = connectStr.Find(
'-',
true );
1941 if( lastDash == wxNOT_FOUND )
1944 wxString refdes = connectStr.Left( lastDash );
1945 wxString pinNumber = connectStr.Mid( lastDash + 1 );
1947 auto fpIt = fpByRef.find( refdes );
1949 if( fpIt == fpByRef.end() )
1952 for(
PAD*
pad : fpIt->second->Pads() )
1954 if(
pad->GetNumber() == pinNumber )
1956 pad->SetNet( netInfo );
1968 const std::map<std::string, UTF8>* aProperties,
1973 init( aProperties );
1978 m_board->SetFileName( aFileName );
1980 std::unique_ptr<BOARD> deleter( aAppendToMe ?
nullptr :
m_board );
1995 wxArrayString parameters;
1998 if( parameters.IsEmpty() )
2001 int paramCnt = parameters.GetCount();
2005 if( parameters[1] == wxT(
"(" ) )
2012 if( parameters[0].CmpNoCase( wxT(
"PCB" ) ) == 0 )
2016 int boardWidth =
static_cast<int>(
parseInt( parameters[3], conv_unit ) );
2017 int boardHeight =
static_cast<int>(
parseInt( parameters[4], conv_unit ) );
2020 VECTOR2I pageSize( boardWidth, boardHeight );
2024 m_board->SetPageSettings( page );
2031 if( parameters[0].CmpNoCase( wxT(
"FileVersion" ) ) == 0 )
2035 if( parameters[0].CmpNoCase( wxT(
"Grid" ) ) == 0
2036 || parameters[0].CmpNoCase( wxT(
"Cursor" ) ) == 0
2037 || parameters[0].CmpNoCase( wxT(
"Thermal" ) ) == 0
2038 || parameters[0].CmpNoCase( wxT(
"DRC" ) ) == 0
2039 || parameters[0].CmpNoCase( wxT(
"Flags" ) ) == 0
2040 || parameters[0].CmpNoCase( wxT(
"Groups" ) ) == 0
2041 || parameters[0].CmpNoCase( wxT(
"Styles" ) ) == 0
2042 || parameters[0].CmpNoCase( wxT(
"Attribute" ) ) == 0 )
2048 if( parameters[0].CmpNoCase( wxT(
"Via" ) ) == 0 )
2055 if( parameters[0].CmpNoCase( wxT(
"Element" ) ) == 0 )
2073 if( parameters[0].CmpNoCase( wxT(
"Layer" ) ) == 0 )
2075 parseLayer( parameters, &reader, conv_unit );
2080 if( parameters[0].CmpNoCase( wxT(
"Rat" ) ) == 0 )
2084 if( parameters[0].CmpNoCase( wxT(
"NetList" ) ) == 0 )
2105 m_board->m_LegacyDesignSettingsLoaded =
true;
2106 m_board->m_LegacyNetclassesLoaded =
true;
2115 std::vector<FOOTPRINT*> retval;
2118 retval.push_back(
static_cast<FOOTPRINT*
>( fp->Clone() ) );
constexpr EDA_IU_SCALE pcbIUScale
constexpr BOX2I KiROUND(const BOX2D &aBoxD)
BASE_SET & set(size_t pos)
virtual void SetNet(NETINFO_ITEM *aNetInfo)
Set a NET_INFO object for the item.
void SetLayer(PCB_LAYER_ID aLayer) override
Set the layer this item is on.
Container for design settings for a BOARD object.
void SetEnabledLayers(const LSET &aMask)
Change the bit-mask of enabled layers to aMask.
const LSET & GetEnabledLayers() const
Return a bit-mask of all the layers that are enabled.
Information pertinent to a Pcbnew printed circuit board.
virtual void SetParent(EDA_ITEM *aParent)
void SetCenter(const VECTOR2I &aCenter)
void SetStart(const VECTOR2I &aStart)
void SetShape(SHAPE_T aShape)
void SetEnd(const VECTOR2I &aEnd)
void SetArcAngleAndEnd(const EDA_ANGLE &aAngle, bool aCheckNegativeAngle=false)
Set the end point from the angle center and start.
A LINE_READER that reads from an open file.
char * ReadLine() override
Read a line of text into the buffer and increments the line number counter.
RAII class to set and restore the fontconfig reporter.
helper class for creating a footprint library cache.
std::unique_ptr< FOOTPRINT > m_footprint
WX_FILENAME GetFileName() const
std::unique_ptr< FOOTPRINT > & GetFootprint()
WX_FILENAME m_filename
The full file name and path of the footprint to cache.
GPCB_FPL_CACHE_ENTRY(FOOTPRINT *aFootprint, const WX_FILENAME &aFileName)
FOOTPRINT * parseFOOTPRINT(LINE_READER *aLineReader)
void Remove(const wxString &aFootprintName)
boost::ptr_map< std::string, GPCB_FPL_CACHE_ENTRY > & GetFootprints()
GPCB_FPL_CACHE(PCB_IO_GEDA *aOwner, const wxString &aLibraryPath)
bool IsModified()
Return true if the cache is not up-to-date.
static long long GetTimestamp(const wxString &aLibPath)
Generate a timestamp representing all source files in the cache (including the parent directory).
PCB_IO_GEDA * m_owner
Plugin object that owns the cache.
boost::ptr_map< std::string, GPCB_FPL_CACHE_ENTRY > m_footprints
Map of footprint filename to cache entries.
void parseParameters(wxArrayString &aParameterList, LINE_READER *aLineReader)
Extract parameters and tokens from aLineReader and adds them to aParameterList.
long long m_cache_timestamp
A hash of the timestamps for all the footprint files.
wxFileName m_lib_path
The path of the library.
bool m_cache_dirty
Stored separately because it's expensive to check m_cache_timestamp against all the files.
void Load()
Save not implemented for the Geda PCB footprint library format.
bool testFlags(const wxString &aFlag, long aMask, const wxChar *aName)
Test aFlag for aMask or aName.
Hold an error message and may be used when throwing exceptions containing meaningful error messages.
virtual const wxString What() const
A composite of Problem() and Where()
A logical library item identifier and consists of various portions much like a URI.
An abstract class from which implementation specific LINE_READERs may be derived to read single lines...
virtual char * ReadLine()=0
Read a line of text into the buffer and increments the line number counter.
virtual const wxString & GetSource() const
Returns the name of the source of the lines in an abstract sense.
virtual unsigned LineNumber() const
Return the line number of the last line read from this LINE_READER.
char * Line() const
Return a pointer to the last line that was read in.
static LOAD_INFO_REPORTER & GetInstance()
LSET is a set of PCB_LAYER_IDs.
static const LSET & AllCuMask()
return AllCuMask( MAX_CU_LAYERS );
Handle the data for a net.
static const int UNCONNECTED
Constant that holds the "unconnected net" number (typically 0) all items "connected" to this net are ...
static NETINFO_ITEM * OrphanedItem()
NETINFO_ITEM meaning that there was no net assigned for an item, as there was no board storing net li...
static constexpr PCB_LAYER_ID ALL_LAYERS
! Temporary layer identifier to identify code that is not padstack-aware
Describe the page size and margins of a paper page on which to eventually print or plot.
void SetHeightMils(double aHeightInMils)
void SetWidthMils(double aWidthInMils)
void SetMid(const VECTOR2I &aMid)
A #PLUGIN derivation for saving and loading Geda PCB files.
void FootprintDelete(const wxString &aLibraryPath, const wxString &aFootprintName, const std::map< std::string, UTF8 > *aProperties=nullptr) override
Delete aFootprintName from the library at aLibraryPath.
void parseVia(wxArrayString &aParameters, double aConvUnit)
void parseNetList(LINE_READER *aLineReader)
bool IsLibraryWritable(const wxString &aLibraryPath) override
Return true if the library at aLibraryPath is writable.
void FootprintEnumerate(wxArrayString &aFootprintNames, const wxString &aLibraryPath, bool aBestEfforts, const std::map< std::string, UTF8 > *aProperties=nullptr) override
Return a list of footprint names contained within the library at aLibraryPath.
long long GetLibraryTimestamp(const wxString &aLibraryPath) const override
Generate a timestamp representing all the files in the library (including the library directory).
std::map< wxString, NETINFO_ITEM * > m_netMap
bool DeleteLibrary(const wxString &aLibraryPath, const std::map< std::string, UTF8 > *aProperties=nullptr) override
Delete an existing library and returns true, or if library does not exist returns false,...
bool CanReadBoard(const wxString &aFileName) const override
Checks if this PCB_IO can read the specified board file.
FOOTPRINT * FootprintLoad(const wxString &aLibraryPath, const wxString &aFootprintName, bool aKeepUUID=false, const std::map< std::string, UTF8 > *aProperties=nullptr) override
Load a footprint having aFootprintName from the aLibraryPath containing a library format that this PC...
std::vector< FOOTPRINT * > GetImportedCachedLibraryFootprints() override
Return a container with the cached library footprints generated in the last call to Load.
void init(const std::map< std::string, UTF8 > *aProperties)
GPCB_FPL_CACHE * m_cache
Footprint library cache.
bool testFlags(const wxString &aFlag, long aMask, const wxChar *aName)
FOOTPRINT * parseElement(wxArrayString &aParameters, LINE_READER *aLineReader, double aConvUnit)
void validateCache(const wxString &aLibraryPath, bool checkModified=true)
void parseParameters(wxArrayString &aParameterList, LINE_READER *aLineReader)
void parseLayer(wxArrayString &aParameters, LINE_READER *aLineReader, double aConvUnit)
std::vector< FOOTPRINT * > m_cachedFootprints
LINE_READER * m_reader
no ownership here.
friend class GPCB_FPL_CACHE
PCB_LAYER_ID mapLayer(int aGedaLayer, const wxString &aLayerName) const
FOOTPRINT * ImportFootprint(const wxString &aFootprintPath, wxString &aFootprintNameOut, const std::map< std::string, UTF8 > *aProperties) override
Load a single footprint from aFootprintPath and put its name in aFootprintNameOut.
BOARD * LoadBoard(const wxString &aFileName, BOARD *aAppendToMe, const std::map< std::string, UTF8 > *aProperties=nullptr, PROJECT *aProject=nullptr) override
Load information from some input file format that this PCB_IO implementation knows about into either ...
const FOOTPRINT * getFootprint(const wxString &aLibraryPath, const wxString &aFootprintName, const std::map< std::string, UTF8 > *aProperties, bool checkModified)
BOARD * m_board
The board BOARD being worked on, no ownership here.
virtual bool CanReadBoard(const wxString &aFileName) const
Checks if this PCB_IO can read the specified board file.
PCB_IO(const wxString &aName)
const std::map< std::string, UTF8 > * m_props
Properties passed via Save() or Load(), no ownership, may be NULL.
void Rotate(const VECTOR2I &aRotCentre, const EDA_ANGLE &aAngle) override
Rotate this object.
void SetLayer(PCB_LAYER_ID aLayer) override
Set the layer this item is on.
void Move(const VECTOR2I &aMoveVector) override
Move this object.
void SetStroke(const STROKE_PARAMS &aStroke) override
void SetEnd(const VECTOR2I &aEnd)
void SetStart(const VECTOR2I &aStart)
virtual void SetWidth(int aWidth)
Container for project specific data.
Simple container to manage line stroke parameters.
Read lines of text from another LINE_READER but only returns non-comment lines and non-blank lines wi...
char * ReadLine() override
Read a line of text into the buffer and increments the line number counter.
A wrapper around a wxFileName which is much more performant with a subset of the API.
void SetFullName(const wxString &aFileNameAndExtension)
wxString GetFullPath() const
Handle a list of polygons defining a copper zone.
void SetLocalClearance(std::optional< int > aClearance)
virtual void SetLayer(PCB_LAYER_ID aLayer) override
Set the layer this item is on.
bool SetNetCode(int aNetCode, bool aNoAssert) override
Override that clamps the netcode to 0 when this zone is in copper-thieving fill mode.
void SetIsFilled(bool isFilled)
bool AppendCorner(VECTOR2I aPosition, int aHoleIdx, bool aAllowDuplication=false)
Add a new corner to the zone outline (to the main outline or a hole)
void SetAssignedPriority(unsigned aPriority)
int GetNumCorners(void) const
Access to m_Poly parameters.
static constexpr EDA_ANGLE ANGLE_360
static constexpr EDA_ANGLE ANGLE_180
#define IGNORE_PARENT_GROUP
void CollectFilesLoopSafe(const wxString &aRoot, wxArrayString &aFiles, const wxString &aFileSpec, int aFlags)
Recursively collect every file under aRoot, deduplicating subdirectories by their resolved path.
static const std::string GedaPcbFootprintLibFileExtension
static const std::string KiCadFootprintFileExtension
const wxChar *const traceGedaPcbPlugin
Flag to enable GEDA PCB plugin debug output.
#define THROW_IO_ERROR(msg)
macro which captures the "call site" values of FILE_, __FUNCTION & LINE
#define THROW_PARSE_ERROR(aProblem, aSource, aInputLine, aLineNumber, aByteIndex)
bool IsCopperLayer(int aLayerId)
Test whether a layer is a copper layer.
PCB_LAYER_ID
A quick note on layer IDs:
This file contains miscellaneous commonly used macros and functions.
#define KI_FALLTHROUGH
The KI_FALLTHROUGH macro is to be used when switch statement cases should purposely fallthrough from ...
@ TOP_BOTTOM
Flip top to bottom (around the X axis)
@ SMD
Smd pad, appears on the solder paste layer (default)
static long parseInt(const wxString &aValue, double aScalar)
#define NEW_GPCB_UNIT_CONV
#define OLD_GPCB_UNIT_CONV
#define TEXT_DEFAULT_SIZE
Geda PCB file plugin definition file.
int parseInt(LINE_READER &aReader, const char *aLine, const char **aOutput)
Parse an ASCII integer string with possible leading whitespace into an integer and updates the pointe...
wxString From_UTF8(const char *cstring)
#define TO_UTF8(wxstring)
Convert a wxString to a UTF8 encoded C string for all wxWidgets build modes.
wxString dump(const wxArrayString &aArray)
Debug helper for printing wxArrayString contents.
wxLogTrace helper definitions.
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.