25#include <fmt/format.h>
26#include <magic_enum.hpp>
30#include <wx/mstream.h>
43#include <schematic_lexer.h>
72using namespace TSCHEMATIC_T;
75#define SCH_PARSE_ERROR( text, reader, pos ) \
76 THROW_PARSE_ERROR( text, reader.GetSource(), reader.Line(), \
77 reader.LineNumber(), pos - reader.Line() )
93 const std::map<std::string, UTF8>* aProperties )
100 m_sheetLoad = aProperties && aProperties->count(
"hierarchical_sheet_load" );
110 const std::map<std::string, UTF8>* aProperties )
112 wxASSERT( !aFileName || aSchematic !=
nullptr );
116 wxFileName fn = aFileName;
124 wxASSERT( fn.IsAbsolute() );
133 if( !normedFn.IsAbsolute() )
135 if( aFileName.Right( normedFn.GetFullPath().Length() ) == normedFn.GetFullPath() )
136 m_path = aFileName.Left( aFileName.Length() - normedFn.GetFullPath().Length() );
150 init( aSchematic, aProperties );
153 if( aAppendToMe ==
nullptr )
156 std::unique_ptr<SCH_SHEET> newSheet = std::make_unique<SCH_SHEET>( aSchematic );
158 wxFileName relPath( aFileName );
164 newSheet->SetFileName( relPath.GetFullPath() );
169 sheet = newSheet.release();
175 wxCHECK_MSG( aSchematic->
IsValid(),
nullptr,
"Can't append to a schematic with no root!" );
206 if( !fileName.IsAbsolute() )
215 wxLogTrace(
traceSchPlugin,
"Loading '%s'", fileName.GetFullPath() );
219 while( !ancestorSheetPath.
empty() )
226 m_error += wxString::Format(
_(
"Could not load sheet '%s' because it already "
227 "appears as a direct ancestor in the schematic "
229 fileName.GetFullPath() );
231 fileName = wxEmptyString;
239 if( ancestorSheetPath.
empty() )
243 if( !
m_rootSheet->SearchHierarchy( fileName.GetFullPath(), &screen ) )
252 if( prevRoot->SearchHierarchy( fileName.GetFullPath(), &screen ) )
271 loadFile( fileName.GetFullPath(), aSheet );
286 if( fileName.FileExists() )
324 size_t lineCount = 0;
351 std::map<wxString, CONNECTION_GRAPH::CHAIN_TERMINAL_REFS> termRefs;
355 termRefs[
name] = { { terms.first.ref, terms.first.pin }, { terms.second.ref, terms.second.pin } };
358 m_schematic->ConnectionGraph()->SetNetChainTerminalRefOverrides( termRefs );
377 std::map<wxString, CONNECTION_GRAPH::CHAIN_TERMINAL_REFS> termRefs;
381 termRefs[
name] = { { terms.first.ref, terms.first.pin }, { terms.second.ref, terms.second.pin } };
384 m_schematic->ConnectionGraph()->SetNetChainTerminalRefOverrides( termRefs );
392 const std::map<std::string, UTF8>* aProperties )
394 wxCHECK_RET( aSheet !=
nullptr,
"NULL SCH_SHEET object." );
395 wxCHECK_RET( !aFileName.IsEmpty(),
"No schematic file name defined." );
402 wxString::Format(
_(
"Please report this bug. Error validating group "
403 "structure: %s\n\nSave anyway?" ),
405 _(
"Save Anyway" ) ) )
411 wxFileName fn = aFileName;
415 wxASSERT( fn.IsAbsolute() );
428 const std::map<std::string, UTF8>* aProperties )
430 wxCHECK_RET( aSheet !=
nullptr,
"NULL SCH_SHEET object." );
432 init( aSchematic, aProperties );
444 wxCHECK_RET( aSheet !=
nullptr,
"NULL SCH_SHEET* object." );
445 wxCHECK_RET(
m_schematic !=
nullptr,
"NULL SCHEMATIC* object." );
458 m_schematic->GetEmbeddedFiles()->ClearEmbeddedFonts();
460 m_out->Print(
"(kicad_sch (version %d) (generator \"eeschema\") (generator_version %s)",
470 m_out->Print(
"(lib_symbols" );
472 for(
const auto& [ libItemName, libSymbol ] : screen->
GetLibSymbols() )
481 if( a->
Type() != b->Type() )
482 return a->
Type() < b->Type();
484 return a->
m_Uuid < b->m_Uuid;
487 std::multiset<
SCH_ITEM*,
decltype( cmp )> save_map( cmp );
493 save_map.insert( item );
498 switch( item->Type() )
558 wxASSERT(
"Unexpected schematic object type in SCH_IO_KICAD_SEXPR::Format()" );
567 m_schematic->NetChains().RefreshTerminalReferences();
569 for(
const auto& sigPtr :
m_schematic->NetChains().GetCommittedNetChains() )
592 m_out->Print(
" (color %d %d %d %s)",
601 std::vector<wxString> persistableNets;
603 for(
const wxString& n : sig.
GetNets() )
606 persistableNets.push_back( n );
609 if( !persistableNets.empty() )
611 m_out->Print(
" (nets" );
613 for(
const wxString& n : persistableNets )
614 m_out->Print(
" %s",
m_out->Quotew( n ).c_str() );
625 std::vector< SCH_SHEET_INSTANCE> instances;
651 wxCHECK( aSelection && aSelectionPath && aFormatter, );
658 std::map<wxString, LIB_SYMBOL*> libSymbols;
660 std::set<SCH_TABLE*> promotedTables;
677 libSymbols[ libSymbolLookup ] = it->second;
680 if( !libSymbols.empty() )
682 m_out->Print(
"(lib_symbols" );
684 for(
const auto& [
name, libSymbol] : libSymbols )
690 for(
EDA_ITEM* edaItem : *aSelection )
692 if( !edaItem->IsSCH_ITEM() )
697 switch( item->
Type() )
700 saveSymbol(
static_cast<SCH_SYMBOL*
>( item ), aSchematic, sheets, aForClipboard, aSelectionPath );
752 if( promotedTables.count(
table ) )
758 promotedTables.insert(
table );
772 wxASSERT(
"Unexpected schematic object type in SCH_IO_KICAD_SEXPR::Format()" );
783 const char* mode =
"library_default";
785 switch( aOverride.
m_Mode )
793 aOut->
Print(
"(pin_map_override (mode %s)", mode );
812 wxCHECK_RET( aSymbol !=
nullptr &&
m_out !=
nullptr,
"" );
818 if( symbol_name.size() )
824 libName =
"_NONAME_";
839 m_out->Print(
"(symbol" );
843 m_out->Print(
"(lib_name %s)",
847 m_out->Print(
"(lib_id %s) (at %s %s %s)",
858 if( mirrorX || mirrorY )
860 m_out->Print(
"(mirror %s %s)",
862 mirrorY ?
"y" :
"" );
873 wxASSERT( parentScreen );
877 std::optional<SCH_SHEET_PATH> ordinalPath =
878 m_schematic->Hierarchy().GetOrdinalPath( parentScreen );
885 aSymbol->
GetInstance( ordinalInstance, ordinalPath->Path() );
890 int unit = ordinalInstance.
m_Unit;
892 if( aForClipboard && aRelativePath )
897 unit = unitInstance.
m_Unit;
900 m_out->Print(
"(unit %d)", unit );
913 using magic_enum::enum_name;
916 std::transform(
name.begin(),
name.end(),
name.begin(), [](
unsigned char c ){ return (char) std::tolower( c ); } );
917 m_out->Print(
"(passthrough %s)",
name.c_str() );
930 std::vector<SCH_FIELD*> orderedFields;
931 aSymbol->
GetFields( orderedFields,
false );
936 wxString value = field->GetText();
945 else if( aForClipboard && aSymbol->
GetInstances().size() && aRelativePath
962 field->SetText( value );
968 field->SetText( value );
971 for(
const std::unique_ptr<SCH_PIN>&
pin : aSymbol->
GetRawPins() )
976 if(
pin->GetAlt().IsEmpty() || (
pin->GetAlt() ==
pin->GetBaseName() ) )
978 m_out->Print(
"(pin %s",
m_out->Quotew(
pin->GetNumber() ).c_str() );
984 m_out->Print(
"(pin %s",
m_out->Quotew(
pin->GetNumber() ).c_str() );
986 m_out->Print(
"(alternate %s))",
m_out->Quotew(
pin->GetAlt() ).c_str() );
992 std::map<KIID, std::vector<SCH_SYMBOL_INSTANCE>> projectInstances;
994 m_out->Print(
"(instances" );
996 wxString projectName;
1002 if( inst.m_Path.empty() )
1013 if( pathToCheck.empty() )
1021 if( !aForClipboard && isOrphaned )
1026 auto it = projectInstances.find(
projectKey );
1028 if( it == projectInstances.end() )
1031 it->second.emplace_back( inst );
1034 for(
auto& [uuid, instances] : projectInstances )
1036 wxCHECK2( instances.size(),
continue );
1039 std::sort( instances.begin(), instances.end(),
1042 return aLhs.m_Path < aRhs.m_Path;
1046 projectName =
m_schematic->Project().GetProjectName();
1048 projectName = instances[0].m_ProjectName;
1050 m_out->Print(
"(project %s",
m_out->Quotew( projectName ).c_str() );
1057 if( aForClipboard && aRelativePath )
1062 m_out->Print(
"(path %s (reference %s) (unit %d)",
1064 m_out->Quotew( instance.m_Reference ).c_str(),
1067 if( !instance.m_Variants.empty() )
1069 for(
const auto&[
name, variant] : instance.m_Variants )
1073 if( !variant.HasDifferentials( *aSymbol ) )
1076 m_out->Print(
"(variant (name %s)",
m_out->Quotew(
name ).c_str() );
1078 if( variant.m_DNP != aSymbol->
GetDNP() )
1093 for(
const auto&[fname, fvalue] : variant.m_Fields )
1095 m_out->Print(
"(field (name %s) (value %s))",
1096 m_out->Quotew( fname ).c_str(),
m_out->Quotew( fvalue ).c_str() );
1099 if( variant.m_SymbolOverride )
1101 m_out->Print(
"(symbol_override %s)",
1102 m_out->Quotew( variant.m_SymbolOverride->Format().wx_str() ).c_str() );
1107 m_out->Print(
")" );
1111 m_out->Print(
")" );
1114 m_out->Print(
")" );
1117 m_out->Print(
")" );
1121 m_out->Print(
")" );
1127 wxCHECK_RET( aField !=
nullptr &&
m_out !=
nullptr,
"" );
1135 m_out->Print(
"(property %s %s %s (at %s %s %s)",
1137 m_out->Quotew( fieldName ).c_str(),
1159 m_out->Print(
")" );
1165 wxCHECK_RET(
m_out !=
nullptr,
"" );
1172 wxCHECK_RET(
image !=
nullptr,
"wxImage* is NULL" );
1174 m_out->Print(
"(image (at %s %s)",
1195 wxMemoryOutputStream stream;
1201 m_out->Print(
")" );
1207 wxCHECK_RET( aSheet !=
nullptr &&
m_out !=
nullptr,
"" );
1209 m_out->Print(
"(sheet (at %s %s) (size %s %s)",
1237 m_out->Print(
"(fill (color %d %d %d %s))",
1250 m_out->Print(
"(pin %s %s (at %s %s %s)",
1254 pin->GetPosition().x ).c_str(),
1256 pin->GetPosition().y ).c_str(),
1263 m_out->Print(
")" );
1267 std::vector< SCH_SHEET_INSTANCE > sheetInstances = aSheet->
GetInstances();
1269 auto it = sheetInstances.begin();
1271 while( it != sheetInstances.end() )
1273 if( it->m_Path.size() == 0 )
1274 it = sheetInstances.erase( it );
1279 if( !sheetInstances.empty() )
1281 m_out->Print(
"(instances" );
1283 KIID lastProjectUuid;
1284 bool inProjectClause =
false;
1286 for(
size_t i = 0; i < sheetInstances.size(); i++ )
1293 bool belongsToThisProject =
m_schematic->IsInstancePathInProject( sheetInstances[i].m_Path );
1297 if( inProjectClause && ( ( i + 1 == sheetInstances.size() )
1298 || lastProjectUuid != sheetInstances[i+1].m_Path[0] ) )
1300 m_out->Print(
")" );
1301 inProjectClause =
false;
1307 if( lastProjectUuid != sheetInstances[i].m_Path[0] )
1309 wxString projectName;
1311 if( belongsToThisProject )
1312 projectName =
m_schematic->Project().GetProjectName();
1314 projectName = sheetInstances[i].m_ProjectName;
1316 lastProjectUuid = sheetInstances[i].m_Path[0];
1317 m_out->Print(
"(project %s",
m_out->Quotew( projectName ).c_str() );
1318 inProjectClause =
true;
1321 wxString
path = sheetInstances[i].m_Path.AsString();
1323 m_out->Print(
"(path %s (page %s)",
1325 m_out->Quotew( sheetInstances[i].m_PageNumber ).c_str() );
1327 if( !sheetInstances[i].m_Variants.empty() )
1329 for(
const auto&[
name, variant] : sheetInstances[i].m_Variants )
1333 if( !variant.HasDifferentials( *aSheet ) )
1336 m_out->Print(
"(variant (name %s)",
m_out->Quotew(
name ).c_str() );
1338 if( variant.m_DNP != aSheet->
GetDNP() )
1347 for(
const auto&[fname, fvalue] : variant.m_Fields )
1349 m_out->Print(
"(field (name %s) (value %s))",
1350 m_out->Quotew( fname ).c_str(),
m_out->Quotew( fvalue ).c_str() );
1353 m_out->Print(
")" );
1357 m_out->Print(
")" );
1359 if( inProjectClause && ( ( i + 1 == sheetInstances.size() )
1360 || lastProjectUuid != sheetInstances[i+1].m_Path[0] ) )
1362 m_out->Print(
")" );
1363 inProjectClause =
false;
1367 m_out->Print(
")" );
1371 m_out->Print(
")" );
1377 wxCHECK_RET( aJunction !=
nullptr &&
m_out !=
nullptr,
"" );
1379 m_out->Print(
"(junction (at %s %s) (diameter %s) (color %d %d %d %s)",
1397 m_out->Print(
")" );
1403 wxCHECK_RET( aNoConnect !=
nullptr &&
m_out !=
nullptr,
"" );
1405 m_out->Print(
"(no_connect (at %s %s)",
1417 m_out->Print(
")" );
1423 wxCHECK_RET( aBusEntry !=
nullptr &&
m_out !=
nullptr,
"" );
1426 if( aBusEntry->
GetClass() ==
"SCH_BUS_BUS_ENTRY" )
1435 m_out->Print(
"(bus_entry (at %s %s) (size %s %s)",
1443 aBusEntry->
GetSize().
y ).c_str() );
1452 m_out->Print(
")" );
1458 wxCHECK_RET( aShape !=
nullptr &&
m_out !=
nullptr,
"" );
1493 aShape->
m_Uuid, writeLocked );
1498 false, aShape->
m_Uuid, writeLocked );
1509 wxCHECK_RET( aRuleArea !=
nullptr &&
m_out !=
nullptr,
"" );
1511 m_out->Print(
"(rule_area " );
1524 m_out->Print(
")" );
1530 wxCHECK_RET( aLine !=
nullptr &&
m_out !=
nullptr,
"" );
1538 case LAYER_BUS: lineType =
"bus";
break;
1545 m_out->Print(
"(%s (pts (xy %s %s) (xy %s %s))",
1570 m_out->Print(
")" );
1576 wxCHECK_RET( aText !=
nullptr &&
m_out !=
nullptr,
"" );
1581 m_out->Print(
"(%s %s",
1592 m_out->Print(
"(length %s)",
1594 flag->GetPinLength() ).c_str() );
1620 m_out->Print(
"(at %s %s %s)",
1627 if( label && !label->
GetFields().empty() )
1635 aText->EDA_TEXT::Format(
m_out, 0 );
1648 m_out->Print(
")" );
1654 wxCHECK_RET( aTextBox !=
nullptr &&
m_out !=
nullptr,
"" );
1656 m_out->Print(
"(%s %s",
1665 m_out->Print(
"(at %s %s %s) (size %s %s) (margins %s %s %s %s)",
1677 m_out->Print(
"(span %d %d)", cell->GetColSpan(), cell->GetRowSpan() );
1683 aTextBox->EDA_TEXT::Format(
m_out, 0 );
1690 m_out->Print(
")" );
1705 for(
int row = 0; row < aTable->
GetRowCount(); ++row )
1707 for(
int col = 0; col < aTable->
GetColCount(); ++col )
1713 minRow = std::min( minRow, row );
1714 maxRow = std::max( maxRow, row );
1715 minCol = std::min( minCol, col );
1716 maxCol = std::max( maxCol, col );
1725 wxCHECK_MSG( maxCol >= minCol && maxRow >= minRow, , wxT(
"No selected cells!" ) );
1729 for(
int row = minRow; row <= maxRow; row++ )
1734 for(
int col = minCol; col <= maxCol; col++ )
1741 wxCHECK_RET( aTable !=
nullptr &&
m_out !=
nullptr,
"" );
1745 m_out->Print(
"(border" );
1752 m_out->Print(
")" );
1754 m_out->Print(
"(separators" );
1761 m_out->Print(
")" );
1763 m_out->Print(
"(column_widths" );
1765 for(
int col = 0; col < aTable->
GetColCount(); ++col )
1767 m_out->Print(
" %s",
1771 m_out->Print(
")" );
1773 m_out->Print(
"(row_heights" );
1775 for(
int row = 0; row < aTable->
GetRowCount(); ++row )
1777 m_out->Print(
" %s",
1781 m_out->Print(
")" );
1788 m_out->Print(
"(cells" );
1793 m_out->Print(
")" );
1796 m_out->Print(
")" );
1819 wxArrayString memberIds;
1822 memberIds.Add( member->m_Uuid.AsString() );
1826 m_out->Print(
"(members" );
1828 for(
const wxString& memberId : memberIds )
1829 m_out->Print(
" %s",
m_out->Quotew( memberId ).c_str() );
1831 m_out->Print(
")" );
1834 m_out->Print(
")" );
1840 if( aInstances.size() )
1842 m_out->Print(
"(sheet_instances" );
1846 wxString
path = instance.m_Path.AsString();
1848 if(
path.IsEmpty() )
1851 m_out->Print(
"(path %s (page %s))",
1853 m_out->Quotew( instance.m_PageNumber ).c_str() );
1856 m_out->Print(
")" );
1862 const std::map<std::string, UTF8>* aProperties )
1869 int oldModifyHash = 1;
1870 bool isNewCache =
false;
1873 oldModifyHash =
m_cache->m_modHash;
1884 m_cache->m_modHash = oldModifyHash + 1;
1899 return m_cache->GetModifyHash();
1907 const wxString& aLibraryPath,
1908 const std::map<std::string, UTF8>* aProperties )
1912 cacheLib( aLibraryPath, aProperties );
1919 for( LIB_SYMBOL_MAP::const_iterator it = symbols.begin(); it != symbols.end(); ++it )
1921 if( !powerSymbolsOnly || it->second->IsPower() )
1922 aSymbolNameList.Add( it->first );
1928 const wxString& aLibraryPath,
1929 const std::map<std::string, UTF8>* aProperties )
1933 cacheLib( aLibraryPath, aProperties );
1940 for( LIB_SYMBOL_MAP::const_iterator it = symbols.begin(); it != symbols.end(); ++it )
1942 if( !powerSymbolsOnly || it->second->IsPower() )
1943 aSymbolList.push_back( it->second );
1949 const wxString& aSymbolName,
1950 const std::map<std::string, UTF8>* aProperties )
1952 cacheLib( aLibraryPath, aProperties );
1954 LIB_SYMBOL_MAP::const_iterator it =
m_cache->m_symbols.find( aSymbolName );
1957 if( it ==
m_cache->m_symbols.end() && aSymbolName.Contains(
'/' ) )
1960 if( it ==
m_cache->m_symbols.end() && aSymbolName.Contains( wxT(
"{slash}" ) ) )
1962 wxString unescaped = aSymbolName;
1963 unescaped.Replace( wxT(
"{slash}" ), wxT(
"/" ) );
1964 it =
m_cache->m_symbols.find( unescaped );
1967 if( it ==
m_cache->m_symbols.end() )
1975 const std::map<std::string, UTF8>* aProperties )
1977 cacheLib( aLibraryPath, aProperties );
1979 m_cache->AddSymbol( std::move( aSymbol ) );
1987 const std::map<std::string, UTF8>* aProperties )
1989 cacheLib( aLibraryPath, aProperties );
1991 m_cache->DeleteSymbol( aSymbolName );
1999 const std::map<std::string, UTF8>* aProperties )
2001 wxFileName fn( aLibraryPath );
2006 if( !fn.IsDir() && wxFileName::DirExists( fn.GetFullPath() ) )
2007 fn.AssignDir( fn.GetFullPath() );
2009 if( !fn.IsDir() && fn.FileExists() )
2010 THROW_IO_ERRORF(
_(
"Symbol library file '%s' already exists." ), fn.GetFullPath() );
2012 if( fn.IsDir() && fn.DirExists() )
2013 THROW_IO_ERRORF(
_(
"Symbol library path '%s' already exists." ), fn.GetPath() );
2024 const std::map<std::string, UTF8>* aProperties )
2026 wxFileName fn = aLibraryPath;
2030 if( !fn.IsDir() && wxFileName::DirExists( fn.GetFullPath() ) )
2031 fn.AssignDir( fn.GetFullPath() );
2033 if( !fn.FileExists() && !fn.DirExists() )
2040 if( wxRemove( aLibraryPath ) )
2041 THROW_IO_ERRORF(
_(
"Symbol library file '%s' cannot be deleted." ), aLibraryPath.GetData() );
2047 if( !fn.Rmdir( wxPATH_RMDIR_RECURSIVE ) )
2048 THROW_IO_ERRORF(
_(
"Symbol library folder '%s' cannot be deleted." ), fn.GetPath() );
2066 wxString oldFileName =
m_cache->GetFileName();
2068 if( !
m_cache->IsFile( aLibraryPath ) )
2069 m_cache->SetFileName( aLibraryPath );
2075 m_cache->SetFileName( oldFileName );
2082 if( wxFileName::DirExists( aLibraryPath ) )
2084 wxDir dir( aLibraryPath );
2086 if( dir.IsOpened() )
2091 if( dir.GetFirst( &filename, filespec, wxDIR_FILES ) )
2103 wxFileName fn( aLibraryPath );
2104 return fn.IsOk() && fn.FileExists();
2110 wxFileName fn( aLibraryPath );
2112 if( fn.FileExists() )
2113 return fn.IsFileWritable();
2115 return fn.IsDirWritable();
2126 std::set<wxString> fieldNames;
2128 for( LIB_SYMBOL_MAP::const_iterator it = symbols.begin(); it != symbols.end(); ++it )
2130 std::map<wxString, wxString> chooserFields;
2131 it->second->GetChooserFields( chooserFields );
2133 for(
const auto& [
name, value] : chooserFields )
2134 fieldNames.insert(
name );
2137 std::copy( fieldNames.begin(), fieldNames.end(), std::back_inserter( aNames ) );
2153 std::vector<LIB_SYMBOL*> newSymbols;
2154 std::unique_ptr<STRING_LINE_READER> reader = std::make_unique<STRING_LINE_READER>( aSymbolText,
2161 newSymbol = parser.
ParseSymbol( map, aFileVersion );
2164 newSymbols.emplace_back( newSymbol );
constexpr EDA_IU_SCALE schIUScale
constexpr BOX2I KiROUND(const BOX2D &aBoxD)
wxString GetMajorMinorVersion()
Get only the major and minor version in a string major.minor.
This class handle bitmap images in KiCad.
bool SaveImageData(wxOutputStream &aOutStream) const
Write the bitmap data to aOutStream.
const LIB_ID & GetDesignBlockLibId() const
std::unordered_set< EDA_ITEM * > & GetItems()
bool HasDesignBlockLink() const
A base class for most all the KiCad significant classes used in schematics and boards.
void SetFlags(EDA_ITEM_FLAGS aMask)
KICAD_T Type() const
Returns the type of object.
void ClearFlags(EDA_ITEM_FLAGS aMask=EDA_ITEM_ALL_FLAGS)
EDA_ITEM * GetParent() const
virtual void SetParent(EDA_ITEM *aParent)
EDA_ITEM_FLAGS GetFlags() const
FILL_T GetFillMode() const
const VECTOR2I & GetEnd() const
Return the ending point of the graphic.
const VECTOR2I & GetStart() const
Return the starting point of the graphic.
COLOR4D GetFillColor() const
wxString SHAPE_T_asString() const
bool IsDefaultFormatting() const
virtual const wxString & GetText() const
Return the string associated with the text object.
virtual bool IsVisible() const
virtual int GetTextHeight() const
virtual void Format(OUTPUTFORMATTER *aFormatter, int aControlBits) const
Output the object to aFormatter in s-expression form.
virtual EDA_ANGLE GetTextAngle() const
EE_TYPE OfType(KICAD_T aType) const
A LINE_READER that reads from an open file.
void Rewind()
Rewind the file and resets the line number back to zero.
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.
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.
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 color representation with 4 components: red, green, blue, alpha.
static const COLOR4D UNSPECIFIED
For legacy support; used as a value to indicate color hasn't been set yet.
bool MakeRelativeTo(const KIID_PATH &aPath)
wxString AsString() const
Define a library symbol object.
void Format(OUTPUTFORMATTER *aOut, const EDA_IU_SCALE &aIuScale, const char *aToken) const
An abstract class from which implementation specific LINE_READERs may be derived to read single lines...
static LOAD_INFO_REPORTER & GetInstance()
void Format(OUTPUTFORMATTER *aFormatter) const
Output the page class to aFormatter in s-expression form.
virtual const wxString GetProjectPath() const
Return the full path of the project.
A REFERENCE_IMAGE is a wrapper around a BITMAP_IMAGE that is displayed in an editor as a reference fo...
VECTOR2I GetPosition() const
const BITMAP_BASE & GetImage() const
Get the underlying image.
double GetImageScale() const
Holds all the data relating to one schematic.
bool IsTopLevelSheetUuid(const KIID &aUuid) const
Check if a UUID names one of this schematic's top level sheets.
SCH_SHEET_LIST Hierarchy() const
Return the full schematic flattened hierarchical sheet list.
PROJECT & Project() const
Return a reference to the project this schematic is part of.
bool IsValid() const
A simple test if the schematic is loaded, not a complete one.
KIID_PATH NormalizeInstancePath(const KIID_PATH &aPath) const
Strip the leading virtual root from a stored instance path, which SCH_SHEET_PATH::Path() omits but st...
bool IsInstancePathInProject(const KIID_PATH &aPath) const
Test whether an instance path is rooted in this schematic's top level sheets.
Object to handle a bitmap image that can be inserted in a schematic.
REFERENCE_IMAGE & GetReferenceImage()
Base class for a bus or wire entry.
VECTOR2I GetPosition() const override
virtual STROKE_PARAMS GetStroke() const override
VECTOR2I GetPosition() const override
virtual const wxString & GetText() const override
Return the string associated with the text object.
wxString GetUntranslatedName() const
Get the untranslated field name for storage, variable look-up, etc.
bool CanAutoplace() const
A set of SCH_ITEMs (i.e., without duplicates).
A cache assistant for the KiCad s-expression symbol libraries.
static void SaveSymbol(LIB_SYMBOL *aSymbol, OUTPUTFORMATTER &aFormatter, const wxString &aLibName=wxEmptyString, bool aIncludeData=true)
Object to parser s-expression symbol library and schematic file formats.
const std::map< wxString, wxString > & GetNetChainNetClasses() const
const std::map< wxString, COLOR4D > & GetNetChainColors() const
void ParseSchematic(SCH_SHEET *aSheet, bool aIsCopyablyOnly=false, int aFileVersion=SEXPR_SCHEMATIC_FILE_VERSION)
Parse the internal LINE_READER object into aSheet.
const std::map< wxString, CHAIN_TERMINALS > & GetNetChainTerminalRefs() const
LIB_SYMBOL * ParseSymbol(LIB_SYMBOL_MAP &aSymbolLibMap, int aFileVersion=SEXPR_SYMBOL_LIB_FILE_VERSION)
Parse internal LINE_READER object into symbols and return all found.
const std::map< wxString, std::set< wxString > > & GetNetChainMemberNets() const
wxString m_path
Root project path for loading child sheets.
void GetDefaultSymbolFields(std::vector< wxString > &aNames) override
Retrieves a list of (custom) field names that should be shown by default for this library in the symb...
void saveShape(SCH_SHAPE *aShape)
void SaveSchematicFile(const wxString &aFileName, SCH_SHEET *aSheet, SCHEMATIC *aSchematic, const std::map< std::string, UTF8 > *aProperties=nullptr) override
Write aSchematic to a storage file in a format that this SCH_IO implementation knows about,...
void SaveLibrary(const wxString &aLibraryPath, const std::map< std::string, UTF8 > *aProperties=nullptr) override
SCH_SHEET_PATH m_currentSheetPath
void saveGroup(SCH_GROUP *aGroup)
void LoadContent(LINE_READER &aReader, SCH_SHEET *aSheet, int aVersion=SEXPR_SCHEMATIC_FILE_VERSION)
void EnumerateSymbolLib(wxArrayString &aSymbolNameList, const wxString &aLibraryPath, const std::map< std::string, UTF8 > *aProperties=nullptr) override
Populate a list of LIB_SYMBOL alias names contained within the library aLibraryPath.
void FormatSchematicToFormatter(OUTPUTFORMATTER *aOut, SCH_SHEET *aSheet, SCHEMATIC *aSchematic, const std::map< std::string, UTF8 > *aProperties=nullptr)
Serialize a schematic sheet to an OUTPUTFORMATTER without file I/O or Prettify.
bool m_appending
Schematic load append status.
std::vector< SCH_SHEET * > m_loadedRootSheets
Root sheets from previous LoadSchematicFile() calls, enabling screen reuse across top-level sheets th...
int m_version
Version of file being loaded.
void loadFile(const wxString &aFileName, SCH_SHEET *aSheet)
static void FormatLibSymbol(LIB_SYMBOL *aPart, OUTPUTFORMATTER &aFormatter)
void DeleteSymbol(const wxString &aLibraryPath, const wxString &aSymbolName, const std::map< std::string, UTF8 > *aProperties=nullptr) override
Delete the entire LIB_SYMBOL associated with aAliasName from the library aLibraryPath.
void loadHierarchy(const SCH_SHEET_PATH &aParentSheetPath, SCH_SHEET *aSheet)
static std::vector< LIB_SYMBOL * > ParseLibSymbols(std::string &aSymbolText, std::string aSource, int aFileVersion=SEXPR_SCHEMATIC_FILE_VERSION)
OUTPUTFORMATTER * m_out
The formatter for saving SCH_SCREEN objects.
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,...
LIB_SYMBOL * LoadSymbol(const wxString &aLibraryPath, const wxString &aAliasName, const std::map< std::string, UTF8 > *aProperties=nullptr) override
Load a LIB_SYMBOL object having aPartName from the aLibraryPath containing a library format that this...
wxString m_error
For throwing exceptions or errors on partial loads.
void saveInstances(const std::vector< SCH_SHEET_INSTANCE > &aSheets)
bool isBuffering(const std::map< std::string, UTF8 > *aProperties)
static const char * PropBuffering
The property used internally by the plugin to enable cache buffering which prevents the library file ...
SCH_SHEET * m_rootSheet
The root sheet of the schematic being loaded.
void cacheLib(const wxString &aLibraryFileName, const std::map< std::string, UTF8 > *aProperties)
void saveRuleArea(SCH_RULE_AREA *aRuleArea)
void saveField(SCH_FIELD *aField)
SCH_IO_KICAD_SEXPR_LIB_CACHE * m_cache
void Format(SCH_SHEET *aSheet)
bool IsLibraryWritable(const wxString &aLibraryPath) override
Return true if the library at aLibraryPath is writable.
void init(SCHEMATIC *aSchematic, const std::map< std::string, UTF8 > *aProperties=nullptr)
initialize PLUGIN like a constructor would.
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,...
void saveBitmap(const SCH_BITMAP &aBitmap)
void saveText(SCH_TEXT *aText)
void saveSheet(SCH_SHEET *aSheet, const SCH_SHEET_LIST &aSheetList)
SCHEMATIC * m_schematic
init() reads this before assigning it.
int GetModifyHash() const override
Return the modification hash from the library cache.
bool m_sheetLoad
Loading a sheet into an open schematic.
bool CanReadLibrary(const wxString &aLibraryPath) const override
Checks if this IO object can read the specified library file/directory.
virtual ~SCH_IO_KICAD_SEXPR()
void saveLine(SCH_LINE *aLine)
void saveNoConnect(SCH_NO_CONNECT *aNoConnect)
void saveTable(SCH_TABLE *aTable)
std::stack< wxString > m_currentPath
Stack to maintain nested sheet paths.
void CreateLibrary(const wxString &aLibraryPath, const std::map< std::string, UTF8 > *aProperties=nullptr) override
Create a new empty library at aLibraryPath empty.
void SaveSymbol(const wxString &aLibraryPath, std::unique_ptr< LIB_SYMBOL > aSymbol, const std::map< std::string, UTF8 > *aProperties=nullptr) override
Write aSymbol to an existing library located at aLibraryPath.
void saveJunction(SCH_JUNCTION *aJunction)
std::function< bool(wxString aTitle, int aIcon, wxString aMsg, wxString aAction)> m_queryUserCallback
void saveTextBox(SCH_TEXTBOX *aText)
void saveSymbol(SCH_SYMBOL *aSymbol, const SCHEMATIC &aSchematic, const SCH_SHEET_LIST &aSheetList, bool aForClipboard, const SCH_SHEET_PATH *aRelativePath=nullptr)
void saveBusEntry(SCH_BUS_ENTRY_BASE *aBusEntry)
void GetAvailableSymbolFields(std::vector< wxString > &aNames) override
Retrieves a list of (custom) field names that are present on symbols in this library.
SCH_IO(const wxString &aName)
Base class for any item which can be embedded within the SCHEMATIC container class,...
bool IsLocked() const override
SCH_LAYER_ID GetLayer() const
Return the layer this item is on.
AUTOPLACE_ALGO GetFieldsAutoplaced() const
Return whether the fields have been automatically placed.
wxString GetClass() const override
Return the class name.
VECTOR2I GetPosition() const override
SPIN_STYLE GetSpinStyle() const
LABEL_FLAG_SHAPE GetShape() const
std::vector< SCH_FIELD > & GetFields()
Segment description base class to describe items which have 2 end points (track, wire,...
virtual STROKE_PARAMS GetStroke() const override
const LINE_ENDING & GetEndEnding() const
VECTOR2I GetEndPoint() const
VECTOR2I GetStartPoint() const
const LINE_ENDING & GetStartEnding() const
void SetEndPoint(const VECTOR2I &aPosition)
A net chain is a collection of nets that are connected together through passive components.
const std::set< wxString > & GetNets() const
const wxString & GetTerminalRef(int aIdx) const
const wxString & GetNetClass() const
const KIGFX::COLOR4D & GetColor() const
const wxString & GetName() const
static bool IsPersistableNet(const wxString &aNet)
Synthetic keys do not survive a reload, so only named nets are written out.
const wxString & GetTerminalPinNum(int aIdx) const
VECTOR2I GetPosition() const override
bool GetExcludedFromSim(const SCH_SHEET_PATH *aInstance=nullptr, const wxString &aVariantName=wxEmptyString) const override
bool GetExcludedFromBOM(const SCH_SHEET_PATH *aInstance=nullptr, const wxString &aVariantName=wxEmptyString) const override
bool GetDNP(const SCH_SHEET_PATH *aInstance=nullptr, const wxString &aVariantName=wxEmptyString) const override
Set or clear the 'Do Not Populate' flag.
bool GetExcludedFromBoard(const SCH_SHEET_PATH *aInstance=nullptr, const wxString &aVariantName=wxEmptyString) const override
const PAGE_INFO & GetPageSettings() const
const std::map< wxString, LIB_SYMBOL * > & GetLibSymbols() const
Fetch a list of unique LIB_SYMBOL object pointers required to properly render each SCH_SYMBOL in this...
EE_RTREE & Items()
Get the full RTree, usually for iterating.
const wxString & GetFileName() const
void SetFileName(const wxString &aFileName)
Set the file name for this screen to aFileName.
TITLE_BLOCK & GetTitleBlock()
wxString GroupsSanityCheck(bool repair=false)
Consistency check of internal m_groups structure.
KIID m_uuid
A unique identifier for each schematic file.
void SetFileReadOnly(bool aIsReadOnly)
void SetFileExists(bool aFileExists)
STROKE_PARAMS GetStroke() const override
A container for handling SCH_SHEET_PATH objects in a flattened hierarchy.
std::optional< SCH_SHEET_PATH > GetSheetPathByKIIDPath(const KIID_PATH &aPath, bool aIncludeLastSheet=true) const
Finds a SCH_SHEET_PATH that matches the provided KIID_PATH.
Handle access to a stack of flattened SCH_SHEET objects by way of a path for creating a flattened sch...
bool empty() const
Forwarded method from std::vector.
KIID_PATH Path() const
Get the sheet path as an KIID_PATH.
SCH_SCREEN * LastScreen()
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.
Sheet symbol placed in a schematic, and is the entry point for a sub schematic.
wxString GetFileName() const
Return the filename corresponding to this sheet.
bool HasRootInstance() const
Check to see if this sheet has a root sheet instance.
std::vector< SCH_FIELD > & GetFields()
Return a reference to the vector holding the sheet's fields.
bool GetExcludedFromBOM(const SCH_SHEET_PATH *aInstance=nullptr, const wxString &aVariantName=wxEmptyString) const override
bool GetExcludedFromSim(const SCH_SHEET_PATH *aInstance=nullptr, const wxString &aVariantName=wxEmptyString) const override
SCH_SCREEN * GetScreen() const
VECTOR2I GetPosition() const override
void SetScreen(SCH_SCREEN *aScreen)
Set the SCH_SCREEN associated with this sheet to aScreen.
const SCH_SHEET_INSTANCE & GetRootInstance() const
Return the root sheet instance data.
KIGFX::COLOR4D GetBorderColor() const
bool GetDNP(const SCH_SHEET_PATH *aInstance=nullptr, const wxString &aVariantName=wxEmptyString) const override
Set or clear the 'Do Not Populate' flags.
bool GetExcludedFromBoard(const SCH_SHEET_PATH *aInstance=nullptr, const wxString &aVariantName=wxEmptyString) const override
int GetBorderWidth() const
std::vector< SCH_SHEET_PIN * > & GetPins()
const std::vector< SCH_SHEET_INSTANCE > & GetInstances() const
KIGFX::COLOR4D GetBackgroundColor() const
PASSTHROUGH_MODE GetPassthroughMode() const
bool GetExcludedFromSim(const SCH_SHEET_PATH *aInstance=nullptr, const wxString &aVariantName=wxEmptyString) const override
std::vector< std::unique_ptr< SCH_PIN > > & GetRawPins()
const std::vector< SCH_SYMBOL_INSTANCE > & GetInstances() const
bool UseLibIdLookup() const
wxString GetSchSymbolLibraryName() const
PIN_MAP_INSTANCE_OVERRIDE GetPinMapOverride(const SCH_SHEET_PATH *aInstance=nullptr, const wxString &aVariantName=wxEmptyString) const
bool GetExcludedFromBOM(const SCH_SHEET_PATH *aInstance=nullptr, const wxString &aVariantName=wxEmptyString) const override
void GetFields(std::vector< SCH_FIELD * > &aVector, bool aVisibleOnly) const override
Populate a std::vector with SCH_FIELDs, sorted in ordinal order.
VECTOR2I GetPosition() const override
const LIB_ID & GetLibId() const override
bool GetExcludedFromPosFiles(const SCH_SHEET_PATH *aInstance=nullptr, const wxString &aVariantName=wxEmptyString) const override
bool GetInstance(SCH_SYMBOL_INSTANCE &aInstance, const KIID_PATH &aSheetPath, bool aTestFromEnd=false) const
bool GetExcludedFromBoard(const SCH_SHEET_PATH *aInstance=nullptr, const wxString &aVariantName=wxEmptyString) const override
int GetOrientation() const override
Get the display symbol orientation.
virtual bool GetDNP(const SCH_SHEET_PATH *aInstance=nullptr, const wxString &aVariantName=wxEmptyString) const override
Set or clear the 'Do Not Populate' flag.
wxString GetPrefix() const
void SetRowHeight(int aRow, int aHeight)
const STROKE_PARAMS & GetSeparatorsStroke() const
void SetColCount(int aCount)
bool StrokeExternal() const
int GetRowHeight(int aRow) const
void SetColWidth(int aCol, int aWidth)
std::vector< SCH_TABLECELL * > GetCells() const
int GetColWidth(int aCol) const
const STROKE_PARAMS & GetBorderStroke() const
bool StrokeHeaderSeparator() const
SCH_TABLECELL * GetCell(int aRow, int aCol) const
bool StrokeColumns() const
EDA_ITEM * Clone() const override
Create a duplicate of this item with linked list members set to NULL.
int GetMarginBottom() const
int GetMarginLeft() const
bool GetExcludedFromSim(const SCH_SHEET_PATH *aInstance=nullptr, const wxString &aVariantName=wxEmptyString) const override
int GetMarginRight() const
bool GetExcludedFromSim(const SCH_SHEET_PATH *aInstance=nullptr, const wxString &aVariantName=wxEmptyString) const override
VECTOR2I GetPosition() const override
Is a LINE_READER that reads from a multiline 8 bit wide std::string.
Simple container to manage line stroke parameters.
void SetWidth(int aWidth)
void Format(OUTPUTFORMATTER *out, const EDA_IU_SCALE &aIuScale) const
static const char * PropPowerSymsOnly
virtual void Format(OUTPUTFORMATTER *aFormatter) const
Output the object to aFormatter in s-expression form.
const char * c_str() const
wxString ExpandTextVars(const wxString &aSource, const PROJECT *aProject, RESOLUTION_CONTEXT aContext)
static constexpr EDA_ANGLE ANGLE_0
static constexpr EDA_ANGLE ANGLE_90
static constexpr EDA_ANGLE ANGLE_270
static constexpr EDA_ANGLE ANGLE_180
#define STRUCT_DELETED
flag indication structures to be erased
#define SKIP_STRUCT
flag indicating that the structure should be ignored
@ RECTANGLE
Use RECTANGLE instead of RECT to avoid collision in a Windows header.
#define DEFAULT_SIZE_TEXT
This is the "default-of-the-default" hardcoded text size; individual application define their own def...
static const std::string KiCadSymbolLibFileExtension
const wxChar *const traceSchPlugin
Flag to enable legacy schematic plugin debug output.
#define THROW_IO_ERRORF(msg,...)
#define THROW_IO_CANCELLED()
wxString LayerName(int aLayer)
Returns the default display name for a given layer.
#define UNIMPLEMENTED_FOR(type)
KICOMMON_API std::string FormatAngle(const EDA_ANGLE &aAngle)
Convert aAngle from board units to a string appropriate for writing to file.
KICOMMON_API std::string FormatInternalUnits(const EDA_IU_SCALE &aIuScale, int aValue, EDA_DATA_TYPE aDataType=EDA_DATA_TYPE::DISTANCE)
Converts aValue from internal units to a string appropriate for writing to file.
#define SEXPR_SCHEMATIC_FILE_VERSION
Schematic file version.
Class to handle a set of SCH_ITEMs.
static void formatPinMapOverride(OUTPUTFORMATTER *aOut, const PIN_MAP_INSTANCE_OVERRIDE &aOverride)
void formatArc(OUTPUTFORMATTER *aFormatter, EDA_SHAPE *aArc, bool aIsPrivate, const STROKE_PARAMS &aStroke, FILL_T aFillMode, const COLOR4D &aFillColor, bool aInvertY, const KIID &aUuid, bool aLocked)
void formatEllipseArc(OUTPUTFORMATTER *aFormatter, EDA_SHAPE *aEllipseArc, bool aIsPrivate, const STROKE_PARAMS &aStroke, FILL_T aFillMode, const COLOR4D &aFillColor, bool aInvertY, const KIID &aUuid, bool aLocked)
void formatCircle(OUTPUTFORMATTER *aFormatter, EDA_SHAPE *aCircle, bool aIsPrivate, const STROKE_PARAMS &aStroke, FILL_T aFillMode, const COLOR4D &aFillColor, bool aInvertY, const KIID &aUuid, bool aLocked)
const char * getSheetPinShapeToken(LABEL_FLAG_SHAPE aShape)
void formatRect(OUTPUTFORMATTER *aFormatter, EDA_SHAPE *aRect, bool aIsPrivate, const STROKE_PARAMS &aStroke, FILL_T aFillMode, const COLOR4D &aFillColor, bool aInvertY, const KIID &aUuid, bool aLocked)
const char * getTextTypeToken(KICAD_T aType)
void formatBezier(OUTPUTFORMATTER *aFormatter, EDA_SHAPE *aBezier, bool aIsPrivate, const STROKE_PARAMS &aStroke, FILL_T aFillMode, const COLOR4D &aFillColor, bool aInvertY, const KIID &aUuid, bool aLocked)
void formatEllipse(OUTPUTFORMATTER *aFormatter, EDA_SHAPE *aEllipse, bool aIsPrivate, const STROKE_PARAMS &aStroke, FILL_T aFillMode, const COLOR4D &aFillColor, bool aInvertY, const KIID &aUuid, bool aLocked)
void formatPoly(OUTPUTFORMATTER *aFormatter, EDA_SHAPE *aPolyLine, bool aIsPrivate, const STROKE_PARAMS &aStroke, FILL_T aFillMode, const COLOR4D &aFillColor, bool aInvertY, const KIID &aUuid, bool aLocked)
EDA_ANGLE getSheetPinAngle(SHEET_SIDE aSide)
void formatFill(OUTPUTFORMATTER *aFormatter, FILL_T aFillMode, const COLOR4D &aFillColor)
Fill token formatting helper.
std::string toUTFTildaText(const wxString &txt)
Convert a wxString to UTF8 and replace any control characters with a ~, where a control character is ...
static wxString projectKey(const wxString &aFullPath)
std::string FormatDouble2Str(double aValue)
Print a float number without using scientific notation and no trailing 0 This function is intended in...
std::string EscapedUTF8(const wxString &aString)
Return an 8 bit UTF8 string given aString in Unicode form.
wxString EscapeString(const wxString &aSource, ESCAPE_CONTEXT aContext)
The Escape/Unescape routines use HTML-entity-reference-style encoding to handle characters which are:...
#define TO_UTF8(wxstring)
Convert a wxString to a UTF8 encoded C string for all wxWidgets build modes.
One symbol-pin to footprint-pad mapping inside a PIN_MAP.
Per-instance override of the active pin map and a sparse delta on top.
std::vector< PIN_MAP_ENTRY > m_Edits
PIN_MAP_OVERRIDE_MODE m_Mode
A simple container for sheet instance information.
A simple container for schematic symbol instance information.
std::map< wxString, LIB_SYMBOL *, LibSymbolMapSort > LIB_SYMBOL_MAP
FIELD_T
The set of all field indices assuming an array like sequence that a SCH_COMPONENT or LIB_PART can hol...
@ REFERENCE
Field Reference of part, i.e. "IC21".
wxLogTrace helper definitions.
VECTOR2< int32_t > VECTOR2I
Definition of file extensions used in Kicad.