24 #include <boost/algorithm/string/join.hpp> 29 #include <wx/mstream.h> 30 #include <wx/filename.h> 32 #include <wx/textfile.h> 33 #include <wx/tokenzr.h> 67 #define Mils2Iu( x ) Mils2iu( x ) 71 #define DOCFILE_IDENT "EESchema-DOCLIB Version 2.0" 73 #define SCH_PARSE_ERROR( text, reader, pos ) \ 74 THROW_PARSE_ERROR( text, reader.GetSource(), reader.Line(), \ 75 reader.LineNumber(), pos - reader.Line() ) 82 #define T_STYLE "style" 83 #define T_COLOR "rgb" // cannot be modified (used by wxWidgets) 84 #define T_COLORA "rgba" // cannot be modified (used by wxWidgets) 85 #define T_WIDTH "width" 96 if( c ==
'\n' || c ==
'\r' || c == 0 )
112 static bool strCompare(
const char* aString,
const char* aLine,
const char** aOutput =
nullptr )
114 size_t len = strlen( aString );
115 bool retv = ( strncasecmp( aLine, aString, len ) == 0 ) &&
116 ( isspace( aLine[ len ] ) || aLine[ len ] == 0 );
118 if( retv && aOutput )
120 const char* tmp = aLine;
126 while( *tmp && isspace( *tmp ) )
157 long retv = strtol( aLine, (
char**) aOutput, 10 );
160 if( errno == ERANGE )
166 const char*
next = *aOutput;
198 unsigned long long retv;
202 retv = strtoull( aLine, (
char**) aOutput, 16 );
205 if( errno == ERANGE )
211 const char*
next = *aOutput;
219 return (uint32_t)retv;
237 const char** aOutput =
nullptr )
245 double retv = strtod( aLine, (
char**) aOutput );
248 if( errno == ERANGE )
254 const char*
next = *aOutput;
278 const char** aNextToken =
nullptr )
280 while( *aCurrentToken && isspace( *aCurrentToken ) )
283 if( !*aCurrentToken )
286 if( !isspace( *( aCurrentToken + 1 ) ) )
287 SCH_PARSE_ERROR(
"expected single character token", aReader, aCurrentToken );
291 const char*
next = aCurrentToken + 2;
299 return *aCurrentToken;
318 const char* aCurrentToken,
const char** aNextToken =
nullptr,
319 bool aCanBeEmpty =
false )
321 if( !*aCurrentToken )
329 const char* tmp = aCurrentToken;
331 while( *tmp && isspace( *tmp ) )
344 while( *tmp && !isspace( *tmp ) )
349 if( aString.IsEmpty() && !aCanBeEmpty )
354 const char*
next = tmp;
380 const char* aCurrentToken,
const char** aNextToken =
nullptr,
381 bool aCanBeEmpty =
false )
383 if( !*aCurrentToken )
391 const char* tmp = aCurrentToken;
393 while( *tmp && isspace( *tmp ) )
423 if( *tmp !=
'"' && *tmp !=
'\\' )
428 else if( *tmp ==
'"' )
442 if( aString.IsEmpty() && !aCanBeEmpty )
445 if( *tmp && *tmp !=
'"' )
453 const char*
next = tmp;
455 while( *
next ==
' ' )
486 int aMajorVersion,
int aMinorVersion );
493 int aMajorVersion,
int aMinorVersion );
537 void Save(
bool aSaveDocFile =
true );
550 bool IsFile(
const wxString& aFullPathAndFileName )
const;
570 m_progressReporter( nullptr ),
571 m_lineReader( nullptr ),
572 m_lastProgressLine( 0 ),
597 const unsigned PROGRESS_DELTA = 250;
620 wxASSERT( !aFileName || aSchematic !=
nullptr );
625 wxFileName fn = aFileName;
630 wxASSERT( fn.IsAbsolute() );
639 if( !normedFn.IsAbsolute() )
641 if( aFileName.Right( normedFn.GetFullPath().Length() ) == normedFn.GetFullPath() )
642 m_path = aFileName.Left( aFileName.Length() - normedFn.GetFullPath().Length() );
656 init( aSchematic, aProperties );
658 if( aAppendToMe ==
nullptr )
661 std::unique_ptr<SCH_SHEET> newSheet = std::make_unique<SCH_SHEET>( aSchematic );
662 newSheet->SetFileName( aFileName );
667 sheet = newSheet.release();
672 wxCHECK_MSG( aSchematic->
IsValid(),
nullptr,
"Can't append to a schematic with no root!" );
696 fileName.SetExt(
"sch" );
698 if( !fileName.IsAbsolute() )
744 wxCHECK2( aItem->Type() ==
SCH_SHEET_T, continue );
745 auto sheet = static_cast<SCH_SHEET*>( aItem );
752 sheet->SetParent( aSheet );
793 char* line = reader.
Line();
795 while( *line ==
' ' )
810 "Cannot call SCH_LEGACY_PLUGIN::LoadContent() without setting root sheet." );
816 char* line = aReader.
Line();
818 while( *line ==
' ' )
853 const char* line = aReader.
ReadLine();
855 if( !line || !
strCompare(
"Eeschema Schematic File Version", line, &line ) )
857 m_error.Printf(
_(
"'%s' does not appear to be an Eeschema file." ),
878 line = aReader.
Line();
880 while( *line ==
' ' )
893 wxASSERT( aScreen !=
nullptr );
896 const char* line = aReader.
Line();
901 wxCHECK_RET(
strCompare(
"$Descr", line, &line ),
"Invalid sheet description" );
908 int pagew =
parseInt( aReader, line, &line );
909 int pageh =
parseInt( aReader, line, &line );
918 wxString orientation;
924 if( orientation ==
"portrait" )
930 while( line !=
nullptr )
937 line = aReader.
Line();
964 else if(
strCompare(
"Comment1", line, &line ) )
969 else if(
strCompare(
"Comment2", line, &line ) )
974 else if(
strCompare(
"Comment3", line, &line ) )
979 else if(
strCompare(
"Comment4", line, &line ) )
984 else if(
strCompare(
"Comment5", line, &line ) )
989 else if(
strCompare(
"Comment6", line, &line ) )
994 else if(
strCompare(
"Comment7", line, &line ) )
999 else if(
strCompare(
"Comment8", line, &line ) )
1004 else if(
strCompare(
"Comment9", line, &line ) )
1022 std::unique_ptr<SCH_SHEET> sheet = std::make_unique<SCH_SHEET>();
1024 const char* line = aReader.
ReadLine();
1026 while( line !=
nullptr )
1034 sheet->SetPosition( position );
1040 sheet->SetSize( size );
1047 if(
text !=
"00000000" )
1048 const_cast<KIID&>( sheet->m_Uuid ) =
KIID(
text );
1050 else if( *line ==
'F' )
1056 int fieldId =
parseInt( aReader, line, &line );
1058 if( fieldId == 0 || fieldId == 1 )
1063 SCH_FIELD& field = sheet->GetFields()[ fieldId ];
1070 std::unique_ptr<SCH_SHEET_PIN> sheetPin = std::make_unique<SCH_SHEET_PIN>( sheet.get() );
1072 sheetPin->SetNumber( fieldId );
1079 if( line ==
nullptr )
1082 switch(
parseChar( aReader, line, &line ) )
1092 switch(
parseChar( aReader, line, &line ) )
1106 sheetPin->SetPosition( position );
1110 sheetPin->SetTextSize( wxSize( size, size ) );
1112 sheet->AddPin( sheetPin.release() );
1117 sheet->AutoplaceFields(
nullptr,
false );
1118 return sheet.release();
1132 std::unique_ptr<SCH_BITMAP> bitmap = std::make_unique<SCH_BITMAP>();
1134 const char* line = aReader.
Line();
1136 wxCHECK(
strCompare(
"$Bitmap", line, &line ),
nullptr );
1140 while( line !=
nullptr )
1148 bitmap->SetPosition( position );
1150 else if(
strCompare(
"Scale", line, &line ) )
1152 auto scalefactor =
parseDouble( aReader, line, &line );
1158 if( !std::isnormal( scalefactor ) )
1161 bitmap->GetImage()->SetScale( scalefactor );
1165 wxMemoryOutputStream stream;
1172 line = aReader.
Line();
1178 wxImage*
image =
new wxImage();
1179 wxMemoryInputStream istream( stream );
1180 image->LoadFile( istream, wxBITMAP_TYPE_PNG );
1181 bitmap->GetImage()->SetImage(
image );
1182 bitmap->GetImage()->SetBitmap(
new wxBitmap( *
image ) );
1193 int len = strlen( line );
1195 for( ; len > 0 && !isspace( *line ) &&
'$' != *line; len -= 3, line += 3 )
1199 if( sscanf( line,
"%X", &value ) == 1 )
1200 stream.PutC( (
char) value );
1206 if( line ==
nullptr )
1210 return bitmap.release();
1221 std::unique_ptr<SCH_JUNCTION> junction = std::make_unique<SCH_JUNCTION>();
1223 const char* line = aReader.
Line();
1225 wxCHECK(
strCompare(
"Connection", line, &line ),
nullptr );
1235 junction->SetPosition( position );
1237 return junction.release();
1243 std::unique_ptr<SCH_NO_CONNECT> no_connect = std::make_unique<SCH_NO_CONNECT>();
1245 const char* line = aReader.
Line();
1247 wxCHECK(
strCompare(
"NoConn", line, &line ),
nullptr );
1257 no_connect->SetPosition( position );
1259 return no_connect.release();
1265 std::unique_ptr<SCH_LINE> wire = std::make_unique<SCH_LINE>();
1267 const char* line = aReader.
Line();
1269 wxCHECK(
strCompare(
"Wire", line, &line ),
nullptr );
1275 else if(
strCompare(
"Notes", line, &line ) )
1285 while( !
is_eol( *line ) )
1297 wire->SetLineWidth( size );
1303 wire->SetLineStyle( style );
1311 wxString prm, keyword;
1312 keyword = buf.BeforeLast(
'(', &prm );
1316 long color[4] = { 0 };
1320 if( !prm.IsEmpty() )
1322 prm.ToLong( &
color[ii] );
1326 int prm_count = ( keyword ==
T_COLORA ) ? 4 : 3;
1330 for(; ii < prm_count && !
is_eol( *line ); ii++ )
1335 if( *line ==
',' || *line ==
' ')
1354 wire->SetStartPoint( begin );
1355 wire->SetEndPoint( end );
1357 return wire.release();
1363 const char* line = aReader.
Line();
1365 wxCHECK(
strCompare(
"Entry", line, &line ),
nullptr );
1367 std::unique_ptr<SCH_BUS_ENTRY_BASE> busEntry;
1371 busEntry = std::make_unique<SCH_BUS_WIRE_ENTRY>();
1374 SCH_PARSE_ERROR(
"invalid bus entry definition expected 'Line'", aReader, line );
1378 busEntry = std::make_unique<SCH_BUS_BUS_ENTRY>();
1381 SCH_PARSE_ERROR(
"invalid bus entry definition expected 'Bus'", aReader, line );
1399 busEntry->SetPosition( pos );
1400 busEntry->SetSize( size );
1402 return busEntry.release();
1419 const char* line = aReader.
Line();
1421 wxCHECK(
strCompare(
"Text", line, &line ),
nullptr );
1423 std::unique_ptr<SCH_TEXT>
text;
1427 else if(
strCompare(
"Label", line, &line ) )
1429 else if(
strCompare(
"HLabel", line, &line ) )
1431 else if(
strCompare(
"GLabel", line, &line ) )
1435 text = std::make_unique<SCH_HIERLABEL>();
1437 text = std::make_unique<SCH_GLOBALLABEL>();
1447 text->SetPosition( position );
1449 int spinStyle =
parseInt( aReader, line, &line );
1461 if( spinStyle == 0 )
1463 else if( spinStyle == 2 )
1471 text->SetTextSize( wxSize( size, size ) );
1477 [ &line ](
const auto& it )
1483 text->SetShape( resultIt->first );
1497 text->SetItalic(
true );
1505 penWidth =
parseInt( aReader, line, &line );
1508 text->SetBold( penWidth != 0 );
1514 tmp = strtok( tmp,
"\r\n" );
1519 int i = val.find( wxT(
"\\n" ) );
1521 if( i == wxNOT_FOUND )
1525 val.insert( i, wxT(
"\n" ) );
1530 return text.release();
1536 const char* line = aReader.
Line();
1538 wxCHECK(
strCompare(
"$Comp", line, &line ),
nullptr );
1540 std::unique_ptr<SCH_SYMBOL> symbol = std::make_unique<SCH_SYMBOL>();
1544 while( line !=
nullptr )
1550 wxString utf8Line = wxString::FromUTF8( line );
1551 wxStringTokenizer tokens( utf8Line,
" \r\n\t" );
1553 if( tokens.CountTokens() < 2 )
1557 libName = tokens.GetNextToken();
1558 libName.Replace(
"~",
" " );
1566 libId.
Parse( libName,
true );
1570 symbol->SetLibId( libId );
1572 wxString refDesignator = tokens.GetNextToken();
1574 refDesignator.Replace(
"~",
" " );
1576 wxString prefix = refDesignator;
1578 while( prefix.Length() )
1580 if( ( prefix.Last() <
'0' || prefix.Last() >
'9') && prefix.Last() !=
'?' )
1583 prefix.RemoveLast();
1587 prefix.Trim(
true );
1588 prefix.Trim(
false );
1590 if( prefix.IsEmpty() )
1591 symbol->SetPrefix( wxString(
"U" ) );
1593 symbol->SetPrefix( prefix );
1599 int unit =
parseInt( aReader, line, &line );
1610 symbol->SetUnit( unit );
1624 symbol->SetConvert(
convert );
1629 if(
text !=
"00000000" )
1630 const_cast<KIID&>( symbol->m_Uuid ) =
KIID(
text );
1638 symbol->SetPosition( pos );
1645 if( strncasecmp(
strCompare, line, len ) != 0 )
1649 wxString pathStr, reference, unit;
1657 if(
path.size() > 0 )
1659 for(
size_t i =
path.size() - 1; i > 0; --i )
1670 if( strncasecmp(
strCompare, line, len ) != 0 )
1679 if( strncasecmp(
strCompare, line, len ) != 0 )
1687 if( !unit.ToLong( &tmp, 10 ) )
1693 symbol->AddHierarchicalReference(
path, reference, (
int)tmp );
1699 int index =
parseInt( aReader, line, &line );
1705 char orientation =
parseChar( aReader, line, &line );
1710 int attributes =
parseHex( aReader, line, &line );
1712 if( index >= symbol->GetFieldCount() )
1722 index = symbol->GetFieldCount();
1724 SCH_FIELD field( wxPoint( 0, 0 ), index, symbol.get(),
name );
1725 symbol->AddField( field );
1728 SCH_FIELD& field = symbol->GetFields()[index];
1734 char hjustify =
parseChar( aReader, line, &line );
1741 if( hjustify ==
'L' )
1743 else if( hjustify ==
'R' )
1745 else if( hjustify !=
'C' )
1746 SCH_PARSE_ERROR(
"symbol field text horizontal justification must be " 1747 "L, R, or C", aReader, line );
1751 if( textAttrs[0] ==
'T' )
1753 else if( textAttrs[0] ==
'B' )
1755 else if( textAttrs[0] !=
'C' )
1757 "B, T, or C", aReader, line );
1760 if( textAttrs.Length() > 1 )
1762 if( textAttrs.Length() != 3 )
1763 SCH_PARSE_ERROR(
_(
"symbol field text attributes must be 3 characters wide" ),
1766 if( textAttrs[1] ==
'I' )
1768 else if( textAttrs[1] !=
'N' )
1769 SCH_PARSE_ERROR(
"symbol field text italics indicator must be I or N",
1772 if( textAttrs[2] ==
'B' )
1774 else if( textAttrs[2] !=
'N' )
1785 if( orientation ==
'H' )
1787 else if( orientation ==
'V' )
1790 SCH_PARSE_ERROR(
"symbol field orientation must be H or V", aReader, line );
1792 if(
name.IsEmpty() )
1800 symbol->ClearFlags();
1801 return symbol.release();
1818 transform.
x1 =
parseInt( aReader, line, &line );
1820 if( transform.
x1 < -1 || transform.
x1 > 1 )
1821 SCH_PARSE_ERROR(
"invalid symbol X1 transform value", aReader, line );
1823 transform.
y1 =
parseInt( aReader, line, &line );
1825 if( transform.
y1 < -1 || transform.
y1 > 1 )
1826 SCH_PARSE_ERROR(
"invalid symbol Y1 transform value", aReader, line );
1828 transform.
x2 =
parseInt( aReader, line, &line );
1830 if( transform.
x2 < -1 || transform.
x2 > 1 )
1831 SCH_PARSE_ERROR(
"invalid symbol X2 transform value", aReader, line );
1833 transform.
y2 =
parseInt( aReader, line, &line );
1835 if( transform.
y2 < -1 || transform.
y2 > 1 )
1836 SCH_PARSE_ERROR(
"invalid symbol Y2 transform value", aReader, line );
1838 symbol->SetTransform( transform );
1853 auto busAlias = std::make_shared<BUS_ALIAS>( aScreen );
1854 const char* line = aReader.
Line();
1856 wxCHECK(
strCompare(
"BusAlias", line, &line ),
nullptr );
1860 busAlias->SetName( buf );
1862 while( *line !=
'\0' )
1869 busAlias->AddMember( buf );
1880 wxCHECK_RET( aSheet !=
nullptr,
"NULL SCH_SHEET object." );
1881 wxCHECK_RET( !aFileName.IsEmpty(),
"No schematic file name defined." );
1885 init( aSchematic, aProperties );
1887 wxFileName fn = aFileName;
1891 wxASSERT( fn.IsAbsolute() );
1905 wxCHECK_RET( aSheet !=
nullptr,
"NULL SCH_SHEET* object." );
1906 wxCHECK_RET(
m_schematic !=
nullptr,
"NULL SCHEMATIC* object." );
1955 std::multiset<
SCH_ITEM*, decltype( cmp )> save_map( cmp );
1957 for(
auto item : screen->
Items() )
1958 save_map.insert( item );
1961 for(
auto& item : save_map )
1963 switch( item->Type() )
1966 saveSymbol( static_cast<SCH_SYMBOL*>( item ) );
1969 saveBitmap( static_cast<SCH_BITMAP*>( item ) );
1972 saveSheet( static_cast<SCH_SHEET*>( item ) );
1982 saveBusEntry( static_cast<SCH_BUS_ENTRY_BASE*>( item ) );
1985 saveLine( static_cast<SCH_LINE*>( item ) );
1991 saveText( static_cast<SCH_TEXT*>( item ) );
1994 wxASSERT(
"Unexpected schematic object type in SCH_LEGACY_PLUGIN::Format()" );
2006 for(
unsigned i = 0; i < aSelection->
GetSize(); ++i )
2010 switch( item->
Type() )
2013 saveSymbol( static_cast< SCH_SYMBOL* >( item ) );
2016 saveBitmap( static_cast< SCH_BITMAP* >( item ) );
2019 saveSheet( static_cast< SCH_SHEET* >( item ) );
2029 saveBusEntry( static_cast< SCH_BUS_ENTRY_BASE* >( item ) );
2032 saveLine( static_cast< SCH_LINE* >( item ) );
2038 saveText( static_cast< SCH_TEXT* >( item ) );
2041 wxASSERT(
"Unexpected schematic object type in SCH_LEGACY_PLUGIN::Format()" );
2052 static wxString delimiters( wxT(
" " ) );
2070 if( symbol_name.size() )
2080 m_out->
Print( 0,
"L %s %s\n", name2.c_str(), name1.c_str() );
2109 wxString
path =
"/";
2112 for(
int i = 1; i < (int) instance.m_Path.size(); ++i )
2113 path += instance.m_Path[i].AsLegacyTimestampString() +
"/";
2115 m_out->
Print( 0,
"AR Path=\"%s\" Ref=\"%s\" Part=\"%d\" \n",
2117 TO_UTF8( instance.m_Reference ),
2148 transform.
x1, transform.
y1, transform.
x2, transform.
y2 );
2155 char hjustify =
'C';
2162 char vjustify =
'C';
2169 m_out->
Print( 0,
"F %d %s %c %-3d %-3d %-3d %4.4X %c %c%c%c",
2179 aField->
IsBold() ?
'B' :
'N' );
2191 wxCHECK_RET( aBitmap !=
nullptr,
"SCH_BITMAP* is NULL" );
2195 wxCHECK_RET(
image !=
nullptr,
"wxImage* is NULL" );
2204 wxMemoryOutputStream stream;
2206 image->SaveFile( stream, wxBITMAP_TYPE_PNG );
2209 wxStreamBuffer* buffer = stream.GetOutputStreamBuffer();
2210 char* begin = (
char*) buffer->GetBufferStart();
2212 for(
int ii = 0; begin < buffer->GetBufferEnd(); begin++, ii++ )
2231 wxCHECK_RET( aSheet !=
nullptr,
"SCH_SHEET* is NULL" );
2237 Iu2Mils( aSheet->
GetSize().x ),
2238 Iu2Mils( aSheet->
GetSize().y ) );
2245 if( !sheetName.
GetText().IsEmpty() )
2250 if( !fileName.
GetText().IsEmpty() )
2259 if(
pin->GetText().IsEmpty() )
2262 switch(
pin->GetSide() )
2271 switch(
pin->GetShape() )
2281 m_out->
Print( 0,
"F%d %s %c %c %-3d %-3d %-3d\n",
2284 type, side, Iu2Mils(
pin->GetPosition().x ),
2285 Iu2Mils(
pin->GetPosition().y ),
2286 Iu2Mils(
pin->GetTextWidth() ) );
2295 wxCHECK_RET( aJunction !=
nullptr,
"SCH_JUNCTION* is NULL" );
2305 wxCHECK_RET( aNoConnect !=
nullptr,
"SCH_NOCONNECT* is NULL" );
2315 wxCHECK_RET( aBusEntry !=
nullptr,
"SCH_BUS_ENTRY_BASE* is NULL" );
2318 m_out->
Print( 0,
"Entry Wire Line\n\t%-4d %-4d %-4d %-4d\n",
2321 Iu2Mils( aBusEntry->
GetEnd().x ), Iu2Mils( aBusEntry->
GetEnd().y ) );
2323 m_out->
Print( 0,
"Entry Bus Bus\n\t%-4d %-4d %-4d %-4d\n",
2326 Iu2Mils( aBusEntry->
GetEnd().x ), Iu2Mils( aBusEntry->
GetEnd().y ) );
2332 wxCHECK_RET( aLine !=
nullptr,
"SCH_LINE* is NULL" );
2334 const char* layer =
"Notes";
2335 const char* width =
"Line";
2342 m_out->
Print( 0,
"Wire %s %s", layer, width );
2371 wxCHECK_RET( aText !=
nullptr,
"SCH_TEXT* is NULL" );
2373 const char* italics =
"~";
2374 const char* textType =
"Notes";
2389 text.Replace( wxT(
"\n" ), wxT(
"\\n" ) );
2397 for(
unsigned ii = 0; ii <
text.Len(); )
2399 if(
text[ii] == 0x0A ||
text[ii] == 0x0D )
2400 text.erase( ii, 1 );
2413 if( spinStyle == 0 )
2415 else if( spinStyle == 2 )
2418 m_out->
Print( 0,
"Text %s %-4d %-4d %-4d %-4d %s %d\n%s\n", textType,
2429 wxCHECK_RET( shapeLabelIt !=
sheetLabelNames.end(),
"Shape not found in names list" );
2431 m_out->
Print( 0,
"Text %s %-4d %-4d %-4d %-4d %s %s %d\n%s\n", textType,
2435 shapeLabelIt->second,
2444 wxCHECK_RET( aAlias !=
nullptr,
"BUS_ALIAS* is NULL" );
2446 wxString members = boost::algorithm::join( aAlias->Members(),
" " );
2458 m_fileName( aFullPathAndFileName ),
2459 m_libFileName( aFullPathAndFileName ),
2460 m_isWritable( true ),
2461 m_isModified( false )
2473 delete symbol.second;
2496 return fn.GetModificationTime();
2510 if(
m_fileModTime.IsValid() && fn.IsOk() && fn.FileExists() )
2519 wxCHECK_MSG( aSymbol !=
nullptr,
nullptr,
"NULL pointer cannot be removed from library." );
2529 wxCHECK_MSG( *it->second == aSymbol,
nullptr,
2530 "Pointer mismatch while attempting to remove alias entry <" + aSymbol->
GetName() +
2531 "> from library cache <" +
m_libFileName.GetName() +
">." );
2539 if( entry.second->IsAlias()
2540 && entry.second->GetParent().lock() == aSymbol->
SharedPtr() )
2542 firstChild = entry.second;
2553 LIB_FIELD& field = static_cast<LIB_FIELD&>( drawItem );
2567 if( entry.second->IsAlias()
2568 && entry.second->GetParent().lock() == aSymbol->
SharedPtr() )
2569 entry.second->SetParent( firstChild );
2616 if( !reader.ReadLine() )
2619 const char* line = reader.Line();
2621 if( !
strCompare(
"EESchema-LIBRARY Version", line, &line ) )
2625 if( !
strCompare(
"EESchema-LIB Version", line, &line ) )
2626 SCH_PARSE_ERROR(
"file is not a valid symbol or symbol library file", reader, line );
2632 SCH_PARSE_ERROR(
"invalid file version formatting in header", reader, line );
2638 if(
m_versionMajor < 1 || m_versionMinor < 0 || m_versionMinor > 99 )
2655 while( reader.ReadLine() )
2657 line = reader.Line();
2659 if( *line ==
'#' || isspace( *line ) )
2698 if( !fn.FileExists() )
2701 if( !fn.IsFileReadable() )
2704 fn.GetFullPath() ) );
2715 SCH_PARSE_ERROR(
"invalid document library file version formatting in header",
2718 while( reader.ReadLine() )
2720 line = reader.Line();
2725 if( !
strCompare(
"$CMP", line, &line ) != 0 )
2728 aliasName = wxString::FromUTF8( line );
2731 LIB_SYMBOL_MAP::iterator it =
m_symbols.find( aliasName );
2734 wxLogWarning(
"Symbol '%s' not found in library:\n\n" 2735 "'%s'\n\nat line %d offset %d", aliasName, fn.GetFullPath(),
2736 reader.LineNumber(), (int) (line - reader.Line() ) );
2738 symbol = it->second;
2743 while( reader.ReadLine() )
2745 line = reader.Line();
2782 SCH_PARSE_ERROR(
"expected token in symbol definition", reader, line );
2791 const char* line = aReader.
Line();
2793 wxASSERT(
strCompare(
"$HEADER", line, &line ) );
2797 line = (
char*) aReader;
2803 else if(
strCompare(
"$ENDHEADER", line, &line ) )
2814 const char* line = aReader.
Line();
2816 while( *line ==
'#' )
2824 wxString utf8Line = wxString::FromUTF8( line );
2825 wxStringTokenizer tokens( utf8Line,
" \r\n\t" );
2827 if( tokens.CountTokens() < 8 )
2831 std::unique_ptr<LIB_SYMBOL> symbol = std::make_unique<LIB_SYMBOL>( wxEmptyString );
2833 wxString
name, prefix, tmp;
2835 name = tokens.GetNextToken();
2843 pos +=
name.size() + 1;
2845 prefix = tokens.GetNextToken();
2846 pos += prefix.size() + 1;
2848 tmp = tokens.GetNextToken();
2849 pos += tmp.size() + 1;
2851 tmp = tokens.GetNextToken();
2853 if( !tmp.ToLong( &num ) )
2857 pos += tmp.size() + 1;
2858 symbol->SetPinNameOffset(
Mils2Iu( (
int)num ) );
2860 tmp = tokens.GetNextToken();
2862 if( !( tmp ==
"Y" || tmp ==
"N") )
2866 pos += tmp.size() + 1;
2867 symbol->SetShowPinNumbers( ( tmp ==
"N" ) ?
false :
true );
2869 tmp = tokens.GetNextToken();
2871 if( !( tmp ==
"Y" || tmp ==
"N") )
2875 pos += tmp.size() + 1;
2876 symbol->SetShowPinNames( ( tmp ==
"N" ) ?
false :
true );
2878 tmp = tokens.GetNextToken();
2880 if( !tmp.ToLong( &num ) )
2884 pos += tmp.size() + 1;
2885 symbol->SetUnitCount( (
int)num );
2888 if( symbol->GetUnitCount() < 1 )
2889 symbol->SetUnitCount( 1 );
2894 if(
name.IsEmpty() )
2896 symbol->SetName(
"~" );
2898 else if(
name[0] !=
'~' )
2900 symbol->SetName(
name );
2904 symbol->SetName(
name.Right(
name.Length() - 1 ) );
2905 symbol->GetValueField().SetVisible(
false );
2909 symbol->SetLibId(
LIB_ID( wxEmptyString, symbol->GetName() ) );
2911 LIB_FIELD& reference = symbol->GetReferenceField();
2925 if(
LIB_VERSION( aMajorVersion, aMinorVersion ) > 0
2930 tmp = tokens.GetNextToken();
2931 pos += tmp.size() + 1;
2935 tmp = tokens.GetNextToken();
2938 symbol->LockUnits(
true );
2939 else if( tmp ==
"F" || tmp ==
"0" )
2940 symbol->LockUnits(
false );
2945 pos += tmp.size() + 1;
2949 if( tokens.HasMoreTokens() )
2951 tmp = tokens.GetNextToken();
2955 else if( tmp ==
"N" )
2956 symbol->SetNormal();
2971 else if(
strCompare(
"ALIAS", line, &line ) )
2973 else if( *line ==
'F' )
2977 else if(
strCompare(
"$FPLIST", line, &line ) )
2979 else if(
strCompare(
"ENDDEF", line, &line ) )
2981 return symbol.release();
2995 wxString newAliasName;
2996 const char* line = aReader.
Line();
2998 wxCHECK_RET(
strCompare(
"ALIAS", line, &line ),
"Invalid ALIAS section" );
3000 wxString utf8Line = wxString::FromUTF8( line );
3001 wxStringTokenizer tokens( utf8Line,
" \r\n\t" );
3004 while( tokens.HasMoreTokens() )
3006 newAliasName = tokens.GetNextToken();
3020 LIB_FIELD* parentField = aSymbol->GetFieldById(
id );
3022 wxASSERT( parentField );
3024 *field = *parentField;
3027 field->
SetText( newAliasName );
3035 (*aMap)[ newSymbol->
GetName() ] = newSymbol;
3044 const char* line = aReader.
Line();
3046 wxCHECK_RET( *line ==
'F',
"Invalid field line" );
3051 if( sscanf( line + 1,
"%d", &
id ) != 1 ||
id < 0 )
3058 field = aSymbol->GetFieldById(
id );
3067 field =
new LIB_FIELD( aSymbol.get(), id );
3068 aSymbol->AddDrawItem( field,
false );
3072 while( *line !=
'"' && *line != 0 )
3087 if(
text.size() == 1 &&
text[0] ==
'~' )
3088 field->
SetText( wxEmptyString );
3100 textSize.x = textSize.y =
Mils2Iu(
parseInt( aReader, line, &line ) );
3103 char textOrient =
parseChar( aReader, line, &line );
3105 if( textOrient ==
'H' )
3107 else if( textOrient ==
'V' )
3110 SCH_PARSE_ERROR(
"invalid field text orientation parameter", aReader, line );
3112 char textVisible =
parseChar( aReader, line, &line );
3114 if( textVisible ==
'V' )
3116 else if ( textVisible ==
'I' )
3119 SCH_PARSE_ERROR(
"invalid field text visibility parameter", aReader, line );
3125 if( *line != 0 && *line !=
'"' )
3127 char textHJustify =
parseChar( aReader, line, &line );
3129 if( textHJustify ==
'C' )
3131 else if( textHJustify ==
'L' )
3133 else if( textHJustify ==
'R' )
3136 SCH_PARSE_ERROR(
"invalid field text horizontal justification", aReader, line );
3138 wxString attributes;
3142 size_t attrSize = attributes.size();
3144 if( !(attrSize == 3 || attrSize == 1 ) )
3145 SCH_PARSE_ERROR(
"invalid field text attributes size", aReader, line );
3147 switch( (wxChar) attributes[0] )
3152 default:
SCH_PARSE_ERROR(
"invalid field text vertical justification", aReader, line );
3157 wxChar attr_1 = attributes[1];
3158 wxChar attr_2 = attributes[2];
3162 else if( attr_1 !=
'N' )
3163 SCH_PARSE_ERROR(
"invalid field text italic parameter", aReader, line );
3165 if ( attr_2 ==
'B' )
3167 else if( attr_2 !=
'N' )
3168 SCH_PARSE_ERROR(
"invalid field text bold parameter", aReader, line );
3183 field->
SetText( aSymbol->GetName() );
3197 const char* line = aReader.
Line();
3199 wxCHECK_RET(
strCompare(
"DRAW", line, &line ),
"Invalid DRAW section" );
3207 aSymbol->GetDrawItems().sort();
3214 aSymbol->AddDrawItem(
loadArc( aSymbol, aReader ),
false );
3218 aSymbol->AddDrawItem(
loadCircle( aSymbol, aReader ),
false );
3222 aSymbol->AddDrawItem(
loadText( aSymbol, aReader, aMajorVersion,
3223 aMinorVersion ),
false );
3227 aSymbol->AddDrawItem(
loadRect( aSymbol, aReader ),
false );
3231 aSymbol->AddDrawItem(
loadPin( aSymbol, aReader ),
false );
3235 aSymbol->AddDrawItem(
loadPolyLine( aSymbol, aReader ),
false );
3239 aSymbol->AddDrawItem(
loadBezier( aSymbol, aReader ),
false );
3255 SCH_PARSE_ERROR(
"File ended prematurely loading symbol draw element.", aReader, line );
3260 const char** aOutput )
3262 switch (
parseChar( aReader, aLine, aOutput ) )
3267 default:
SCH_PARSE_ERROR(
"invalid fill type, expected f, F, or N", aReader, aLine );
3278 const char* line = aReader.
Line();
3280 wxCHECK_MSG(
strCompare(
"A", line, &line ),
nullptr,
"Invalid arc definition" );
3292 int angle1 =
parseInt( aReader, line, &line );
3293 int angle2 =
parseInt( aReader, line, &line );
3310 wxPoint arcStart, arcEnd;
3324 wxPoint arcStart( radius, 0 );
3325 wxPoint arcEnd( radius, 0 );
3342 if( !
TRANSFORM().MapAngles( &angle1, &angle2 ) )
3356 const char* line = aReader.
Line();
3358 wxCHECK_MSG(
strCompare(
"C", line, &line ),
nullptr,
"Invalid circle definition" );
3370 circle->
SetEnd( wxPoint( center.x + radius, center.y ) );
3387 const char* line = aReader.
Line();
3389 wxCHECK_MSG(
strCompare(
"T", line, &line ),
nullptr,
"Invalid LIB_TEXT definition" );
3393 text->SetTextAngle( (
double)
parseInt( aReader, line, &line ) );
3399 text->SetPosition( center );
3404 text->SetTextSize( size );
3423 str.Replace(
"~",
" " );
3426 if( !str.IsEmpty() )
3429 str.Replace(
"''",
"\"" );
3432 text->SetText( str );
3441 if(
LIB_VERSION( aMajorVersion, aMinorVersion ) > 0
3445 text->SetItalic(
true );
3446 else if( !
strCompare(
"Normal", line, &line ) )
3447 SCH_PARSE_ERROR(
"invalid text stype, expected 'Normal' or 'Italic'", aReader, line );
3449 if(
parseInt( aReader, line, &line ) > 0 )
3450 text->SetBold(
true );
3455 switch(
parseChar( aReader, line, &line ) )
3460 default:
SCH_PARSE_ERROR(
"invalid horizontal text justication; expected L, C, or R",
3464 switch(
parseChar( aReader, line, &line ) )
3469 default:
SCH_PARSE_ERROR(
"invalid vertical text justication; expected T, C, or B",
3482 const char* line = aReader.
Line();
3484 wxCHECK_MSG(
strCompare(
"S", line, &line ),
nullptr,
"Invalid rectangle definition" );
3498 rectangle->
SetEnd( end );
3514 const char* line = aReader.
Line();
3516 wxCHECK_MSG(
strCompare(
"X", line, &line ),
nullptr,
"Invalid LIB_PIN definition" );
3523 wxString utf8Line = wxString::FromUTF8( line );
3524 wxStringTokenizer tokens( utf8Line,
" \r\n\t" );
3526 if( tokens.CountTokens() < 11 )
3529 tmp = tokens.GetNextToken();
3531 pos += tmp.size() + 1;
3533 tmp = tokens.GetNextToken();
3535 pos += tmp.size() + 1;
3540 tmp = tokens.GetNextToken();
3542 if( !tmp.ToLong( &num ) )
3546 pos += tmp.size() + 1;
3547 position.x =
Mils2Iu( (
int) num );
3549 tmp = tokens.GetNextToken();
3551 if( !tmp.ToLong( &num ) )
3555 pos += tmp.size() + 1;
3556 position.y =
Mils2Iu( (
int) num );
3558 tmp = tokens.GetNextToken();
3560 if( !tmp.ToLong( &num ) )
3564 pos += tmp.size() + 1;
3565 int length =
Mils2Iu( (
int) num );
3568 tmp = tokens.GetNextToken();
3570 if( tmp.size() > 1 )
3574 pos += tmp.size() + 1;
3575 int orientation = tmp[0];
3577 tmp = tokens.GetNextToken();
3579 if( !tmp.ToLong( &num ) )
3583 pos += tmp.size() + 1;
3584 int numberTextSize =
Mils2Iu( (
int) num );
3586 tmp = tokens.GetNextToken();
3588 if( !tmp.ToLong( &num ) )
3592 pos += tmp.size() + 1;
3593 int nameTextSize =
Mils2Iu( (
int) num );
3595 tmp = tokens.GetNextToken();
3597 if( !tmp.ToLong( &num ) )
3601 pos += tmp.size() + 1;
3602 int unit = (int) num;
3604 tmp = tokens.GetNextToken();
3606 if( !tmp.ToLong( &num ) )
3610 pos += tmp.size() + 1;
3613 tmp = tokens.GetNextToken();
3615 if( tmp.size() != 1 )
3619 pos += tmp.size() + 1;
3655 if( tokens.HasMoreTokens() )
3657 tmp = tokens.GetNextToken();
3663 LOWLEVEL_IN = 1 << 2,
3664 LOWLEVEL_OUT = 1 << 3,
3665 FALLING_EDGE = 1 << 4,
3671 for(
int j = tmp.size(); j > 0; )
3673 switch( tmp[--j].GetValue() )
3676 case 'N':
pin->SetVisible(
false );
break;
3677 case 'I': flags |=
INVERTED;
break;
3678 case 'C': flags |=
CLOCK;
break;
3679 case 'L': flags |= LOWLEVEL_IN;
break;
3680 case 'V': flags |= LOWLEVEL_OUT;
break;
3681 case 'F': flags |= FALLING_EDGE;
break;
3682 case 'X': flags |=
NONLOGIC;
break;
3702 SCH_PARSE_ERROR(
"pin attributes do not define a valid pin shape", aReader, line );
3713 const char* line = aReader.
Line();
3715 wxCHECK_MSG(
strCompare(
"P", line, &line ),
nullptr,
"Invalid poly definition" );
3719 int points =
parseInt( aReader, line, &line );
3726 for(
int i = 0; i < points; i++ )
3743 const char* line = aReader.
Line();
3745 wxCHECK_MSG(
strCompare(
"B", line, &line ),
nullptr,
"Invalid Bezier definition" );
3747 int points =
parseInt( aReader, line, &line );
3749 wxCHECK_MSG( points == 4, NULL,
"Invalid Bezier curve definition" );
3781 const char* line = aReader.
Line();
3783 wxCHECK_RET(
strCompare(
"$FPLIST", line, &line ),
"Invalid footprint filter list" );
3787 wxArrayString footprintFilters;
3791 if(
strCompare(
"$ENDFPLIST", line, &line ) )
3793 aSymbol->SetFPFilters( footprintFilters );
3800 footprintFilters.Add( footprint );
3804 SCH_PARSE_ERROR(
"File ended prematurely while loading footprint filters.", aReader, line );
3816 auto formatter = std::make_unique<FILE_OUTPUTFORMATTER>( fn.GetFullPath() );
3818 formatter->Print( 0,
"#encoding utf-8\n");
3822 if( !it->second->IsRoot() )
3828 formatter->Print( 0,
"#\n#End Library\n" );
3848 wxCHECK_RET( aSymbol && aSymbol->
IsRoot(),
"Invalid LIB_SYMBOL pointer." );
3852 wxArrayString aliasNames;
3856 for(
auto entry : *aMap )
3861 aliasNames.Add( symbol->
GetName() );
3871 aFormatter.
Print( 0,
"DEF" );
3876 if( !reference.
GetText().IsEmpty() )
3879 aFormatter.
Print( 0,
" ~" );
3881 aFormatter.
Print( 0,
" %d %d %c %c %d %c %c\n",
3886 aSymbol->
IsPower() ?
'P' :
'N' );
3890 if( dateModified != 0 )
3892 int sec = dateModified & 63;
3893 int min = ( dateModified >> 6 ) & 63;
3894 int hour = ( dateModified >> 12 ) & 31;
3895 int day = ( dateModified >> 17 ) & 31;
3896 int mon = ( dateModified >> 22 ) & 15;
3897 int year = ( dateModified >> 26 ) + 1990;
3899 aFormatter.
Print( 0,
"Ti %d/%d/%d %d:%d:%d\n", year, mon, day, hour, min, sec );
3902 std::vector<LIB_FIELD*> fields;
3921 if( !fields[i]->GetText().IsEmpty() )
3923 fields[i]->SetId( fieldId++ );
3929 if( !aliasNames.IsEmpty() )
3931 aFormatter.
Print( 0,
"ALIAS" );
3933 for(
unsigned i = 0; i < aliasNames.GetCount(); i++ )
3934 aFormatter.
Print( 0,
" %s",
TO_UTF8( aliasNames[i] ) );
3936 aFormatter.
Print( 0,
"\n" );
3942 if( footprints.GetCount() != 0 )
3944 aFormatter.
Print( 0,
"$FPLIST\n" );
3946 for(
unsigned i = 0; i < footprints.GetCount(); i++ )
3947 aFormatter.
Print( 0,
" %s\n",
TO_UTF8( footprints[i] ) );
3949 aFormatter.
Print( 0,
"$ENDFPLIST\n" );
3958 aFormatter.
Print( 0,
"DRAW\n" );
3962 switch( item.Type() )
3970 LIB_SHAPE& shape = static_cast<LIB_SHAPE&>( item );
3985 aFormatter.
Print( 0,
"ENDDRAW\n" );
3988 aFormatter.
Print( 0,
"ENDDEF\n" );
4007 aFormatter.
Print( 0,
"A %d %d %d %d %d %d %d %d %c %d %d %d %d\n",
4019 Iu2Mils( aArc->
GetEnd().x ),
4020 Iu2Mils( aArc->
GetEnd().y ) );
4028 aFormatter.
Print( 0,
"B %u %d %d %d",
4035 aFormatter.
Print( 0,
" %d %d", Iu2Mils( pt.x ), Iu2Mils( pt.y ) );
4045 aFormatter.
Print( 0,
"C %d %d %d %d %d %d %c\n",
4058 wxCHECK_RET( aField && aField->
Type() ==
LIB_FIELD_T,
"Invalid LIB_FIELD object." );
4060 int hjustify, vjustify;
4061 int id = aField->
GetId();
4078 aFormatter.
Print( 0,
"F%d %s %d %d %d %c %c %c %c%c%c",
4088 aField->
IsBold() ?
'B' :
'N' );
4100 aFormatter.
Print( 0,
"\n" );
4106 wxCHECK_RET( aPin && aPin->
Type() ==
LIB_PIN_T,
"Invalid LIB_PIN object." );
4126 if( !aPin->
GetName().IsEmpty() )
4129 aFormatter.
Print( 0,
"X ~" );
4131 aFormatter.
Print( 0,
" %s %d %d %d %c %d %d %d %d %c",
4144 aFormatter.
Print( 0,
" " );
4147 aFormatter.
Print( 0,
"N" );
4160 default: wxFAIL_MSG(
"Invalid pin shape" );
4163 aFormatter.
Print( 0,
"\n" );
4165 const_cast<LIB_PIN*>( aPin )->ClearFlags(
IS_CHANGED );
4173 aFormatter.
Print( 0,
"P %d %d %d %d",
4177 Iu2Mils( aPolyLine->
GetWidth() ) );
4180 aFormatter.
Print( 0,
" %d %d", Iu2Mils( pt.x ), Iu2Mils( pt.y ) );
4190 aFormatter.
Print( 0,
"S %d %d %d %d %d %d %d %c\n",
4193 Iu2Mils( aRectangle->
GetEnd().x ),
4194 Iu2Mils( aRectangle->
GetEnd().y ),
4204 wxCHECK_RET( aText && aText->
Type() ==
LIB_TEXT_T,
"Invalid LIB_TEXT object." );
4208 if(
text.Contains( wxT(
" " ) ) ||
text.Contains( wxT(
"~" ) ) ||
text.Contains( wxT(
"\"" ) ) )
4211 text.Replace( wxT(
"\"" ), wxT(
"''" ) );
4212 text = wxT(
"\"" ) +
text + wxT(
"\"" );
4220 aFormatter.
Print( 0,
" %s %d", aText->
IsItalic() ?
"Italic" :
"Normal", aText->
IsBold() );
4222 char hjustify =
'C';
4229 char vjustify =
'C';
4236 aFormatter.
Print( 0,
" %c %c\n", hjustify, vjustify );
4257 wxString description = it->second->GetDescription();
4258 wxString keyWords = it->second->GetKeyWords();
4259 wxString docFileName = it->second->GetDatasheetField().GetText();
4261 if( description.IsEmpty() && keyWords.IsEmpty() && docFileName.IsEmpty() )
4264 formatter.Print( 0,
"#\n$CMP %s\n",
TO_UTF8( it->second->GetName() ) );
4266 if( !description.IsEmpty() )
4267 formatter.Print( 0,
"D %s\n",
TO_UTF8( description ) );
4269 if( !keyWords.IsEmpty() )
4270 formatter.Print( 0,
"K %s\n",
TO_UTF8( keyWords ) );
4272 if( !docFileName.IsEmpty() )
4273 formatter.Print( 0,
"F %s\n",
TO_UTF8( docFileName ) );
4275 formatter.Print( 0,
"$ENDCMP\n" );
4278 formatter.Print( 0,
"#\n#End Doc Library\n" );
4284 LIB_SYMBOL_MAP::iterator it =
m_symbols.find( aSymbolName );
4299 LIB_SYMBOL_MAP::iterator it1 =
m_symbols.begin();
4303 if( it1->second->IsAlias()
4304 && it1->second->GetParent().lock() == rootSymbol->
SharedPtr() )
4352 if( aProperties && aProperties->find( propName ) != aProperties->end() )
4376 const wxString& aLibraryPath,
4381 bool powerSymbolsOnly = ( aProperties &&
4384 cacheLib( aLibraryPath, aProperties );
4388 for( LIB_SYMBOL_MAP::const_iterator it = symbols.begin(); it != symbols.end(); ++it )
4390 if( !powerSymbolsOnly || it->second->IsPower() )
4391 aSymbolNameList.Add( it->first );
4397 const wxString& aLibraryPath,
4402 bool powerSymbolsOnly = ( aProperties &&
4405 cacheLib( aLibraryPath, aProperties );
4409 for( LIB_SYMBOL_MAP::const_iterator it = symbols.begin(); it != symbols.end(); ++it )
4411 if( !powerSymbolsOnly || it->second->IsPower() )
4412 aSymbolList.push_back( it->second );
4418 const wxString& aSymbolName,
4423 cacheLib( aLibraryPath, aProperties );
4425 LIB_SYMBOL_MAP::const_iterator it =
m_cache->
m_symbols.find( aSymbolName );
4439 cacheLib( aLibraryPath, aProperties );
4453 cacheLib( aLibraryPath, aProperties );
4465 if( wxFileExists( aLibraryPath ) )
4468 aLibraryPath.GetData() ) );
4484 wxFileName fn = aLibraryPath;
4486 if( !fn.FileExists() )
4491 if( wxRemove( aLibraryPath ) )
4494 aLibraryPath.GetData() ) );
4529 wxTextFile tempFile;
4531 tempFile.Open( aFileName );
4534 firstline = tempFile.GetFirstLine();
4537 return firstline.StartsWith(
"EESchema" );
Field Reference of part, i.e. "IC21".
static LIB_TEXT * loadText(std::unique_ptr< LIB_SYMBOL > &aSymbol, LINE_READER &aReader, int aMajorVersion, int aMinorVersion)
wxString ConvertToNewOverbarNotation(const wxString &aOldStr)
Convert the old ~...~ overbar notation to the new ~{...} one.
SCH_SHEET * loadSheet(LINE_READER &aReader)
void CalcArcAngles(int &aStartAngle, int &aEndAngle) const
power input (GND, VCC for ICs). Must be connected to a power output.
#define TEXT_ANGLE_HORIZ
Frequent text rotations, used with {Set,Get}TextAngle(), in 0.1 degrees for now, hoping to migrate to...
LIB_FIELD * FindField(const wxString &aFieldName)
Find a field within this symbol matching aFieldName and returns it or NULL if not found.
void LoadContent(LINE_READER &aReader, SCH_SCREEN *aScreen, int version=EESCHEMA_VERSION)
EE_TYPE OfType(KICAD_T aType) const
static const char * GetLineStyleName(PLOT_DASH_TYPE aStyle)
SCH_JUNCTION * loadJunction(LINE_READER &aReader)
#define IS_CHANGED
Item was edited, and modified.
LIB_SYMBOL * LoadSymbol(const wxString &aLibraryPath, const wxString &aAliasName, const PROPERTIES *aProperties=nullptr) override
Load a LIB_SYMBOL object having aPartName from the aLibraryPath containing a library format that this...
Instances are attached to a symbol or sheet and provide a place for the symbol's value,...
void DeleteSymbol(const wxString &aName)
static LIB_SYMBOL * LoadPart(LINE_READER &aReader, int aMajorVersion, int aMinorVersion, LIB_SYMBOL_MAP *aMap=nullptr)
LIB_SYMBOL_REF & GetParent()
int GetPinNameOffset() const
~SCH_LEGACY_PLUGIN_CACHE()
COLOR4D GetLineColor() const
Returns COLOR4D::UNSPECIFIED if a custom color hasn't been set for this line.
std::map< wxString, LIB_SYMBOL *, LibSymbolMapSort > LIB_SYMBOL_MAP
Symbol map used by symbol library object.
const wxString & GetFileName() const
void AddPoint(const wxPoint &aPosition)
LIB_SYMBOL_SPTR SharedPtr() const
An abstract class from which implementation specific LINE_READERs may be derived to read single lines...
const std::vector< wxPoint > & GetBezierPoints() const
timestamp_t GetLastModDate() const
static void saveCircle(LIB_SHAPE *aCircle, OUTPUTFORMATTER &aFormatter)
char * ReadLine() override
Read a line of text into the buffer and increments the line number counter.
SCH_SHEET * Load(const wxString &aFileName, SCHEMATIC *aSchematic, SCH_SHEET *aAppendToMe=nullptr, const PROPERTIES *aProperties=nullptr) override
Load information from some input file format that this SCH_PLUGIN implementation knows about,...
bool SearchHierarchy(const wxString &aFilename, SCH_SCREEN **aScreen)
Search the existing hierarchy for an instance of screen loaded from aFileName.
char * Line() const
Return a pointer to the last line that was read in.
EDA_TEXT_VJUSTIFY_T GetVertJustify() const
bool IsGraphicLine() const
Return if the line is a graphic (non electrical line)
virtual void Report(const wxString &aMessage)=0
Display aMessage in the progress bar dialog.
virtual size_t GetPointCount() const override
static wxString FROM_UTF8(const char *cstring)
Convert a UTF8 encoded C string to a wxString for all wxWidgets build modes.
void SetVirtualPageNumber(int aPageNumber)
static void saveBezier(LIB_SHAPE *aBezier, OUTPUTFORMATTER &aFormatter)
virtual const wxString & GetSource() const
Returns the name of the source of the lines in an abstract sense.
void SetEnd(const wxPoint &aEnd)
Instantiate the current locale within a scope in which you are expecting exceptions to be thrown.
wxPoint GetStartPoint() const
SCH_FIELD * GetField(MANDATORY_FIELD_T aFieldType)
Return a mandatory field in this symbol.
int GetPenSizeForBold(int aTextSize)
wxString m_error
For throwing exceptions or errors on partial schematic loads.
static bool strCompare(const char *aString, const char *aLine, const char **aOutput=nullptr)
Compare aString to the string starting at aLine and advances the character point to the end of String...
static void saveRectangle(LIB_SHAPE *aRectangle, OUTPUTFORMATTER &aFormatter)
Holds all the data relating to one schematic.
wxPoint GetPosition() const override
const wxPoint & GetStart() const
Return the starting point of the graphic.
void SetRevision(const wxString &aRevision)
wxString GetName() const override
Define a symbol library graphical text item.
void saveLine(SCH_LINE *aLine)
int GetOrientation() const
const wxString & GetComment(int aIdx) const
int GetHeightMils() const
static void saveArc(LIB_SHAPE *aArc, OUTPUTFORMATTER &aFormatter)
GRAPHIC_PINSHAPE GetShape() const
static void parseUnquotedString(wxString &aString, LINE_READER &aReader, const char *aCurrentToken, const char **aNextToken=nullptr, bool aCanBeEmpty=false)
Parse an unquoted utf8 string and updates the pointer at aOutput if it is not NULL.
SCH_LEGACY_PLUGIN_CACHE * m_cache
static void savePolyLine(LIB_SHAPE *aPolyLine, OUTPUTFORMATTER &aFormatter)
static void loadAliases(std::unique_ptr< LIB_SYMBOL > &aSymbol, LINE_READER &aReader, LIB_SYMBOL_MAP *aMap=nullptr)
void SetItalic(bool isItalic)
Field object used in symbol libraries.
virtual ~SCH_LEGACY_PLUGIN()
void SetScreen(SCH_SCREEN *aScreen)
Set the SCH_SCREEN associated with this sheet to aScreen.
const wxChar *const traceSchLegacyPlugin
Flag to enable legacy schematic plugin debug output.
int GetVirtualPageNumber() const
pin for passive symbols: must be connected, and can be connected to any pin
bool IsValid() const
A simple test if the schematic is loaded, not a complete one.
void GetFields(std::vector< SCH_FIELD * > &aVector, bool aVisibleOnly)
Populate a std::vector with SCH_FIELDs.
void SetTextPos(const wxPoint &aPoint)
void AddSymbol(const LIB_SYMBOL *aSymbol)
bool ShowPinNumbers() const
void init(SCHEMATIC *aSchematic, const PROPERTIES *aProperties=nullptr)
initialize PLUGIN like a constructor would.
bool SetType(const wxString &aStandardPageDescriptionName, bool aIsPortrait=false)
Set the name of the page type and also the sizes and margins commonly associated with that type name.
SCH_SHEET * m_rootSheet
The root sheet of the schematic being loaded.
wxString GetLogicalName() const
double GetTextAngle() const
static uint32_t parseHex(LINE_READER &aReader, const char *aLine, const char **aOutput=nullptr)
Parse an ASCII hex integer string with possible leading whitespace into a long integer and updates th...
unknown electrical properties: creates always a warning when connected
void saveText(SCH_TEXT *aText)
void SetDate(const wxString &aDate)
Set the date field, and defaults to the current time and date.
const TITLE_BLOCK & GetTitleBlock() const
SCH_LEGACY_PLUGIN_CACHE(const wxString &aLibraryPath)
void SetPageSettings(const PAGE_INFO &aPageSettings)
#define MAX_UNIT_COUNT_PER_PACKAGE
The maximum number of units per package.
static const wxChar Custom[]
"User" defined page type
const wxString & GetType() const
void SetTextSize(const wxSize &aNewSize)
wxString GetFileName() const
void saveNoConnect(SCH_NO_CONNECT *aNoConnect)
void SetFileExists(bool aFileExists)
static double parseDouble(LINE_READER &aReader, const char *aLine, const char **aOutput=nullptr)
Parses an ASCII point string with possible leading whitespace into a double precision floating point ...
LIB_FIELD & GetValueField()
Return reference to the value field.
void RotatePoint(int *pX, int *pY, double angle)
void NORMALIZE_ANGLE_POS(T &Angle)
wxPoint GetPosition() const override
A logical library item identifier and consists of various portions much like a URI.
#define LIB_VERSION_MINOR
bool empty(int aType=UNDEFINED_TYPE) const
int GetTextThickness() const
A name/value tuple with unique names and optional values.
void loadHeader(FILE_LINE_READER &aReader)
std::string toUTFTildaText(const wxString &txt)
Convert a wxString to UTF8 and replace any control characters with a ~, where a control character is ...
SCH_SCREEN * GetScreen() const
Define a library symbol object.
std::chrono::steady_clock CLOCK
static void IncrementModifyHash()
Hold the information shown in the lower right corner of a plot, printout, or editing view.
const PAGE_INFO & GetPageSettings() const
TRANSFORM & GetTransform()
virtual const wxString GetProjectPath() const
Return the full path of the project.
#define SCH_LAYER_ID_COUNT
LIB_FIELD & GetReferenceField()
Return reference to the reference designator field.
void saveSheet(SCH_SHEET *aSheet)
void SetBezierC1(const wxPoint &aPt)
SCH_BUS_ENTRY_BASE * loadBusEntry(LINE_READER &aReader)
virtual void SetParent(EDA_ITEM *aParent)
virtual EDA_ITEM * Clone() const
Create a duplicate of this item with linked list members set to NULL.
The base class for drawable items used by schematic library symbols.
void GetFields(std::vector< LIB_FIELD * > &aList)
Return a list of fields within this symbol.
A cache assistant for the symbol library portion of the SCH_PLUGIN API, and only for the SCH_LEGACY_P...
void saveField(SCH_FIELD *aField)
unsigned m_lastProgressLine
static void FormatPart(LIB_SYMBOL *aSymbol, OUTPUTFORMATTER &aFormatter)
Base class for a bus or wire entry.
const std::vector< SYMBOL_INSTANCE_REFERENCE > & GetInstanceReferences()
void saveJunction(SCH_JUNCTION *aJunction)
int m_version
Version of file being loaded.
void loadFile(const wxString &aFileName, SCH_SCREEN *aScreen)
#define SCHEMATIC_HEAD_STRING
void saveSymbol(SCH_SYMBOL *aSymbol)
void SetStart(const wxPoint &aStart)
void Rewind()
Rewind the file and resets the line number back to zero.
std::vector< SCH_FIELD > & GetFields()
void DeleteSymbol(const wxString &aLibraryPath, const wxString &aSymbolName, const PROPERTIES *aProperties=nullptr) override
Delete the entire LIB_SYMBOL associated with aAliasName from the library aLibraryPath.
void SetPosition(const wxPoint &aPosition) override
void SetFileReadOnly(bool aIsReadOnly)
wxString m_path
Root project path for loading child sheets.
#define TO_UTF8(wxstring)
Convert a wxString to a UTF8 encoded C string for all wxWidgets build modes.
static LIB_PIN * loadPin(std::unique_ptr< LIB_SYMBOL > &aSymbol, LINE_READER &aReader)
virtual void SetVisible(bool aVisible)
PLOT_DASH_TYPE GetDefaultStyle() const
A LINE_READER that reads from an open file.
const wxPoint & GetEnd() const
Return the ending point of the graphic.
#define THROW_PARSE_ERROR(aProblem, aSource, aInputLine, aLineNumber, aByteIndex)
bool isBuffering(const PROPERTIES *aProperties)
EDA_TEXT_HJUSTIFY_T GetHorizJustify() const
Field Value of part, i.e. "3.3K".
virtual void SetText(const wxString &aText)
void SetComment(int aIdx, const wxString &aComment)
static void loadDrawEntries(std::unique_ptr< LIB_SYMBOL > &aSymbol, LINE_READER &aReader, int aMajorVersion, int aMinorVersion)
void loadHierarchy(SCH_SHEET *aSheet)
virtual const wxString What() const
A composite of Problem() and Where()
const std::vector< VECTOR2I > & CPoints() const
BITMAP_BASE * GetImage() const
SCH_LAYER_ID
Eeschema drawing layers.
static LIB_SHAPE * loadPolyLine(std::unique_ptr< LIB_SYMBOL > &aSymbol, LINE_READER &aReader)
virtual unsigned LineNumber() const
Return the line number of the last line read from this LINE_READER.
const wxString & GetRevision() const
wxPoint GetPosition() const override
timestamp_t AsLegacyTimestamp() const
const wxString & GetName() const
PLOT_DASH_TYPE GetLineStyle() const
SHAPE_LINE_CHAIN & Outline(int aIndex)
virtual bool IsVisible() const
Describe the page size and margins of a paper page on which to eventually print or plot.
const wxSize & GetTextSize() const
void SetVertJustify(EDA_TEXT_VJUSTIFY_T aType)
const wxString & GetCompany() const
int GetUnitCount() const override
For items with units, return the number of units.
int GetFieldCount() const
Return the number of fields in this symbol.
static bool is_eol(char c)
static void ResolvePossibleSymlinks(wxFileName &aFilename)
#define LIB_VERSION_MAJOR
wxString GetCanonicalName() const
Get a non-language-specific name for a field which can be used for storage, variable look-up,...
void SetDescription(const wxString &aDescription)
void cacheLib(const wxString &aLibraryFileName, const PROPERTIES *aProperties)
static void IncrementModifyGeneration()
void SetCompany(const wxString &aCompany)
A simple container for schematic symbol instance information.
Definition for symbol library class.
void loadPageSettings(LINE_READER &aReader, SCH_SCREEN *aScreen)
void Save(const wxString &aFileName, SCH_SHEET *aScreen, SCHEMATIC *aSchematic, const PROPERTIES *aProperties=nullptr) override
Write aSchematic to a storage file in a format that this SCH_PLUGIN implementation knows about,...
bool ShowPinNames() const
wxLogTrace helper definitions.
static int parseInt(LINE_READER &aReader, const char *aLine, const char **aOutput=nullptr)
Parse an ASCII integer string with possible leading whitespace into an integer and updates the pointe...
#define USE_OLD_DOC_FILE_FORMAT(major, minor)
void SetWidth(int aWidth)
void AddDrawItem(LIB_ITEM *aItem, bool aSort=true)
Add a new draw aItem to the draw object list and sort according to aSort.
void saveBitmap(SCH_BITMAP *aBitmap)
wxPoint GetLibPosition() const
void SetParent(LIB_SYMBOL *aParent=nullptr)
LABEL_SPIN_STYLE GetLabelSpinStyle() const
static const char * PropNoDocFile
The property used internally by the plugin to disable writing the library documentation (....
static LIB_SYMBOL * ParsePart(LINE_READER &aReader, int majorVersion=0, int minorVersion=0)
Define a sheet pin (label) used in sheets to create hierarchical schematics.
static const wxString GetDefaultFieldName(int aFieldNdx, bool aTranslate=true)
Return a default symbol field name for field aFieldNdx for all components.
int GetNameTextSize() const
wxPoint GetCenter() const
wxString GetFileName() const
Return the filename corresponding to this sheet.
int SetLibItemName(const UTF8 &aLibItemName)
Override the library item name portion of the LIB_ID to aLibItemName.
void SetModified(bool aModified=true)
void SetTitleBlock(const TITLE_BLOCK &aTitleBlock)
wxPoint GetPosition() const override
wxPoint GetPosition() const override
void SetTitle(const wxString &aTitle)
LIB_ITEMS_CONTAINER & GetDrawItems()
Return a reference to the draw item list.
static PLOT_DASH_TYPE GetLineStyleByName(const wxString &aStyleName)
Object to handle a bitmap image that can be inserted in a schematic.
void SetHeightMils(int aHeightInMils)
SHAPE_POLY_SET & GetPolyShape()
void SaveLibrary(const wxString &aLibraryPath, const PROPERTIES *aProperties=nullptr) override
wxString UnescapeString(const wxString &aSource)
bool UnitsLocked() const
Check whether symbol units are interchangeable.
bool CheckHeader(const wxString &aFileName) override
Return true if the first line in aFileName begins with the expected header.
static void SaveSymbol(LIB_SYMBOL *aSymbol, OUTPUTFORMATTER &aFormatter, LIB_SYMBOL_MAP *aMap=nullptr)
Sheet symbol placed in a schematic, and is the entry point for a sub schematic.
PLOT_DASH_TYPE
Dashed line types.
PROJECT & Prj() const override
Return a reference to the project this schematic is part of.
void SetConvert(int aConvert)
wxPoint GetPosition() const override
void Format(SCH_SHEET *aSheet)
virtual unsigned int GetSize() const override
Return the number of stored items.
SCH_LAYER_ID GetLayer() const
Return the layer this item is on.
void SetFileName(const wxString &aFileName)
std::vector< SCH_SHEET_PIN * > & GetPins()
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Output a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
void SetContentModified(bool aModified=true)
The first 4 are mandatory, and must be instantiated in SCH_COMPONENT and LIB_PART constructors.
SCH_BITMAP * loadBitmap(LINE_READER &aReader)
static void saveText(const LIB_TEXT *aText, OUTPUTFORMATTER &aFormatter)
uint32_t timestamp_t
timestamp_t is our type to represent unique IDs for all kinds of elements; historically simply the ti...
static void loadField(std::unique_ptr< LIB_SYMBOL > &aSymbol, LINE_READER &aReader)
static void savePin(const LIB_PIN *aPin, OUTPUTFORMATTER &aFormatter)
bool IsFile(const wxString &aFullPathAndFileName) const
static LIB_SHAPE * loadCircle(std::unique_ptr< LIB_SYMBOL > &aSymbol, LINE_READER &aReader)
const wxString & GetDate() const
void RebuildBezierToSegmentsPointsList(int aMinSegLen)
Rebuild the m_bezierPoints vertex list that approximate the Bezier curve by a list of segments.
const wxString & GetNumber() const
ELECTRICAL_PINTYPE GetType() const
static void saveField(const LIB_FIELD *aField, OUTPUTFORMATTER &aFormatter)
std::unordered_set< std::shared_ptr< BUS_ALIAS > > GetBusAliases() const
Return a list of bus aliases defined in this screen.
int Parse(const UTF8 &aId, bool aFix=false)
Parse LIB_ID with the information from aId.
LIB_FIELD * GetFieldById(int aId) const
Return pointer to the requested field.
int GetNumberTextSize() const
bool Exists(const std::string &aProperty) const
virtual char * ReadLine()=0
Read a line of text into the buffer and increments the line number counter.
#define SCH_PARSE_ERROR(text, reader, pos)
wxString AsLegacyTimestampString() const
void saveBusAlias(std::shared_ptr< BUS_ALIAS > aAlias)
void AddBusAlias(std::shared_ptr< BUS_ALIAS > aAlias)
Add a bus alias definition (and transfers ownership of the pointer).
Segment description base class to describe items which have 2 end points (track, wire,...
static LIB_SHAPE * loadRect(std::unique_ptr< LIB_SYMBOL > &aSymbol, LINE_READER &aReader)
OUTPUTFORMATTER * m_out
The formatter for saving SCH_SCREEN objects.
ELECTRICAL_PINTYPE
The symbol library pin object electrical types used in ERC tests.
void Append(SCH_ITEM *aItem)
const std::map< PINSHEETLABEL_SHAPE, const char * > sheetLabelNames
virtual KIGFX::VIEW_ITEM * GetItem(unsigned int aIdx) const override
void SetHorizJustify(EDA_TEXT_HJUSTIFY_T aType)
usual pin input: must be connected
LINE_READER * m_lineReader
for progress reporting
PROGRESS_REPORTER * m_progressReporter
optional; may be nullptr
void CreateSymbolLib(const wxString &aLibraryPath, const PROPERTIES *aProperties=nullptr) override
Create a new empty symbol library at aLibraryPath.
wxString GetName(bool aUseDefaultName=true) const
Return the field name.
unsigned m_lineCount
for progress reporting
static FILL_T parseFillMode(LINE_READER &aReader, const char *aLine, const char **aOutput)
EE_RTREE & Items()
Gets the full RTree, usually for iterating.
void SetWidthMils(int aWidthInMils)
static char parseChar(LINE_READER &aReader, const char *aCurrentToken, const char **aNextToken=nullptr)
Parse a single ASCII character and updates the pointer at aOutput if it is not NULL.
void SetName(const wxString &aName)
wxString GetPrefix() const
void SaveSymbol(const wxString &aLibraryPath, const LIB_SYMBOL *aSymbol, const PROPERTIES *aProperties=nullptr) override
Write aSymbol to an existing library located at aLibraryPath.
wxPoint GetPosition() const override
static const char * PropBuffering
The property used internally by the plugin to enable cache buffering which prevents the library file ...
void SetBezierC2(const wxPoint &aPt)
wxArrayString GetFPFilters() const
int GetModifyHash() const override
Return the modification hash from the library cache.
SCH_NO_CONNECT * loadNoConnect(LINE_READER &aReader)
wxDateTime GetLibModificationTime()
const wxPoint & GetTextPos() const
void SetPosition(const wxPoint &aPosition) override
static void parseQuotedString(wxString &aString, LINE_READER &aReader, const char *aCurrentToken, const char **aNextToken=nullptr, bool aCanBeEmpty=false)
Parse an quoted ASCII utf8 and updates the pointer at aOutput if it is not NULL.
virtual bool KeepRefreshing(bool aWait=false)=0
Update the UI (if any).
static LIB_SHAPE * loadArc(std::unique_ptr< LIB_SYMBOL > &aSymbol, LINE_READER &aReader)
const wxString & GetTitle() const
input or output (like port for a microprocessor)
void SetFillMode(FILL_T aFill)
bool IsRoot() const override
For symbols derived from other symbols, IsRoot() indicates no derivation.
void loadHeader(LINE_READER &aReader, SCH_SCREEN *aScreen)
std::string EscapedUTF8(const wxString &aString)
Return an 8 bit UTF8 string given aString in Unicode form.
static std::mutex s_modHashMutex
static LIB_SHAPE * loadBezier(std::unique_ptr< LIB_SYMBOL > &aSymbol, LINE_READER &aReader)
virtual void SetTextAngle(double aAngle)
SCH_LINE * loadWire(LINE_READER &aReader)
wxString EscapeString(const wxString &aSource, ESCAPE_CONTEXT aContext)
The Escape/Unescape routines use HTML-entity-reference-style encoding to handle characters which are:...
void SetFileName(const wxString &aFileName)
Set the file name for this screen to aFileName.
wxString m_name
Name (not the field text value itself, that is #EDA_TEXT::m_Text)
not connected (must be left open)
SCH_TEXT * loadText(LINE_READER &aReader)
wxPoint GetPosition() const override
static int GetModifyHash()
bool IsFileChanged() const
LIB_SYMBOL * removeSymbol(LIB_SYMBOL *aAlias)
bool IsSymbolLibWritable(const wxString &aLibraryPath) override
Return true if the library at aLibraryPath is writable.
void SetPageCount(int aPageCount)
void SetPortrait(bool aIsPortrait)
Rotate the paper page 90 degrees.
void Save(bool aSaveDocFile=true)
Save the entire library to file m_libFileName;.
Hold an error message and may be used when throwing exceptions containing meaningful error messages.
Base class for any item which can be embedded within the SCHEMATIC container class,...
#define THROW_IO_ERROR(msg)
SCH_SYMBOL * loadSymbol(LINE_READER &aReader)
output of a regulator: intended to be connected to power input pins
void saveBusEntry(SCH_BUS_ENTRY_BASE *aBusEntry)
virtual const wxString & GetText() const
Return the string associated with the text object.
static void loadFootprintFilters(std::unique_ptr< LIB_SYMBOL > &aSymbol, LINE_READER &aReader)
static const char * PropPowerSymsOnly
void SetKeyWords(const wxString &aKeyWords)
FILL_T GetFillType() const
bool writeDocFile(const PROPERTIES *aProperties)
wxFileName GetRealFile() const
void EnumerateSymbolLib(wxArrayString &aSymbolNameList, const wxString &aLibraryPath, const PROPERTIES *aProperties=nullptr) override
Populate a list of LIB_SYMBOL alias names contained within the library aLibraryPath.
PINSHEETLABEL_SHAPE GetShape() const
KICAD_T Type() const
Returns the type of object.
std::shared_ptr< BUS_ALIAS > loadBusAlias(LINE_READER &aReader, SCH_SCREEN *aScreen)
const LIB_ID & GetLibId() const
bool DeleteSymbolLib(const wxString &aLibraryPath, const PROPERTIES *aProperties=nullptr) override
Delete an existing symbol library and returns true if successful, or if library does not exist return...
#define LIB_VERSION(major, minor)
wxPoint GetPosition() const override
virtual void SetCurrentProgress(double aProgress)=0
Set the progress value to aProgress (0..1).
std::stack< wxString > m_currentPath
Stack to maintain nested sheet paths.
wxPoint GetEndPoint() const