60#include <compoundfilereader.h>
70#include <wx/mstream.h>
71#include <wx/zstream.h>
72#include <wx/wfstream.h>
73#include <magic_enum.hpp>
79#define HARNESS_PORT_COLOR_DEFAULT_BACKGROUND COLOR4D( 0.92941176470588238, \
80 0.94901960784313721, \
81 0.98431372549019602, 1.0 )
83#define HARNESS_PORT_COLOR_DEFAULT_OUTLINE COLOR4D( 0.56078431372549020, \
84 0.61960784313725492, \
85 0.78823529411764703, 1.0 )
98 wxFileName fn = aFileName;
99 fn.Normalize( wxPATH_NORM_ABSOLUTE | wxPATH_NORM_DOTS | wxPATH_NORM_TILDE | wxPATH_NORM_CASE );
100 return fn.GetFullPath();
116 for(
const wxString& key :
m_keys )
117 m_owner->m_parsingFiles[key]++;
122 for(
const wxString& key :
m_keys )
124 auto it =
m_owner->m_parsingFiles.find( key );
126 if( it !=
m_owner->m_parsingFiles.end() && --it->second <= 0 )
127 m_owner->m_parsingFiles.erase( it );
148 int red = color & 0x0000FF;
149 int green = ( color & 0x00FF00 ) >> 8;
150 int blue = ( color & 0xFF0000 ) >> 16;
222 if( stroke.
GetColor() == default_color || stroke.
GetColor() == alt_default_color )
259 else if( elem.
AreaColor == aStrokeColor )
265 else if( bgcolor.
WithAlpha( 1.0 ) == default_bgcolor )
310 for(
auto& [
name, symbol] : lib )
362 std::vector<SCH_PIN*> pins;
365 pins =
static_cast<SCH_SYMBOL*
>( aSymbol )->GetPins(
nullptr );
367 pins =
static_cast<LIB_SYMBOL*
>( aSymbol )->GetGraphicalPins( 0, 0 );
370 bool names_visible =
false;
371 bool numbers_visible =
false;
375 if(
pin->GetNameTextSize() > 0 && !
pin->GetName().empty() )
376 names_visible =
true;
378 if(
pin->GetNumberTextSize() > 0 && !
pin->GetNumber().empty() )
379 numbers_visible =
true;
390 if( !numbers_visible )
439 std::map<wxString, SCH_SHEET*> sheets;
440 wxFileName
project( aProperties->at(
"project_file" ) );
442 for(
auto& [key, filestring] : *aProperties )
444 if( key.starts_with(
"sch" ) )
448 for(
auto& [ key, filestring] : *aProperties )
450 if( !key.starts_with(
"sch" ) )
453 wxFileName fn( filestring );
461 [&](
const wxString& aParsed )
472 std::unique_ptr<SCH_SHEET> sheet = std::make_unique<SCH_SHEET>(
m_rootSheet, pos );
474 sheet->SetScreen( screen );
477 sheet->SyncUuidToScreen();
482 sheet->SetFileName( kicad_fn.GetFullName() );
485 wxCHECK2( sheet && screen,
continue );
487 wxString pageNo = wxString::Format( wxT(
"%d" ), page++ );
499 if( sheet->GetName().Trim().empty() )
501 std::set<wxString> existingNames;
503 for(
auto& [
path, existing] : sheets )
504 existingNames.insert( existing->GetName() );
514 wxCHECK2( currentScreen,
continue );
518 currentScreen->
Append( sheetPtr );
534 for(
auto& [ sourceKey, sheet ] : sheets )
546 const std::map<std::string, UTF8>* aProperties )
548 wxCHECK( ( !aFileName.IsEmpty() || !aProperties->empty() ) && aSchematic,
nullptr );
550 wxFileName fileName( aFileName );
570 if( !
m_schematic->Project().GetProjectName().IsEmpty() )
580 std::unique_ptr<SCH_SHEET> deleter( aAppendToMe ?
nullptr :
m_rootSheet );
584 wxCHECK_MSG( aSchematic->
IsValid(),
nullptr,
"Can't append to a schematic with no root!" );
592 wxFileName saved( screen->GetFileName() );
600 m_rootSheet->SetFileName( fileName.GetFullPath() );
605 if( aFileName.empty() )
628 if( !aFileName.empty() )
635 wxCHECK( rootScreen,
nullptr );
644 if( aFileName.empty() )
649 if( aFileName.empty() )
651 std::vector<SCH_SHEET*> topLevelSheets;
659 topLevelSheets.push_back( sheet );
665 rootScreen->
Remove( sheet );
667 if( !topLevelSheets.empty() )
679 std::vector<SCH_HIERLABEL*> hierLabels;
687 hierLabel->GetText() );
688 globalLabel->
SetShape( hierLabel->GetShape() );
692 screen->
Remove( hierLabel );
693 screen->
Append( globalLabel );
712 if( aProperties && aProperties->count(
"project_file" ) )
729 std::map<SCH_SYMBOL*, bool> resolves;
744 if( !
text.StartsWith( wxS(
"${" ) ) || !
text.EndsWith( wxS(
"}" ) )
745 ||
text.find(
'}', 2 ) !=
text.length() - 1 ||
text.find( wxS(
"${" ), 2 ) != wxString::npos )
754 known |= field.GetName().IsSameAs(
name,
false );
757 resolves[symbol] |= known;
761 for(
const auto& [symbol, known] : resolves )
772 if( aProperties && aProperties->count(
"project_file" ) )
774 const wxString& projectFile = aProperties->at(
"project_file" );
778 if( !variants.empty() )
784 std::vector<std::pair<wxString, const ALTIUM_VARIANT_ENTRY*>>;
786 std::map<wxString, ENTRY_LIST> variantsByUid;
787 std::map<wxString, ENTRY_LIST> variantsByDesignator;
793 if( !pv.description.empty() && pv.description != pv.name )
794 m_schematic->SetVariantDescription( pv.name, pv.description );
799 variantsByUid[entry.
uniqueId].push_back( { pv.name, &entry } );
801 variantsByDesignator[entry.
designator].push_back( { pv.name, &entry } );
818 ENTRY_LIST applicable;
820 const ENTRY_LIST* uidEntries =
nullptr;
825 auto varIt = variantsByUid.find( symUidIt->second );
827 if( varIt != variantsByUid.end() )
828 uidEntries = &varIt->second;
831 if( uidEntries && uidEntries->size() == 1 )
833 applicable = *uidEntries;
835 else if( uidEntries )
841 for(
const auto& namedEntry : *uidEntries )
843 if( namedEntry.second->designator == ref )
844 applicable.push_back( namedEntry );
850 auto varIt = variantsByDesignator.find( ref );
852 if( varIt != variantsByDesignator.end() )
853 applicable = varIt->second;
856 if( applicable.empty() )
859 for(
const auto& [variantName, entry] : applicable )
864 if( entry->kind == 1 )
866 variant.
m_DNP =
true;
870 else if( entry->kind == 0 )
872 for(
const auto& [key, value] : entry->alternateFields )
874 if( key.CmpNoCase( wxS(
"LibReference" ) ) == 0 )
875 variant.
m_Fields[wxS(
"Value" )] = value;
876 else if( key.CmpNoCase( wxS(
"Description" ) ) == 0 )
877 variant.
m_Fields[wxS(
"Description" )] = value;
878 else if( key.CmpNoCase( wxS(
"Footprint" ) ) == 0 )
879 variant.
m_Fields[wxS(
"Footprint" )] = value;
890 if( aProperties && aProperties->count(
"project_file" )
899 int minWireWidth = std::numeric_limits<int>::max();
900 int minBusWidth = std::numeric_limits<int>::max();
904 std::vector<SCH_MARKER*> markers;
911 minWireWidth = std::min( minWireWidth, line->
GetLineWidth() );
914 minBusWidth = std::min( minBusWidth, line->
GetLineWidth() );
918 std::shared_ptr<NET_SETTINGS>& netSettings =
m_schematic->Project().GetProjectFile().NetSettings();
920 if( minWireWidth < std::numeric_limits<int>::max() )
921 netSettings->GetDefaultNetclass()->SetWireWidth( minWireWidth );
923 if( minBusWidth < std::numeric_limits<int>::max() )
924 netSettings->GetDefaultNetclass()->SetBusWidth( minBusWidth );
947 std::vector<SCH_LINE*> busLines;
948 std::map<VECTOR2I, std::vector<SCH_LINE*>> busLineMap;
956 busLines.push_back( line );
958 busLineMap[ line->
GetEndPoint() ].push_back( line );
965 auto it = busLineMap.find( aStart );
967 if( it == busLineMap.end() )
973 if( aVisited.count( line ) )
976 aVisited.insert( line );
997 std::shared_ptr<BUS_ALIAS> alias = std::make_shared<BUS_ALIAS>();
998 alias->SetName( harness.m_name );
1001 alias->AddMember( port.
m_name );
1006 BOX2I box( harness.m_location, harness.m_size );
1013 if( !line->
IsBus() )
1036 int delta_x =
center.x - pos.
x;
1037 int delta_y =
center.y - pos.
y;
1044 screen->
Append( busLine );
1051 screen->
Append( busLine );
1061 std::set<SCH_LINE*> visited;
1062 SCH_LABEL* label = walkBusLine( pos, visited );
1069 if( label && !label->
GetText().StartsWith( wxT(
"{" ) ) )
1070 label->
SetText( label->
GetText() + wxT(
"{" ) + harness.m_name + wxT(
"}" ) );
1085 if( harness.m_ports.empty() )
1090 bool isVertical =
true;
1092 if( harness.m_ports.size() > 1 )
1094 VECTOR2I first = harness.m_ports.front().m_location;
1095 VECTOR2I last = harness.m_ports.back().m_location;
1097 if( first.
y == last.
y )
1103 VECTOR2I bottom = harness.m_ports.front().m_entryLocation;
1104 VECTOR2I top = harness.m_ports.front().m_entryLocation;
1177 if( aText.Contains( wxT(
" " ) ) || aText.Contains( wxT(
"," ) ) )
1180 return wxT(
"{" ) + aText + wxT(
"}" );
1186 wxString baseName = wxFileName( aFilename ).GetName();
1187 baseName.Replace( wxT(
"/" ), wxT(
"_" ) );
1189 if( baseName.Trim().empty() )
1190 baseName = wxT(
"Sheet" );
1192 wxString sheetName = baseName;
1194 for(
int ii = 1; aExistingNames.count( sheetName ); ++ii )
1195 sheetName = baseName + wxString::Format( wxT(
"_%d" ), ii );
1206 bool hasBusLines =
false;
1224 std::vector<SCH_LABEL*> labelsToWrap;
1239 labelsToWrap.push_back( label );
1255 std::set<wxString> existingNames;
1261 if( !sheet->
GetName().Trim().empty() )
1262 existingNames.insert( sheet->
GetName() );
1265 for(
auto& [idx, sheet] :
m_sheets )
1267 if( !sheet->GetName().Trim().empty() )
1271 wxString filename = filenameField ? filenameField->
GetText() : wxString();
1274 sheet->SetName( sheetName );
1275 existingNames.insert( sheetName );
1281 const wxString& aSheetFileName )
const
1283 wxString sheetFileName = aSheetFileName;
1284 sheetFileName.Replace( wxS(
"\\" ), wxS(
"/" ) );
1286 wxFileName loadAltiumFileName( sheetFileName );
1287 loadAltiumFileName.MakeAbsolute( aParentPath );
1289 if( loadAltiumFileName.IsFileReadable() )
1290 return loadAltiumFileName;
1292 if( !loadAltiumFileName.HasExt() )
1294 wxFileName withExt( loadAltiumFileName );
1295 withExt.SetExt( wxT(
"SchDoc" ) );
1297 if( withExt.IsFileReadable() )
1301 bool extensionless = !loadAltiumFileName.HasExt();
1303 wxArrayString files;
1304 wxDir::GetAllFiles( loadAltiumFileName.GetPath(), &files, wxEmptyString, wxDIR_FILES | wxDIR_HIDDEN );
1306 for(
const wxString& candidate : files )
1308 wxFileName candidateFname( candidate );
1310 if( candidateFname.GetFullName().IsSameAs( loadAltiumFileName.GetFullName(),
false )
1312 && !loadAltiumFileName.GetName().empty()
1313 && candidateFname.GetName().IsSameAs( loadAltiumFileName.GetName(),
false )
1314 && candidateFname.GetExt().IsSameAs( wxT(
"SchDoc" ),
false ) ) )
1316 return candidateFname;
1323 if( document.IsFileReadable()
1324 && ( document.GetFullName().IsSameAs( loadAltiumFileName.GetFullName(),
false )
1325 || ( extensionless && document.GetName().IsSameAs( loadAltiumFileName.GetName(),
false ) ) ) )
1331 return loadAltiumFileName;
1342 std::map<wxString, std::vector<SCH_SHEET_PATH>> pathsByFile;
1346 if( sheetPath.size() < 2 || !sheetPath.LastScreen() )
1349 wxString sheetFileName = sheetPath.Last()->GetFileName().Lower();
1351 if( sheetFileName.IsEmpty() )
1357 pathsByFile[parentPath.
Path().
AsString() + wxT(
"|" ) + sheetFileName]
1358 .push_back( sheetPath );
1361 for(
auto& [groupKey, sheetPaths] : pathsByFile )
1363 if( sheetPaths.size() < 2 )
1366 std::sort( sheetPaths.begin(), sheetPaths.end(),
1369 const VECTOR2I& firstPos = aFirst.Last()->GetPosition();
1370 const VECTOR2I& secondPos = aSecond.Last()->GetPosition();
1372 if( firstPos.y != secondPos.y )
1373 return firstPos.y < secondPos.y;
1375 return firstPos.x < secondPos.x;
1384 if( sheetPath.GetPageNumber().ToLong( &page ) && page > 0 )
1385 basePage = basePage == 0 ? page : std::min( basePage, page );
1391 nextPage.ToLong( &basePage );
1397 for(
size_t ii = 0; ii < sheetPaths.size(); ++ii )
1401 sheetPath.
SetPageNumber( wxString::Format( wxT(
"%ld" ), basePage + (
long) ii ) );
1408 if( baseRef.StartsWith( wxT(
"#" ) ) )
1414 if( !baseRef.IsEmpty() )
1415 symbol->
SetRef( &sheetPath, baseRef + wxT(
"_" ) + sheetPath.
Last()->
GetName() );
1428 const std::map<const SCH_ITEM*, const SCH_ITEM*>& aOriginals )
1432 for(
const auto& [key, subgraphs] : aGraph.
GetNetMap() )
1436 for(
const SCH_ITEM* item : subgraph->GetItems() )
1438 auto original = aOriginals.find( item );
1440 codes[{ subgraph->GetSheet().Path(), original != aOriginals.end() ? original->second : item }] =
1452 if( aBefore.size() != aAfter.size() )
1455 std::map<int, int> forward;
1456 std::map<int, int> backward;
1458 for(
const auto& [
pin, code] : aBefore )
1460 auto it = aAfter.find(
pin );
1462 if( it == aAfter.end() )
1465 if( forward.emplace( code, it->second ).first->second != it->second
1466 || backward.emplace( it->second, code ).first->second != code )
1483 struct NET_IDENTIFIERS
1486 bool hasGlobalLabel =
false;
1487 bool hasGlobalPower =
false;
1488 std::set<wxString> labelNames;
1489 std::set<SCH_LABEL*> labels;
1492 std::map<int, NET_IDENTIFIERS> nets;
1493 std::map<wxString, std::set<int>> globalNameNets;
1494 std::map<SCH_LABEL*, std::set<int>> labelNets;
1496 for(
const auto& [key, subgraphs] : graph->
GetNetMap() )
1498 NET_IDENTIFIERS& net = nets[key.Netcode];
1499 net.name = key.Name;
1503 for(
SCH_ITEM* item : subgraph->GetItems() )
1507 net.hasGlobalLabel =
true;
1508 globalNameNets[subgraph->GetNameForDriver( item )].insert( key.Netcode );
1512 net.hasGlobalPower =
true;
1513 globalNameNets[subgraph->GetNameForDriver( item )].insert( key.Netcode );
1516 && !wxString(
static_cast<SCH_LABEL*
>( item )->GetText() ).Trim().IsEmpty() )
1520 net.labelNames.insert( label->
GetText() );
1521 net.labels.insert( label );
1522 labelNets[label].insert( key.Netcode );
1528 std::map<wxString, std::vector<int>>
candidates;
1530 for(
const auto& [code, net] : nets )
1533 if( net.hasGlobalLabel || !net.hasGlobalPower || net.labelNames.size() != 1 )
1536 const wxString&
text = *net.labelNames.begin();
1539 if(
name == net.name ||
text.Contains( wxS(
"${" ) ) )
1543 if(
auto it = globalNameNets.find(
name );
1544 it != globalNameNets.end()
1545 && std::any_of( it->second.begin(), it->second.end(),
1548 return aCode != code;
1555 if( std::all_of( net.labels.begin(), net.labels.end(),
1558 return labelNets[aLabel].size() == 1;
1565 std::vector<std::pair<SCH_LABEL*, SCH_GLOBALLABEL*>> converted;
1566 std::vector<wxString> promoted;
1571 if( codes.size() != 1 )
1574 promoted.push_back(
name );
1576 for(
SCH_LABEL* label : nets[codes.front()].labels )
1596 converted.emplace_back( label, globalLabel );
1600 if( converted.empty() )
1603 auto screenOf = [](
SCH_ITEM* aItem )
1605 return static_cast<SCH_SCREEN*
>( aItem->GetParent() );
1608 std::map<const SCH_ITEM*, const SCH_ITEM*> originals;
1610 for(
const auto& [label, globalLabel] : converted )
1611 originals[globalLabel] = label;
1615 for(
auto& [label, globalLabel] : converted )
1619 screen->
Append( globalLabel );
1626 for(
auto& [label, globalLabel] : converted )
1631 for(
const wxString&
name : promoted )
1633 m_reporter->Report( wxString::Format(
_(
"Net label '%s' made global so it names its net "
1634 "ahead of the power port, as in Altium." ),
1643 for(
auto& [label, globalLabel] : converted )
1645 SCH_SCREEN* screen = screenOf( globalLabel );
1646 screen->
Remove( globalLabel );
1654 m_reporter->Report( wxS(
"Net labels kept local, a global label would have changed connectivity" ),
1662 wxFileName parentFileName( aFileName );
1677 wxFileName relative = parentFileName;
1680 m_progressReporter->Report( wxString::Format(
_(
"Importing %s" ), relative.GetFullPath() ) );
1698 catch(
const CFB::CFBException& exception )
1702 catch(
const std::exception& exc )
1704 THROW_IO_ERROR( wxString::Format(
_(
"Error parsing Altium schematic: %s" ), exc.what() ) );
1713 wxCHECK( currentScreen, );
1717 std::vector<SCH_SHEET*> cyclicSheets;
1723 wxCHECK2( sheet,
continue );
1729 wxArrayString tokens = wxSplit( sheet->
GetFileName(),
';' );
1730 std::vector<wxFileName> members;
1731 std::set<wxString> memberKeySet;
1732 bool skippedForRecursion =
false;
1734 for( wxString token : tokens )
1736 token.Trim(
true ).Trim(
false );
1738 if( token.IsEmpty() )
1743 if( resolved.GetFullName().IsEmpty() || !resolved.IsFileReadable() )
1750 skippedForRecursion =
true;
1755 if( memberKeySet.insert( key ).second )
1756 members.push_back( resolved );
1759 if( members.empty() )
1763 if( skippedForRecursion )
1765 cyclicSheets.push_back( sheet );
1769 wxString missingFile;
1771 for( wxString token : tokens )
1773 if( !token.Trim(
true ).Trim(
false ).IsEmpty() )
1775 missingFile = token;
1780 if( missingFile.IsEmpty() )
1782 m_errorMessages.emplace( wxString::Format(
_(
"The file name for sheet %s is undefined, "
1783 "this is probably an Altium signal harness "
1784 "that got converted to a sheet." ),
1790 m_errorMessages.emplace( wxString::Format(
_(
"The file %s of sheet %s was not found; the "
1791 "sheet is empty." ),
1792 missingFile, sheet->
GetName() ),
1804 std::vector<wxString> loadKey;
1806 for(
const wxFileName& member : members )
1815 loadedScreen = it->second;
1829 wxCHECK2( screen,
continue );
1831 if( sheet->
GetName().Trim().empty() )
1833 std::set<wxString> sheetNames;
1844 std::vector<wxString>( memberKeySet.begin(),
1845 memberKeySet.end() ) );
1849 std::optional<int> nextPageTop;
1851 for(
const wxFileName& member : members )
1853 std::set<const SCH_ITEM*> before;
1856 before.insert( screenItem );
1860 std::vector<SCH_ITEM*> added;
1865 if( !before.count( screenItem ) )
1867 added.push_back( screenItem );
1868 addedBox.
Merge( screenItem->GetBoundingBox() );
1882 addedItem->Move( shift );
1883 screen->
Update( addedItem );
1886 addedBox.
Offset( shift );
1907 wxString stem = aMissingFile;
1908 stem.Replace( wxS(
"\\" ), wxS(
"/" ) );
1909 stem = stem.IsEmpty() ? aSheet->
GetName() : wxFileName( stem ).GetName();
1912 if( stem.IsEmpty() )
1940 || !
m_sheetFiles.insert( fn.GetFullPath().Lower() ).second;
1943 fn.SetName( wxString::Format( wxS(
"%s_%d" ), aStem, n ) );
1946 return fn.GetFullPath();
1965 aScreen->
Append( label );
1974 return !aInstance.m_Path.empty()
1975 && aInstance.m_Path.back() == sheet->m_Uuid;
1986 const CFB::COMPOUND_FILE_ENTRY* file = aAltiumSchFile.
FindStream( {
"Storage" } );
1988 if( file ==
nullptr )
1993 std::map<wxString, wxString> properties = reader.
ReadProperties();
2000 for(
int i = 0; i < weight; i++ )
2010 m_errorMessages.emplace( wxString::Format(
_(
"Storage file not fully parsed (%d bytes remaining)." ),
2019 wxString streamName = wxS(
"Additional" );
2021 const CFB::COMPOUND_FILE_ENTRY* file =
2022 aAltiumSchFile.
FindStream( { streamName.ToStdString() } );
2024 if( file ==
nullptr )
2031 THROW_IO_ERROR(
"Additional section does not contain any data" );
2035 std::map<wxString, wxString> properties = reader.
ReadProperties();
2046 std::map<wxString, wxString> properties = reader.
ReadProperties();
2073 wxString streamName = wxS(
"FileHeader" );
2075 const CFB::COMPOUND_FILE_ENTRY* file = aAltiumSchFile.
FindStream( { streamName.ToStdString() } );
2077 if( file ==
nullptr )
2088 std::map<wxString, wxString> properties = reader.
ReadProperties();
2092 if( libtype.CmpNoCase(
"Protel for Windows - Schematic Capture Binary File Version 5.0" ) )
2105 std::map<wxString, wxString> properties = reader.
ReadProperties();
2117 for( std::pair<const int, SCH_SYMBOL*>& symbol :
m_symbols )
2127 symbol.second->SetLibSymbol( libSymbolIt->second );
2170 while( storageReader.
CanRead() )
2172 std::map<wxString, wxString> properties = storageReader.
ReadProperties();
2175 if( properties.find( wxS(
"BINARY" ) ) != properties.end() )
2189 std::map<wxString, wxString> properties = reader.
ReadProperties();
2193 if( libtype.CmpNoCase(
"Protel for Windows - Schematic Capture Ascii File Version 5.0" ) )
2208 std::map<wxString, wxString> properties = reader.
ReadProperties();
2211 if( properties.find( wxS(
"HEADER" ) ) != properties.end() )
2217 if( properties.find( wxS(
"RECORD" ) ) != properties.end() )
2230 for( std::pair<const int, SCH_SYMBOL*>& symbol :
m_symbols )
2240 symbol.second->SetLibSymbol( libSymbolIt->second );
2286 const wxString& aSectionName )
2482 wxString::Format(
_(
"Unknown or unexpected record id %d found in %s." ), recordId,
2499 if( file.filename.IsSameAs( aFilename ) )
2502 if( file.filename.EndsWith( aFilename ) )
2503 nonExactMatch = &file;
2506 return nonExactMatch;
2513 wxCHECK( currentSheet, );
2515 wxString sheetName = currentSheet->
GetName();
2517 if( sheetName.IsEmpty() )
2518 sheetName = wxT(
"root" );
2526 m_errorMessages.emplace( wxString::Format(
_(
"Symbol '%s' in sheet '%s' at index %d "
2527 "replaced with symbol \"%s\"." ),
2554 name = wxString::Format(
"%s_%d%s_%s_%s",
2575 std::vector<wxString> bodyStyleNames;
2578 bodyStyleNames.push_back( wxString::Format(
"Display %d", i + 1 ) );
2591 field.SetVisible(
false );
2627 screen->
Append( symbol );
2639 wxCHECK( currentSheet, );
2641 wxString sheetName = currentSheet->
GetName();
2643 if( sheetName.IsEmpty() )
2644 sheetName = wxT(
"root" );
2649 wxString baseName = altiumTemplate.
filename.AfterLast(
'\\' ).BeforeLast(
'.' );
2651 if( baseName.IsEmpty() )
2652 baseName = wxS(
"Template" );
2660 std::vector<LIB_SYMBOL*>& aSymbol )
2664 LIB_SYMBOL* symbol = aSymbol.empty() ? nullptr : aSymbol[0];
2674 m_errorMessages.emplace( wxString::Format( wxT(
"Pin's owner (%d) not found." ),
2680 schSymbol =
m_symbols.at( libSymbolIt->first );
2681 symbol = libSymbolIt->second;
2697 if( !aSymbol.empty() )
2715 pin->SetVisible(
false );
2718 pin->SetNumberTextSize( 0 );
2721 pin->SetNameTextSize( 0 );
2759 VECTOR2I dir = bodyEnd - pinLocation;
2767 pin->SetPosition( pinLocation );
2865 int vjustify, hjustify;
2868 switch( justification )
2891 switch( justification )
2914 switch( orientation )
2937 text->SetTextAngle( angle );
3022 for(
int i = 0; i < nRenderRotations; i++ )
3042 std::vector<LIB_SYMBOL*>& aSymbol, std::vector<int>& aFontSizes )
3048 static const std::map<wxString, wxString> variableMap = {
3049 {
"SHEETNUMBER",
"#" },
3050 {
"SHEETTOTAL",
"##" },
3051 {
"TITLE",
"TITLE" },
3052 {
"REVISION",
"REVISION" },
3053 {
"DATE",
"ISSUE_DATE" },
3054 {
"CURRENTDATE",
"CURRENT_DATE" },
3055 {
"CURRENTTIME",
"CURRENT_TIME_LOCALE" },
3056 {
"COMPANYNAME",
"COMPANY" },
3057 {
"DOCUMENTNAME",
"FILENAME" },
3058 {
"DOCUMENTFULLPATHANDNAME",
"FILEPATH" },
3059 {
"PROJECTNAME",
"PROJECTNAME" },
3062 std::set<wxString> unmapped;
3067 std::set<wxString> kicadNames;
3069 for(
const auto& [altiumName, kicadName] : variableMap )
3070 kicadNames.insert( kicadName );
3072 for(
const wxString&
name : unmapped )
3074 if( !kicadNames.count(
name ) )
3080 size_t fontId =
static_cast<int>( elem.
fontId );
3097 screen->
Append( textItem );
3101 LIB_SYMBOL* symbol = aSymbol.empty() ? nullptr : aSymbol[0];
3116 symbol = libSymbolIt->second;
3117 schsym =
m_symbols.at( libSymbolIt->first );
3126 if( !aSymbol.empty() )
3155 size_t fontId = elem.
fontId;
3166 else if( fontId > 0 && fontId <= aFontSizes.size() )
3168 int size = aFontSizes[fontId - 1];
3176 std::vector<LIB_SYMBOL*>& aSymbol,
3177 std::vector<int>& aFontSizes )
3204 textBox->
SetStart( sheetTopRight );
3205 textBox->
SetEnd( sheetBottomLeft );
3235 size_t fontId =
static_cast<int>( aElem->
FontID );
3253 screen->
Append( textBox );
3258 std::vector<int>& aFontSizes )
3260 LIB_SYMBOL* symbol = aSymbol.empty() ? nullptr : aSymbol[0];
3275 symbol = libSymbolIt->second;
3276 schsym =
m_symbols.at( libSymbolIt->first );
3286 if( !aSymbol.empty() )
3339 if( aElem->
FontID > 0 && aElem->
FontID <=
static_cast<int>( aFontSizes.size() ) )
3341 int size = aFontSizes[aElem->
FontID - 1];
3348 std::vector<LIB_SYMBOL*>& aSymbol )
3352 if( elem.
points.size() < 2 )
3354 m_errorMessages.emplace( wxString::Format(
_(
"Bezier has %d control points. At least 2 are expected." ),
3355 static_cast<int>( elem.
points.size() ) ),
3363 wxCHECK( currentScreen, );
3365 for(
size_t i = 0; i + 1 < elem.
points.size(); i += 3 )
3367 if( i + 2 == elem.
points.size() )
3378 currentScreen->
Append( line );
3383 std::vector<VECTOR2I> bezierPoints;
3384 std::vector<VECTOR2I> polyPoints;
3386 for(
size_t j = i; j < elem.
points.size() && j < i + 4; j++ )
3387 bezierPoints.push_back( elem.
points.at( j ) );
3390 converter.
GetPoly( polyPoints );
3392 for(
size_t k = 0; k + 1 < polyPoints.size(); k++ )
3401 currentScreen->
Append( line );
3408 LIB_SYMBOL* symbol = aSymbol.empty() ? nullptr : aSymbol[0];
3418 m_errorMessages.emplace( wxString::Format( wxT(
"Bezier's owner (%d) not found." ),
3424 symbol = libSymbolIt->second;
3425 schsym =
m_symbols.at( libSymbolIt->first );
3432 if( !aSymbol.empty() )
3445 for(
size_t i = 0; i + 1 < elem.
points.size(); i += 3 )
3447 if( i + 2 == elem.
points.size() )
3458 for(
size_t j = i; j < elem.
points.size() && j < i + 2; j++ )
3470 else if( i + 3 == elem.
points.size() )
3484 for(
size_t j = i; j < elem.
points.size() && j < i + 2; j++ )
3507 for(
size_t j = i; j < elem.
points.size() && j < i + 4; j++ )
3516 case 0: bezier->
SetStart( pos );
break;
3519 case 3: bezier->
SetEnd( pos );
break;
3533 std::vector<LIB_SYMBOL*>& aSymbol )
3537 if( elem.
Points.size() < 2 )
3545 for(
size_t i = 1; i < elem.
Points.size(); i++ )
3562 LIB_SYMBOL* symbol = aSymbol.empty() ? nullptr : aSymbol[0];
3572 m_errorMessages.emplace( wxString::Format( wxT(
"Polyline's owner (%d) not found." ),
3578 symbol = libSymbolIt->second;
3579 schsym =
m_symbols.at( libSymbolIt->first );
3589 if( !aSymbol.empty() )
3620 std::vector<LIB_SYMBOL*>& aSymbol )
3643 LIB_SYMBOL* symbol = aSymbol.empty() ? nullptr : aSymbol[0];
3653 m_errorMessages.emplace( wxString::Format( wxT(
"Polygon's owner (%d) not found." ),
3659 symbol = libSymbolIt->second;
3660 schsym =
m_symbols.at( libSymbolIt->first );
3670 if( !aSymbol.empty() )
3713 std::vector<LIB_SYMBOL*>& aSymbol )
3735 LIB_SYMBOL* symbol = aSymbol.empty() ? nullptr : aSymbol[0];
3745 m_errorMessages.emplace( wxString::Format( wxT(
"Rounded rectangle's owner (%d) not found." ),
3751 symbol = libSymbolIt->second;
3752 schsym =
m_symbols.at( libSymbolIt->first );
3767 int radius = std::min( width / 2, height / 2 );
3801 if( !aSymbol.empty() )
3818 std::vector<LIB_SYMBOL*>& aSymbol )
3826 VECTOR2I startOffset =
KiROUND( arc_radius * startAngle.
Cos(), -( arc_radius * startAngle.
Sin() ) );
3832 wxCHECK( currentScreen, );
3857 currentScreen->
Append( arc );
3862 LIB_SYMBOL* symbol = aSymbol.empty() ? nullptr : aSymbol[0];
3877 symbol = libSymbolIt->second;
3878 schsym =
m_symbols.at( libSymbolIt->first );
3885 if( !aSymbol.empty() )
3906 circle->SetBodyStyle( bodyStyle );
3947 std::vector<LIB_SYMBOL*>& aSymbol )
3961 wxCHECK( currentScreen, );
3967 std::vector<BEZIER<int>> beziers;
3974 schbezier->
SetStart( bezier.Start );
3977 schbezier->
SetEnd( bezier.End );
3981 currentScreen->
Append( schbezier );
3986 LIB_SYMBOL* symbol = aSymbol.empty() ? nullptr : aSymbol[0];
3996 m_errorMessages.emplace( wxString::Format( wxT(
"Elliptical Arc's owner (%d) not found." ),
4002 symbol = libSymbolIt->second;
4003 schsym =
m_symbols.at( libSymbolIt->first );
4010 if( !aSymbol.empty() )
4027 std::vector<BEZIER<int>> beziers;
4050 schbezier->
SetStart( bezier.Start );
4053 schbezier->
SetEnd( bezier.End );
4064 std::vector<LIB_SYMBOL*>& aSymbol )
4074 VECTOR2I startOffset =
KiROUND( arc_radius * startAngle.
Cos(), -( arc_radius * startAngle.
Sin() ) );
4099 LIB_SYMBOL* symbol = aSymbol.empty() ? nullptr : aSymbol[0];
4109 m_errorMessages.emplace( wxString::Format( wxT(
"Piechart's owner (%d) not found." ),
4115 symbol = libSymbolIt->second;
4116 schsym =
m_symbols.at( libSymbolIt->first );
4126 if( !aSymbol.empty() )
4158 std::vector<LIB_SYMBOL*>& aSymbol )
4183 std::vector<BEZIER<int>> beziers;
4184 std::vector<VECTOR2I> polyPoints;
4191 schbezier->
SetStart( bezier.Start );
4194 schbezier->
SetEnd( bezier.End );
4200 screen->
Append( schbezier );
4202 polyPoints.push_back( bezier.Start );
4212 for(
const VECTOR2I& point : polyPoints )
4215 schpoly->
AddPoint( polyPoints[0] );
4217 screen->
Append( schpoly );
4222 LIB_SYMBOL* symbol = aSymbol.empty() ? nullptr : aSymbol[0];
4237 symbol = libSymbolIt->second;
4238 schsym =
m_symbols.at( libSymbolIt->first );
4245 if( !aSymbol.empty() )
4261 std::vector<BEZIER<int>> beziers;
4262 std::vector<VECTOR2I> polyPoints;
4277 libbezier->
SetStart( bezier.Start );
4280 libbezier->
SetEnd( bezier.End );
4294 polyPoints.push_back( libbezier->
GetStart() );
4308 for(
const VECTOR2I& point : polyPoints )
4311 libline->
AddPoint( polyPoints[0] );
4321 std::vector<LIB_SYMBOL*>& aSymbol )
4341 circle->SetFilled(
false );
4347 LIB_SYMBOL* symbol = aSymbol.empty() ? nullptr : aSymbol[0];
4362 symbol = libSymbolIt->second;
4363 schsym =
m_symbols.at( libSymbolIt->first );
4374 if( !aSymbol.empty() )
4400 std::vector<LIB_SYMBOL*>& aSymbol )
4420 LIB_SYMBOL* symbol = aSymbol.empty() ? nullptr : aSymbol[0];
4435 symbol = libSymbolIt->second;
4436 schsym =
m_symbols.at( libSymbolIt->first );
4446 if( !aSymbol.empty() )
4485 for(
size_t ii = 0; ii < elem.
points.size() - 1; ii++ )
4498 m_errorMessages.emplace( wxT(
"Signal harness, belonging to the part is not currently supported." ),
4505 wxString>& aProperties )
4514 HARNESS& harness = it->second;
4542 m_errorMessages.emplace( wxT(
"Harness connector, belonging to the part is not currently supported." ),
4556 m_errorMessages.emplace( wxString::Format( wxT(
"Harness entry's parent (%d) not found." ),
4562 HARNESS& harness = harnessIt->second;
4599 harness.
m_ports.emplace_back( port );
4611 m_errorMessages.emplace( wxString::Format( wxT(
"Harness type's parent (%d) not found." ),
4617 HARNESS& harness = harnessIt->second;
4623 std::vector<LIB_SYMBOL*>& aSymbol )
4638 rect->
SetEnd( sheetBottomLeft );
4647 LIB_SYMBOL* symbol = aSymbol.empty() ? nullptr : aSymbol[0];
4657 m_errorMessages.emplace( wxString::Format( wxT(
"Rectangle's owner (%d) not found." ),
4663 symbol = libSymbolIt->second;
4664 schsym =
m_symbols.at( libSymbolIt->first );
4674 if( !aSymbol.empty() )
4690 rect->
SetEnd( sheetBottomLeft );
4718 wxCHECK( currentScreen, );
4719 currentScreen->
Append( sheet );
4728 wxCHECK( rootScreen, );
4736 m_sheets.insert( { aIndex, sheet } );
4754 sheetIt->second->AddPin( sheetPin );
4756 wxString pinName = elem.
name;
4759 pinName += wxT(
"{" ) + elem.
harnessType + wxT(
"}" );
4766 VECTOR2I pos = sheetIt->second->GetPosition();
4767 VECTOR2I size = sheetIt->second->GetSize();
5004 aReporter->
Report(
_(
"Power Port with unknown style imported as 'Bar' type." ),
5029 wxString symName( elem.
text );
5030 std::string styleName( magic_enum::enum_name<ASCH_POWER_PORT_STYLE>( elem.
style ) );
5032 if( !styleName.empty() )
5033 symName <<
'_' << styleName;
5042 libSymbol = powerSymbolIt->second;
5048 libSymbol->
SetName( symName );
5053 libSymbol->
SetDescription( wxString::Format(
_(
"Power symbol creates a global label with name '%s'" ),
5063 pin->SetPosition( { 0, 0 } );
5064 pin->SetLength( 0 );
5066 pin->SetVisible(
false );
5123 screen->
Append( symbol );
5151 switch( aElem.
Style )
5181 bool connectionFound = startIsWireTerminal
5182 || startIsBusTerminal
5183 || endIsWireTerminal
5184 || endIsBusTerminal;
5186 if( !connectionFound )
5190 if( harness.m_name.CmpNoCase( aElem.
HarnessType ) != 0 )
5193 BOX2I bbox( harness.m_location, harness.m_size );
5198 startIsBusTerminal =
true;
5199 connectionFound =
true;
5205 endIsBusTerminal =
true;
5206 connectionFound =
true;
5211 if( !connectionFound )
5219 VECTOR2I position = ( startIsWireTerminal || startIsBusTerminal ) ? start :
end;
5222 wxString labelName = aElem.
Name;
5225 labelName += wxT(
"{" ) + aElem.
HarnessType + wxT(
"}" );
5248 switch( aElem.
Style )
5255 if( ( startIsWireTerminal || startIsBusTerminal ) )
5266 if( ( startIsWireTerminal || startIsBusTerminal ) )
5280 if( ( startIsWireTerminal && endIsWireTerminal ) )
5288 else if( startIsBusTerminal && endIsBusTerminal )
5312 screen->
Append( noConnect );
5340 for(
size_t i = 0; i + 1 < elem.
points.size(); i++ )
5359 for(
size_t i = 0; i + 1 < elem.
points.size(); i++ )
5381 screen->
Append( junction );
5393 && component->second.currentpartid != elem.
ownerpartid )
5397 std::unique_ptr<SCH_BITMAP> bitmap = std::make_unique<SCH_BITMAP>(
center );
5409 m_errorMessages.emplace( wxString::Format(
_(
"Embedded file '%s' not found in "
5416 wxString storagePath = wxFileName::CreateTempFileName(
"kicad_import_" );
5419 wxMemoryInputStream fileStream( storageFile->
data.data(), storageFile->
data.size() );
5420 wxZlibInputStream zlibInputStream( fileStream );
5421 wxFFileOutputStream outputStream( storagePath );
5422 outputStream.Write( zlibInputStream );
5426 const bool writeOk = outputStream.IsOk();
5427 const bool closeOk = outputStream.Close();
5429 if( storagePath.IsEmpty() || !writeOk || !closeOk )
5432 wxString::Format(
_(
"Could not write a temporary file while extracting the "
5433 "embedded image '%s'." ),
5437 if( !storagePath.IsEmpty() )
5438 wxRemoveFile( storagePath );
5454 wxString::Format(
_(
"Failed to read embedded image '%s'. "
5455 "The image data may be corrupt or in an "
5456 "unsupported format." ),
5459 wxRemoveFile( storagePath );
5464 wxRemoveFile( storagePath );
5468 if( !wxFileExists( elem.
filename ) )
5471 wxString::Format(
_(
"Could not find image file '%s'. The file "
5472 "path may be specific to a different operating "
5489 wxString::Format(
_(
"Failed to read image file '%s'. The image "
5490 "may be corrupt or in an unsupported "
5501 const double scaleX =
std::abs(
static_cast<double>( expectedImageSize.
x ) / currentImageSize.
x );
5502 const double scaleY =
std::abs(
static_cast<double>( expectedImageSize.
y ) / currentImageSize.
y );
5505 bitmap->SetFlags(
IS_NEW );
5506 screen->
Append( bitmap.release() );
5512 m_altiumSheet = std::make_unique<ASCH_SHEET>( aProperties );
5557 const int gridPitch =
m_schematic->Settings().m_ConnectionGridSize;
5560 m_sheetOffset = { 0, ( pageHeight / gridPitch ) * gridPitch };
5569 wxCHECK( currentScreen, );
5575 m_errorMessages.emplace( wxString::Format( wxT(
"Sheetname's owner (%d) not found." ),
5581 wxString baseName = elem.
text;
5582 baseName.Replace( wxT(
"/" ), wxT(
"_" ) );
5584 wxString sheetName = baseName;
5585 std::set<wxString> sheetNames;
5590 sheetNames.insert( sheet->
GetName() );
5593 for(
int ii = 1; ; ++ii )
5595 if( sheetNames.find( sheetName ) == sheetNames.end() )
5598 sheetName = baseName + wxString::Format( wxT(
"_%d" ), ii );
5604 sheetNameField->
SetText( sheetName );
5618 m_errorMessages.emplace( wxString::Format( wxT(
"Filename's owner (%d) not found." ),
5644 m_errorMessages.emplace( wxString::Format( wxT(
"Designator's owner (%d) not found." ),
5658 bool emptyRef = elem.
text.IsEmpty();
5663 bool visible = !emptyRef;
5680 std::vector<LIB_SYMBOL*>& aSymbol,
5681 std::vector<int>& aFontSizes )
5690 bool emptyRef = elem.
text.IsEmpty();
5691 SCH_FIELD& refField = symbol->GetReferenceField();
5694 refField.
SetText( wxT(
"X" ) );
5701 if( elem.
fontId > 0 && elem.
fontId <=
static_cast<int>( aFontSizes.size() ) )
5703 int size = aFontSizes[elem.
fontId - 1];
5720 busWireEntry->
SetSize( { vector.
x, vector.
y } );
5723 screen->
Append( busWireEntry );
5732 static const std::map<wxString, wxString> variableMap = {
5733 {
"COMMENT",
"VALUE" },
5734 {
"VALUE",
"ALTIUM_VALUE" },
5740 wxString paramName = elem.
name.Upper();
5743 if( elem.
text ==
"*" )
5745 if( paramName !=
"SHEETNUMBER" && paramName !=
"TITLE" && paramName !=
"REVISION" && paramName !=
"DATE"
5746 && paramName !=
"COMPANYNAME" )
5754 if( paramName ==
"SHEETNUMBER" )
5758 else if( paramName ==
"TITLE" )
5762 else if( paramName ==
"REVISION" )
5766 else if( paramName ==
"DATE" )
5770 else if( paramName ==
"COMPANYNAME" )
5791 wxString upperName = elem.
name.Upper();
5793 if( upperName ==
"COMMENT" )
5799 wxString fieldName = elem.
name.Upper();
5801 if( fieldName.IsEmpty() )
5803 int disambiguate = 1;
5807 fieldName = wxString::Format(
"ALTIUM_UNNAMED_%d", disambiguate++ );
5809 if( !symbol->
GetField( fieldName ) )
5813 else if( fieldName ==
"VALUE" )
5815 fieldName =
"ALTIUM_VALUE";
5837 std::vector<LIB_SYMBOL*>& aSymbol,
5838 std::vector<int>& aFontSizes )
5862 std::map<wxString, wxString> variableMap = {
5863 {
"COMMENT",
"VALUE" },
5869 wxString upperName = elem.
name.Upper();
5871 if( upperName ==
"COMMENT" )
5873 field = &libSymbol->GetValueField();
5877 wxString fieldNameStem = elem.
name;
5878 wxString fieldName = fieldNameStem;
5879 int disambiguate = 1;
5881 if( fieldName.IsEmpty() )
5883 fieldNameStem =
"ALTIUM_UNNAMED";
5884 fieldName =
"ALTIUM_UNNAMED_1";
5887 else if( upperName ==
"VALUE" )
5889 fieldNameStem =
"ALTIUM_VALUE";
5890 fieldName =
"ALTIUM_VALUE";
5894 while( libSymbol->GetField( fieldName ) )
5895 fieldName = wxString::Format(
"%s_%d", fieldNameStem, disambiguate++ );
5898 libSymbol->AddField( new_field );
5909 if( elem.
fontId > 0 && elem.
fontId <=
static_cast<int>( aFontSizes.size() ) )
5911 int size = aFontSizes[elem.
fontId - 1];
5925 const std::map<wxString, wxString>& aProperties )
5934 std::vector<LIB_SYMBOL*>& aSymbol )
5938 if( elem.
type != wxS(
"PCBLIB" ) )
5942 if( aSymbol.size() == 0 && !elem.
isCurrent )
5950 wxArrayString fpFilters;
5951 fpFilters.Add( wxString::Format( wxS(
"*%s*" ), elem.
name ) );
5954 if( !aSymbol.empty() )
5960 symbol->SetFPFilters( fpFilters );
5971 m_errorMessages.emplace( wxString::Format( wxT(
"Implementation's owner (%d) not found." ),
5977 const auto& libSymbolIt =
m_libSymbols.find( implementationOwnerIt->second );
5981 m_errorMessages.emplace( wxString::Format( wxT(
"Footprint's owner (%d) not found." ),
5982 implementationOwnerIt->second ),
5989 libSymbolIt->second->SetFPFilters( fpFilters );
5999 wxString>& aProperties )
6016 std::vector<wxString> bodyStyleNames;
6019 bodyStyleNames.push_back( wxString::Format(
"Display %d", i + 1 ) );
6032 std::vector<int> fontSizes;
6033 struct SYMBOL_PIN_FRAC
6042 std::map<wxString, ALTIUM_SYMBOL_DATA> syms = aAltiumLibFile.
GetLibSymbols(
nullptr );
6044 for(
auto& [
name, entry] : syms )
6049 std::map<int, SYMBOL_PIN_FRAC> pinFracs;
6051 if( entry.m_pinsFrac )
6053 auto parse_binary_pin_frac =
6054 [&](
const std::string& binaryData ) -> std::map<wxString, wxString>
6056 std::map<wxString, wxString>
result;
6062 SYMBOL_PIN_FRAC pinFrac;
6066 pinFrac.len_frac = binreader.
ReadInt32();
6067 pinFracs.insert( { pinFracData.first, pinFrac } );
6079 std::vector<LIB_SYMBOL*> symbols;
6086 std::map<wxString, wxString> properties = reader.
ReadProperties();
6091 THROW_IO_ERROR(
"LibSymbol does not start with COMPONENT record" );
6096 auto handleBinaryPinLambda =
6097 [&](
const std::string& binaryData ) -> std::map<wxString, wxString>
6099 std::map<wxString, wxString>
result;
6103 int32_t recordId = binreader.
ReadInt32();
6108 result[
"RECORD"] = wxString::Format(
"%d", recordId );
6110 result[
"OWNERPARTID"] = wxString::Format(
"%d", binreader.
ReadInt16() );
6111 result[
"OWNERPARTDISPLAYMODE"] = wxString::Format(
"%d", binreader.
ReadByte() );
6112 result[
"SYMBOL_INNEREDGE"] = wxString::Format(
"%d", binreader.
ReadByte() );
6113 result[
"SYMBOL_OUTEREDGE"] = wxString::Format(
"%d", binreader.
ReadByte() );
6114 result[
"SYMBOL_INNER"] = wxString::Format(
"%d", binreader.
ReadByte() );
6115 result[
"SYMBOL_OUTER"] = wxString::Format(
"%d", binreader.
ReadByte() );
6118 result[
"ELECTRICAL"] = wxString::Format(
"%d", binreader.
ReadByte() );
6119 result[
"PINCONGLOMERATE"] = wxString::Format(
"%d", binreader.
ReadByte() );
6120 result[
"PINLENGTH"] = wxString::Format(
"%d", binreader.
ReadInt16() );
6121 result[
"LOCATION.X"] = wxString::Format(
"%d", binreader.
ReadInt16() );
6122 result[
"LOCATION.Y"] = wxString::Format(
"%d", binreader.
ReadInt16() );
6128 if(
auto it = pinFracs.find( pin_index ); it != pinFracs.end() )
6130 result[
"LOCATION.X_FRAC"] = wxString::Format(
"%d", it->second.x_frac );
6131 result[
"LOCATION.Y_FRAC"] = wxString::Format(
"%d", it->second.y_frac );
6132 result[
"PINLENGTH_FRAC"] = wxString::Format(
"%d", it->second.len_frac );
6136 std::vector<std::string> partSeqSplit =
split( partSeq,
"|" );
6138 if( partSeqSplit.size() == 3 )
6140 result[
"PART"] = partSeqSplit[0];
6141 result[
"SEQ"] = partSeqSplit[2];
6149 std::map<wxString, wxString> properties = reader.
ReadProperties( handleBinaryPinLambda );
6151 if( properties.empty() )
6200 m_errorMessages.emplace( wxString::Format(
_(
"Unknown or unexpected record id %d found in %s." ),
6220 if( valField.
GetText().IsEmpty() )
6241 wxFileName fn( aLibraryPath );
6243 if( fn.IsFileReadable() && fn.GetModificationTime().IsValid() )
6244 return fn.GetModificationTime().GetValue().GetValue();
6251 const std::map<std::string, UTF8>* aProperties )
6264 std::vector<std::unique_ptr<ALTIUM_COMPOUND_FILE>> compoundFiles;
6266 wxFileName fileName( aLibraryPath );
6271 if( aLibraryPath.Lower().EndsWith( wxS(
".schlib" ) ) )
6275 compoundFiles.push_back( std::make_unique<ALTIUM_COMPOUND_FILE>( aLibraryPath ) );
6277 else if( aLibraryPath.Lower().EndsWith( wxS(
".intlib" ) ) )
6281 std::unique_ptr<ALTIUM_COMPOUND_FILE> intCom = std::make_unique<ALTIUM_COMPOUND_FILE>( aLibraryPath );
6283 std::map<wxString, const CFB::COMPOUND_FILE_ENTRY*> schLibFiles = intCom->EnumDir(
L"SchLib" );
6285 for(
const auto& [schLibName, cfe] : schLibFiles )
6287 std::unique_ptr<ALTIUM_COMPOUND_FILE> decodedStream = std::make_unique<ALTIUM_COMPOUND_FILE>();
6289 if( intCom->DecodeIntLibStream( *cfe, decodedStream.get() ) )
6290 compoundFiles.emplace_back( std::move( decodedStream ) );
6296 for(
const std::unique_ptr<ALTIUM_COMPOUND_FILE>& altiumSchFilePtr : compoundFiles )
6299 cacheMapRef.insert( parsed.begin(), parsed.end() );
6304 catch(
const CFB::CFBException& exception )
6308 catch(
const std::exception& exc )
6316 std::vector<int>& aFontSizes )
6318 const CFB::COMPOUND_FILE_ENTRY* file = aAltiumSchFile.
FindStream( {
"FileHeader" } );
6320 if( file ==
nullptr )
6328 std::map<wxString, wxString> properties = reader.
ReadProperties();
6332 if( libtype.CmpNoCase(
"Protel for Windows - Schematic Library Editor Binary File Version 5.0" ) )
6333 THROW_IO_ERROR(
_(
"Expected Altium Schematic Library file version 5.0" ) );
6335 for(
auto& [key, value] : properties )
6337 wxString upperKey = key.Upper();
6340 if( upperKey.StartsWith(
"SIZE", &remaining ) )
6342 if( !remaining.empty() )
6344 int ind = wxAtoi( remaining );
6349 if(
static_cast<int>( aFontSizes.size() ) < ind )
6350 aFontSizes.resize( ind );
6353 int scaled =
schIUScale.MilsToIU( wxAtoi( value ) * 72.0 / 10.0 );
6354 aFontSizes[ind - 1] = scaled;
6362 const std::map<std::string, UTF8>* aProperties,
6363 std::function<
void(
const wxString&,
LIB_SYMBOL*)> aInserter )
6367 bool powerSymbolsOnly = ( aProperties &&
6374 for(
auto& [libnameStr, libSymbol] : it->second )
6376 if( powerSymbolsOnly && !libSymbol->IsPower() )
6379 aInserter( libnameStr, libSymbol );
6386 const std::map<std::string, UTF8>* aProperties )
6391 aSymbolNameList.Add( aStr );
6397 const wxString& aLibraryPath,
6398 const std::map<std::string, UTF8>* aProperties )
6403 aSymbolList.emplace_back( aSymbol );
6409 const std::map<std::string, UTF8>* aProperties )
6417 auto it2 = it->second.find( aAliasName );
6419 if( it2 != it->second.end() )
const int ALTIUM_COMPONENT_NONE
wxString AltiumPinDesignatorToKiCad(const wxString &aDesignator)
Convert an Altium pin designator string to the equivalent KiCad pin number.
wxString AltiumSchSpecialStringsToKiCadVariables(const wxString &aString, const std::map< wxString, wxString > &aOverrides, std::set< wxString > *aUnmapped)
Convert the special strings in Altium schematic text to KiCad variables.
wxString AltiumEscapeTextVars(const wxString &aText)
Escape the KiCad variables and expressions in literal Altium text, which Altium shows as typed.
wxString AltiumPinNamesToKiCad(wxString &aString)
LIB_ID AltiumToKiCadLibID(const wxString &aLibName, const wxString &aLibReference)
std::vector< ALTIUM_PROJECT_VARIANT > ParseAltiumProjectVariants(const wxString &aPrjPcbPath)
Parse all [ProjectVariantN] sections from an Altium .PrjPcb project file.
std::map< wxString, wxString > ParseAltiumProjectParameters(const wxString &aPrjPcbPath)
Parse all [ParameterN] sections from an Altium .PrjPcb project file.
bool AltiumPowerPortNamesTakePriority(const wxString &aPrjPcbPath)
Read the project's Power Port Names Take Priority netlist option.
void ApplyAltiumProjectParametersToProject(PROJECT *aProject, const std::map< wxString, wxString > &aParameters)
Register Altium project parameters as KiCad project text variables so that imported board text refere...
constexpr EDA_IU_SCALE schIUScale
constexpr double ARC_LOW_DEF_MM
void TransformEllipseToBeziers(const ELLIPSE< T > &aEllipse, std::vector< BEZIER< T > > &aBeziers)
Transforms an ellipse or elliptical arc into a set of quadratic Bezier curves that approximate it.
constexpr BOX2I KiROUND(const BOX2D &aBoxD)
std::map< wxString, ValueType, DETAIL::CASE_INSENSITIVE_COMPARER > CASE_INSENSITIVE_MAP
std::map< wxString, wxString > ReadProperties()
size_t GetRemainingBytes() const
std::map< wxString, wxString > ReadProperties(std::function< std::map< wxString, wxString >(const std::string &)> handleBinaryData=[](const std::string &) { return std::map< wxString, wxString >();})
std::string ReadShortPascalString()
std::map< wxString, ALTIUM_SYMBOL_DATA > GetLibSymbols(const CFB::COMPOUND_FILE_ENTRY *aStart) const
const CFB::COMPOUND_FILE_ENTRY * FindStream(const std::vector< std::string > &aStreamPath) const
std::pair< int, std::string * > ReadCompressedString()
static int ReadInt(const std::map< wxString, wxString > &aProps, const wxString &aKey, int aDefault)
static wxString ReadString(const std::map< wxString, wxString > &aProps, const wxString &aKey, const wxString &aDefault)
Bezier curves to polygon converter.
void GetPoly(std::vector< VECTOR2I > &aOutput, int aMaxError=10)
Convert a Bezier curve to a polygon.
Generic cubic Bezier representation.
constexpr BOX2< Vec > & Inflate(coord_type dx, coord_type dy)
Inflates the rectangle horizontally by dx and vertically by dy.
constexpr BOX2< Vec > & Merge(const BOX2< Vec > &aRect)
Modify the position and size of the rectangle in order to contain aRect.
constexpr const Vec GetCenter() const
constexpr bool Contains(const Vec &aPoint) const
constexpr coord_type GetTop() const
constexpr void Offset(coord_type dx, coord_type dy)
constexpr coord_type GetBottom() const
static const COLOR4D UNSPECIFIED
For legacy support; used as a value to indicate color hasn't been set yet.
Calculate the connectivity of a schematic and generate netlists.
const NET_MAP & GetNetMap() const
void Recalculate(const SCH_SHEET_LIST &aSheetList, bool aUnconditional=false, std::function< void(SCH_ITEM *)> *aChangedItemHandler=nullptr, PROGRESS_REPORTER *aProgressReporter=nullptr)
Update the connection graph for the given list of sheets.
A subgraph is a set of items that are electrically connected on a single sheet.
bool IsHorizontal() 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.
virtual void SetEnd(const VECTOR2I &aEnd)
virtual void SetCenter(const VECTOR2I &aCenter)
FILL_T GetFillMode() const
void SetLineStyle(const LINE_STYLE aStyle)
virtual void SetBezierC2(const VECTOR2I &aPt)
virtual void SetBezierC1(const VECTOR2I &aPt)
void SetFillColor(const COLOR4D &aColor)
void RebuildBezierToSegmentsPointsList(int aMaxError)
Rebuild the m_bezierPoints vertex list that approximate the Bezier curve by a list of segments.
const VECTOR2I & GetStart() const
Return the starting point of the graphic.
COLOR4D GetFillColor() const
virtual void SetWidth(int aWidth)
void SetFillMode(FILL_T aFill)
virtual void SetStart(const VECTOR2I &aStart)
A mix-in class (via multiple inheritance) that handles texts such as labels, parts,...
virtual void SetTextSize(VECTOR2I aNewSize, bool aEnforceMinTextSize=true)
virtual const wxString & GetText() const
Return the string associated with the text object.
virtual void SetTextPos(const VECTOR2I &aPoint)
void SetAttributes(const EDA_TEXT &aSrc, bool aSetPosition=true)
Set the text attributes from another instance.
void SetVertJustify(GR_TEXT_V_ALIGN_T aType)
GR_TEXT_H_ALIGN_T GetHorizJustify() const
virtual void SetVisible(bool aVisible)
virtual EDA_ANGLE GetTextAngle() const
void SetBold(bool aBold)
Set the text to be bold - this will also update the font if needed.
GR_TEXT_V_ALIGN_T GetVertJustify() const
virtual void SetText(const wxString &aText)
virtual void SetTextAngle(const EDA_ANGLE &aAngle)
void SetItalic(bool aItalic)
Set the text to be italic - this will also update the font if needed.
void SetHorizJustify(GR_TEXT_H_ALIGN_T aType)
EE_TYPE Overlapping(const BOX2I &aRect) const
EE_TYPE OfType(KICAD_T aType) const
Plain ellipse / elliptical-arc data.
RAII class to set and restore the fontconfig reporter.
const wxString & GetName() const
Return a brief hard coded name for this IO interface.
REPORTER * m_reporter
Reporter to log errors/warnings to, may be nullptr.
PROGRESS_REPORTER * m_progressReporter
Progress reporter to track the progress of the operation, may be nullptr.
virtual bool CanReadLibrary(const wxString &aFileName) const
Checks if this IO object can read the specified library file/directory.
A color representation with 4 components: red, green, blue, alpha.
COLOR4D WithAlpha(double aAlpha) const
Return a color with the same color, but the given alpha.
COLOR4D & FromCSSRGBA(int aRed, int aGreen, int aBlue, double aAlpha=1.0)
Initialize the color from a RGBA value with 0-255 red/green/blue and 0-1 alpha.
wxString AsString() const
wxString AsString() const
A logical library item identifier and consists of various portions much like a URI.
static UTF8 FixIllegalChars(const UTF8 &aLibItemName, bool aLib)
Replace illegal LIB_ID item name characters with underscores '_'.
Define a library symbol object.
void FixupDrawItems()
This function finds the filled draw items that are covering up smaller draw items and replaces their ...
void SetBodyStyleNames(const std::vector< wxString > &aBodyStyleNames)
wxString GetName() const override
void SetUnitCount(int aCount, bool aDuplicateDrawItems)
Set the units per symbol count.
void SetDescription(const wxString &aDescription)
Set the Description field text value.
void SetKeyWords(const wxString &aKeyWords)
SCH_FIELD & GetValueField()
int GetBodyStyleCount() const override
The body styles are a property of the drawings, which a derived symbol inherits from its root symbol ...
int GetUnitCount() const override
void SetLibId(const LIB_ID &aLibId)
void AddDrawItem(SCH_ITEM *aItem, bool aSort=true)
Add a new draw aItem to the draw object list and sort according to aSort.
virtual void SetName(const wxString &aName)
SCH_FIELD & GetReferenceField()
static LOAD_INFO_REPORTER & GetInstance()
Describe the page size and margins of a paper page on which to eventually print or plot.
int GetHeightIU(double aIUScale) const
Get the page height in IU.
bool SetType(PAGE_SIZE_TYPE aPageSize, bool aIsPortrait=false)
Set the name of the page type and also the sizes and margins commonly associated with that type name.
static void SetCustomWidthMils(double aWidthInMils)
Set the width of Custom page in mils for any custom page constructed or made via SetType() after maki...
static void SetCustomHeightMils(double aHeightInMils)
Set the height of Custom page in mils for any custom page constructed or made via SetType() after mak...
A REFERENCE_IMAGE is a wrapper around a BITMAP_IMAGE that is displayed in an editor as a reference fo...
bool ReadImageFile(const wxString &aFullFilename)
Read and store an image file.
void SetImageScale(double aScale)
Set the image "zoom" value.
A pure virtual class used to derive REPORTER objects from.
virtual REPORTER & Report(const wxString &aText, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED)
Report a string with a given severity.
Holds all the data relating to one schematic.
bool IsValid() const
A simple test if the schematic is loaded, not a complete one.
void SetTopLevelSheets(const std::vector< SCH_SHEET * > &aSheets)
Replace the top level sheets, rebuilding the hierarchy and connectivity around them.
void SetSize(const VECTOR2I &aSize)
VECTOR2I GetPosition() const override
Class for a wire to bus entry.
static bool IsBusLabel(const wxString &aLabel)
Test if aLabel has a bus notation.
VECTOR2I GetPosition() const override
virtual const wxString & GetText() const override
Return the string associated with the text object.
void SetPosition(const VECTOR2I &aPosition) override
void SetText(const wxString &aText) override
void SetNameShown(bool aShown=true)
SCH_FIELD * GetField(FIELD_T aFieldType)
Return a mandatory field in this label.
void SetSpinStyle(SPIN_STYLE aSpinStyle) override
void SetSpinStyle(SPIN_STYLE aSpinStyle) override
void ParseFileHeader(const ALTIUM_COMPOUND_FILE &aAltiumSchFile)
std::vector< wxFileName > m_projectDocuments
void ParseSignalHarness(const std::map< wxString, wxString > &aProperties)
std::map< int, ASCH_TEMPLATE > m_altiumTemplates
std::map< int, ASCH_SYMBOL > m_altiumComponents
void ParsePort(const ASCH_PORT &aElem)
void ParseNote(const std::map< wxString, wxString > &aProperties)
std::map< std::vector< wxString >, SCH_SCREEN * > m_loadedScreens
void ParseAltiumSch(const wxString &aFileName)
std::vector< ASCH_PORT > m_altiumPortsCurrentSheet
void ParseSheetName(const std::map< wxString, wxString > &aProperties)
void ParseBusEntry(const std::map< wxString, wxString > &aProperties)
wxFileName ResolveSheetFileName(const wxString &aParentPath, const wxString &aSheetFileName) const
SCH_SHEET * getCurrentSheet()
void ParseStorage(const ALTIUM_COMPOUND_FILE &aAltiumSchFile)
std::map< wxString, LIB_SYMBOL * > m_powerSymbols
void ParseBus(const std::map< wxString, wxString > &aProperties)
void ParseFileName(const std::map< wxString, wxString > &aProperties)
static bool isASCIIFile(const wxString &aFileName)
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...
std::map< int, SCH_SHEET * > m_sheets
void ParseLibHeader(const ALTIUM_COMPOUND_FILE &aAltiumSchFile, std::vector< int > &aFontSizes)
void ParseHarnessPort(const ASCH_PORT &aElem)
void ParseRoundRectangle(const std::map< wxString, wxString > &aProperties, std::vector< LIB_SYMBOL * > &aSymbol=nullsym)
void pruneCyclicSheets(const std::vector< SCH_SHEET * > &aCyclicSheets, SCH_SCREEN *aScreen)
Remove sheet symbols referencing a parse-stack file (an unrepresentable cycle), converting their pins...
int GetModifyHash() const override
Return the modification hash from the library cache.
void ParseLibDesignator(const std::map< wxString, wxString > &aProperties, std::vector< LIB_SYMBOL * > &aSymbol=nullsym, std::vector< int > &aFontSize=nullint)
std::map< wxString, CASE_INSENSITIVE_MAP< LIB_SYMBOL * > > m_libCache
std::map< int, int > m_altiumImplementationList
void attachEmptySheetScreen(SCH_SHEET *aSheet, const wxString &aMissingFile)
Give a sheet whose source file is missing an empty screen with a file of its own; aMissingFile is emp...
std::map< wxString, SCH_SCREEN * > m_missingScreens
void ParseTextFrame(const std::map< wxString, wxString > &aProperties, std::vector< LIB_SYMBOL * > &aSymbol=nullsym, std::vector< int > &aFontSize=nullint)
void ParsePolygon(const std::map< wxString, wxString > &aProperties, std::vector< LIB_SYMBOL * > &aSymbol=nullsym)
void fixupSymbolPinNameNumbers(SYMBOL *aSymbol)
void EnsureSheetSymbolNames()
void ParseRecord(int index, std::map< wxString, wxString > &properties, const wxString &aSectionName)
std::vector< ASCH_PORT > m_altiumHarnessPortsCurrentSheet
void ParseDesignator(const std::map< wxString, wxString > &aProperties)
int m_harnessOwnerIndexOffset
void ParsePortHelper(const ASCH_PORT &aElem)
std::set< wxString > m_subsheetFiles
static bool checkFileHeader(const wxString &aFileName)
long long getLibraryTimestamp(const wxString &aLibraryPath) const
void ParseSheetEntry(const std::map< wxString, wxString > &aProperties)
static bool isBinaryFile(const wxString &aFileName)
void ParseHarnessType(const std::map< wxString, wxString > &aProperties)
void ParseJunction(const std::map< wxString, wxString > &aProperties)
void ParseLibParameter(const std::map< wxString, wxString > &aProperties, std::vector< LIB_SYMBOL * > &aSymbol=nullsym, std::vector< int > &aFontSize=nullint)
std::set< wxString > m_parsedFiles
void ParseASCIISchematic(const wxString &aFileName)
void ParsePolyline(const std::map< wxString, wxString > &aProperties, std::vector< LIB_SYMBOL * > &aSymbol=nullsym)
std::unique_ptr< ASCH_SHEET > m_altiumSheet
void ParseComponent(int aIndex, const std::map< wxString, wxString > &aProperties)
std::unique_ptr< TITLE_BLOCK > m_currentTitleBlock
SCH_SHEET * LoadSchematicProject(SCHEMATIC *aSchematic, const std::map< std::string, UTF8 > *aProperties)
void ParseImage(const std::map< wxString, wxString > &aProperties)
void ParseArc(const std::map< wxString, wxString > &aProperties, std::vector< LIB_SYMBOL * > &aSymbol=nullsym)
void ParseNetLabel(const std::map< wxString, wxString > &aProperties)
void ParseNoERC(const std::map< wxString, wxString > &aProperties)
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,...
std::unordered_map< wxString, SEVERITY > m_errorMessages
std::map< wxString, int > m_parsingFiles
void ParseImplementationList(int aIndex, const std::map< wxString, wxString > &aProperties)
std::vector< LIB_SYMBOL * > ParseLibComponent(const std::map< wxString, wxString > &aProperties)
void ParseSheet(const std::map< wxString, wxString > &aProperties)
void ParseParameter(const std::map< wxString, wxString > &aProperties)
bool ShouldPutItemOnSheet(int aOwnerindex)
void NormalizeRepeatedSheetInstances()
void AddLibTextBox(const ASCH_TEXT_FRAME *aElem, std::vector< LIB_SYMBOL * > &aSymbol=nullsym, std::vector< int > &aFontSize=nullint)
bool CanReadSchematicFile(const wxString &aFileName) const override
Checks if this SCH_IO can read the specified schematic file.
void ParsePieChart(const std::map< wxString, wxString > &aProperties, std::vector< LIB_SYMBOL * > &aSymbol=nullsym)
void ParseEllipticalArc(const std::map< wxString, wxString > &aProperties, std::vector< LIB_SYMBOL * > &aSymbol=nullsym)
std::map< int, HARNESS > m_altiumHarnesses
void ParseEllipse(const std::map< wxString, wxString > &aProperties, std::vector< LIB_SYMBOL * > &aSymbol=nullsym)
std::set< wxString > m_sheetSpecialStrings
void ParseWire(const std::map< wxString, wxString > &aProperties)
void ParseHarnessEntry(const std::map< wxString, wxString > &aProperties)
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 ParseImplementation(const std::map< wxString, wxString > &aProperties, std::vector< LIB_SYMBOL * > &aSymbol=nullsym)
void ParseTemplate(int aIndex, const std::map< wxString, wxString > &aProperties)
void ParseAdditional(const ALTIUM_COMPOUND_FILE &aAltiumSchFile)
friend struct PARSE_FILE_GUARD
std::set< wxString > m_sheetFiles
std::set< wxString > m_unsetSheetParams
void AddTextBox(const ASCH_TEXT_FRAME *aElem)
void ParsePowerPort(const std::map< wxString, wxString > &aProperties)
bool CanReadLibrary(const wxString &aFileName) const override
Checks if this IO object can read the specified library file/directory.
std::map< const SCH_SYMBOL *, wxString > m_altiumSymbolToUid
const ASCH_STORAGE_FILE * GetFileFromStorage(const wxString &aFilename) const
void ParseRectangle(const std::map< wxString, wxString > &aProperties, std::vector< LIB_SYMBOL * > &aSymbol=nullsym)
void doEnumerateSymbolLib(const wxString &aLibraryPath, const std::map< std::string, UTF8 > *aProperties, std::function< void(const wxString &, LIB_SYMBOL *)> aInserter)
void NameNetsAfterNetLabels()
Name power nets after their net labels, as Altium does unless Power Port Names Take Priority is set.
std::vector< ASCH_STORAGE_FILE > m_altiumStorage
SCH_SHEET_PATH m_sheetPath
void PostProcessBusLabels()
wxString claimSheetFile(const wxString &aStem)
Claim a file in the project folder for a sheet screen that neither the root nor another sheet holds,...
void ParseLabel(const std::map< wxString, wxString > &aProperties, std::vector< LIB_SYMBOL * > &aSymbol=nullsym, std::vector< int > &aFontSize=nullint)
CASE_INSENSITIVE_MAP< LIB_SYMBOL * > ParseLibFile(const ALTIUM_COMPOUND_FILE &aAltiumSchFile)
void ParseBezier(const std::map< wxString, wxString > &aProperties, std::vector< LIB_SYMBOL * > &aSymbol=nullsym)
void ParseLine(const std::map< wxString, wxString > &aProperties, std::vector< LIB_SYMBOL * > &aSymbol=nullsym)
void ParseCircle(const std::map< wxString, wxString > &aProperties, std::vector< LIB_SYMBOL * > &aSymbol=nullsym)
std::map< int, SCH_SYMBOL * > m_symbols
void ParseSheetSymbol(int aIndex, const std::map< wxString, wxString > &aProperties)
std::map< wxString, long long > m_timestamps
wxFileName getLibFileName()
SCH_SCREEN * getCurrentScreen()
void ParsePin(const std::map< wxString, wxString > &aProperties, std::vector< LIB_SYMBOL * > &aSymbol=nullsym)
std::map< int, LIB_SYMBOL * > m_libSymbols
void ParseHarnessConnector(int aIndex, const std::map< wxString, wxString > &aProperties)
void ensureLoadedLibrary(const wxString &aLibraryPath, const std::map< std::string, UTF8 > *aProperties)
virtual bool CanReadSchematicFile(const wxString &aFileName) const
Checks if this SCH_IO can read the specified schematic file.
SCH_IO(const wxString &aName)
Base class for any item which can be embedded within the SCHEMATIC container class,...
virtual void SetBodyStyle(int aBodyStyle)
virtual void SetUnit(int aUnit)
void MirrorHorizontally(int aCenter) override
Mirror item horizontally about aCenter.
void SetShape(LABEL_FLAG_SHAPE aShape)
const BOX2I GetBoundingBox() const override
Return the bounding box of the label including its fields.
void MirrorVertically(int aCenter) override
Mirror item vertically about aCenter.
void AutoplaceFields(SCH_SCREEN *aScreen, AUTOPLACE_ALGO aAlgo) override
virtual void SetSpinStyle(SPIN_STYLE aSpinStyle)
Segment description base class to describe items which have 2 end points (track, wire,...
void SetStartPoint(const VECTOR2I &aPosition)
bool HitTest(const VECTOR2I &aPosition, int aAccuracy=0) const override
Test if aPosition is inside or on the boundary of this item.
std::vector< VECTOR2I > GetConnectionPoints() const override
Add all the connection points for this item to aPoints.
bool IsWire() const
Return true if the line is a wire.
const BOX2I GetBoundingBox() const override
Return the orthogonal bounding box of this object for display purposes.
void SetLineWidth(const int aSize)
VECTOR2I GetEndPoint() const
VECTOR2I GetStartPoint() const
SEG GetSeg() const
Get the geometric aspect of the wire as a SEG.
bool IsBus() const
Return true if the line is a bus.
virtual void SetStroke(const STROKE_PARAMS &aStroke) override
KIGFX::COLOR4D GetLineColor() const
Return COLOR4D::UNSPECIFIED if a custom color hasn't been set for this line.
void SetLineColor(const KIGFX::COLOR4D &aColor)
void SetEndPoint(const VECTOR2I &aPosition)
bool IsGlobalPower() const
Return whether this pin forms a global power connection: i.e., is part of a power symbol and of type ...
Container class that holds multiple SCH_SCREEN objects in a hierarchy.
void UpdateSymbolLinks(REPORTER *aReporter=nullptr)
Initialize the LIB_SYMBOL reference for each SCH_SYMBOL found in the full schematic.
std::vector< SCH_SHEET_INSTANCE > m_sheetInstances
void SetTitleBlock(const TITLE_BLOCK &aTitleBlock)
void Append(SCH_ITEM *aItem, bool aUpdateLibSymbol=true)
void AddBusAlias(std::shared_ptr< BUS_ALIAS > aAlias)
Add a bus alias definition.
void SetPageSettings(const PAGE_INFO &aPageSettings)
EE_RTREE & Items()
Get the full RTree, usually for iterating.
const wxString & GetFileName() const
bool IsTerminalPoint(const VECTOR2I &aPosition, int aLayer) const
Test if aPosition is a connection point on aLayer.
void SetFileName(const wxString &aFileName)
Set the file name for this screen to aFileName.
bool Remove(SCH_ITEM *aItem, bool aUpdateLibSymbol=true)
Remove aItem from the schematic associated with this screen.
void Update(SCH_ITEM *aItem, bool aUpdateLibSymbol=true)
Refresh a changed item in the tree and invalidate connectivity.
void DeleteItem(SCH_ITEM *aItem)
Remove aItem from the linked list and deletes the object.
void SetPosition(const VECTOR2I &aPos) override
void SetFilled(bool aFilled) override
void SetStroke(const STROKE_PARAMS &aStroke) override
void AddPoint(const VECTOR2I &aPosition)
STROKE_PARAMS GetStroke() const override
VECTOR2I GetPosition() const override
A container for handling SCH_SHEET_PATH objects in a flattened hierarchy.
wxString GetNextPageNumber() const
Handle access to a stack of flattened SCH_SHEET objects by way of a path for creating a flattened sch...
KIID_PATH Path() const
Get the sheet path as an KIID_PATH.
SCH_SCREEN * LastScreen()
void SetPageNumber(const wxString &aPageNumber)
Set the sheet instance user definable page number.
SCH_SHEET * Last() const
Return a pointer to the last SCH_SHEET of the list.
void push_back(SCH_SHEET *aSheet)
Forwarded method from std::vector.
void pop_back()
Forwarded method from std::vector.
Define a sheet pin (label) used in sheets to create hierarchical schematics.
void SetPosition(const VECTOR2I &aPosition) override
void SetSide(SHEET_SIDE aEdge)
Sheet symbol placed in a schematic, and is the entry point for a sub schematic.
void SetBorderColor(KIGFX::COLOR4D aColor)
void SetFileName(const wxString &aFilename)
wxString GetFileName() const
Return the filename corresponding to this sheet.
void SetBackgroundColor(KIGFX::COLOR4D aColor)
void SetName(const wxString &aName)
SCH_SCREEN * GetScreen() const
void SetScreen(SCH_SCREEN *aScreen)
Set the SCH_SCREEN associated with this sheet to aScreen.
Variant information for a schematic symbol.
void InitializeAttributes(const SCH_SYMBOL &aSymbol)
void SetLibId(const LIB_ID &aName)
void SetPosition(const VECTOR2I &aPosition) override
void SetBodyStyle(int aBodyStyle) override
bool AddSheetPathReferenceEntryIfMissing(const KIID_PATH &aSheetPath)
Add an instance to the alternate references list (m_instances), if this entry does not already exist.
void SetRef(const SCH_SHEET_PATH *aSheet, const wxString &aReference)
Set the reference for the given sheet path for this symbol.
void GetFields(std::vector< SCH_FIELD * > &aVector, bool aVisibleOnly) const override
Populate a std::vector with SCH_FIELDs, sorted in ordinal order.
void SetOrientation(int aOrientation)
Compute the new transform matrix based on aOrientation for the symbol which is applied to the current...
void SetFootprintFieldText(const wxString &aFootprint)
VECTOR2I GetPosition() const override
bool ResolveTextVar(const SCH_SHEET_PATH *aPath, wxString *token, int aDepth=0) const
Resolve any references to system tokens supported by the symbol.
void SetValueFieldText(const wxString &aValue, const SCH_SHEET_PATH *aInstance=nullptr, const wxString &aVariantName=wxEmptyString)
void AddVariant(const SCH_SHEET_PATH &aInstance, const SCH_SYMBOL_VARIANT &aVariant)
SCH_FIELD * AddField(const SCH_FIELD &aField)
Add a field to the symbol.
void SetLibSymbol(LIB_SYMBOL *aLibSymbol)
Set this schematic symbol library symbol reference to aLibSymbol.
const wxString GetRef(const SCH_SHEET_PATH *aSheet, bool aIncludeUnit=false) const override
SCH_FIELD * GetField(FIELD_T aFieldType)
Return a mandatory field in this symbol.
VECTOR2I GetPosition() const override
virtual void Rotate90(bool aClockwise)
void SetPosition(const VECTOR2I &aPosition) override
Simple container to manage line stroke parameters.
void SetLineStyle(LINE_STYLE aLineStyle)
void SetWidth(int aWidth)
void SetColor(const KIGFX::COLOR4D &aColor)
KIGFX::COLOR4D GetColor() const
static const char * PropPowerSymsOnly
A base class for LIB_SYMBOL and SCH_SYMBOL.
virtual void SetShowPinNumbers(bool aShow)
Set or clear the pin number visibility flag.
const TRANSFORM & GetTransform() const
virtual void SetShowPinNames(bool aShow)
Set or clear the pin name visibility flag.
std::map< wxString, wxString > m_Fields
bool m_ExcludedFromPosFiles
constexpr extended_type SquaredEuclideanNorm() const
Compute the squared euclidean norm of the vector, which is defined as (x ** 2 + y ** 2).
static REPORTER & GetInstance()
#define DEFAULT_PINNUM_SIZE
The default pin number size when creating pins(can be changed in preference menu)
#define DEFAULT_PINNAME_SIZE
The default pin name size when creating pins(can be changed in preference menu)
#define DEFAULT_TEXT_SIZE
The default text size in mils. (can be changed in preference menu)
static constexpr EDA_ANGLE ANGLE_0
static constexpr EDA_ANGLE ANGLE_VERTICAL
static constexpr EDA_ANGLE ANGLE_HORIZONTAL
@ FILLED_WITH_BG_BODYCOLOR
@ FILLED_SHAPE
Fill with object color.
#define IS_NEW
New item, just created.
@ RECTANGLE
Use RECTANGLE instead of RECT to avoid collision in a Windows header.
#define THROW_IO_ERROR(msg)
macro which captures the "call site" values of FILE_, __FUNCTION & LINE
#define THROW_IO_ERRORF(msg,...)
#define THROW_IO_CANCELLED()
static const std::string KiCadSchematicFileExtension
static const std::string KiCadSymbolLibFileExtension
constexpr int Mils2IU(const EDA_IU_SCALE &aIuScale, int mils)
bool fileStartsWithPrefix(const wxString &aFilePath, const wxString &aPrefix, bool aIgnoreWhitespace)
Check if a file starts with a defined string.
const std::vector< uint8_t > COMPOUND_FILE_HEADER
bool fileHasBinaryHeader(const wxString &aFilePath, const std::vector< uint8_t > &aHeader, size_t aOffset)
Check if a file starts with a defined binary header.
const VECTOR2I & GetOtherEnd(const SEG &aSeg, const VECTOR2I &aPoint)
Get the end point of the segment that is not the given point.
bool signbit(T v)
Integral version of std::signbit that works all compilers.
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
@ PT_INPUT
usual pin input: must be connected
@ PT_TRISTATE
tri state bus pin
@ PT_BIDI
input or output (like port for a microprocessor)
@ PT_OPENEMITTER
pin type open emitter
@ PT_OPENCOLLECTOR
pin type open collector
@ PT_POWER_IN
power input (GND, VCC for ICs). Must be connected to a power output.
@ PT_UNSPECIFIED
unknown electrical properties: creates always a warning when connected
@ PT_PASSIVE
pin for passive symbols: must be connected, and can be connected to any pin.
@ PIN_UP
The pin extends upwards from the connection point: Probably on the bottom side of the symbol.
@ PIN_RIGHT
The pin extends rightwards from the connection point.
@ PIN_LEFT
The pin extends leftwards from the connection point: Probably on the right side of the symbol.
@ PIN_DOWN
The pin extends downwards from the connection: Probably on the top side of the symbol.
static COLOR4D GetColorFromInt(int color)
static ITEM_NET_CODES itemNetCodes(const CONNECTION_GRAPH &aGraph, const std::map< const SCH_ITEM *, const SCH_ITEM * > &aOriginals)
static void SetLibShapeFillAndColor(const ASCH_FILL_INTERFACE &elem, SCH_SHAPE *shape, ALTIUM_SCH_RECORD aType, int aStrokeColor)
VECTOR2I HelperGeneratePowerPortGraphics(LIB_SYMBOL *aKsymbol, ASCH_POWER_PORT_STYLE aStyle, REPORTER *aReporter)
static void SetSchShapeLine(const ASCH_BORDER_INTERFACE &elem, SCH_SHAPE *shape)
static const VECTOR2I GetRelativePosition(const VECTOR2I &aPosition, const SCH_SYMBOL *aSymbol)
static void SetLibShapeLine(const ASCH_BORDER_INTERFACE &elem, SCH_SHAPE *shape, ALTIUM_SCH_RECORD aType)
static wxString AltiumParseKey(const wxFileName &aFileName)
void AdjustTextForSymbolOrientation(SCH_TEXT *aText, const ASCH_SYMBOL &aSymbol)
static LINE_STYLE GetPlotDashType(const ASCH_POLYLINE_LINESTYLE linestyle)
static void SetSchShapeFillAndColor(const ASCH_FILL_INTERFACE &elem, SCH_SHAPE *shape)
void AdjustFieldForSymbolOrientation(SCH_FIELD *aField, const ASCH_SYMBOL &aSymbol)
wxString AltiumDeriveSheetName(const wxString &aFilename, const std::set< wxString > &aExistingNames)
static bool sameNets(const ITEM_NET_CODES &aBefore, const ITEM_NET_CODES &aAfter)
wxString AltiumWrapBusLabel(const wxString &aText)
std::map< std::pair< KIID_PATH, const SCH_ITEM * >, int > ITEM_NET_CODES
void SetTextPositioning(EDA_TEXT *text, ASCH_LABEL_JUSTIFICATION justification, ASCH_RECORD_ORIENTATION orientation)
Utility functions for working with shapes.
wxString UnescapeString(const wxString &aSource)
bool ReplaceIllegalFileNameChars(std::string &aName, int aReplaceChar)
Checks aName for illegal file name characters.
wxString EscapeString(const wxString &aSource, ESCAPE_CONTEXT aContext)
The Escape/Unescape routines use HTML-entity-reference-style encoding to handle characters which are:...
static std::vector< std::string > split(const std::string &aStr, const std::string &aDelim)
Split the input string into a vector of output strings.
LINE_STYLE
Dashed line types.
A project-level assembly variant parsed from an Altium .PrjPcb file.
A single component variation within an Altium project variant.
std::vector< VECTOR2I > points
std::vector< VECTOR2I > points
ASCH_LABEL_JUSTIFICATION justification
ASCH_RECORD_ORIENTATION orientation
ASCH_RECORD_ORIENTATION orientation
int m_primaryConnectionPosition
ASCH_SHEET_ENTRY_SIDE m_harnessConnectorSide
ASCH_SHEET_ENTRY_SIDE Side
ASCH_RECORD_ORIENTATION orientation
ASCH_LABEL_JUSTIFICATION justification
ASCH_POLYLINE_LINESTYLE LineStyle
ASCH_LABEL_JUSTIFICATION justification
ASCH_RECORD_ORIENTATION orientation
ASCH_RECORD_ORIENTATION orientation
ASCH_LABEL_JUSTIFICATION justification
ASCH_PIN_SYMBOL::PTYPE symbolOuterEdge
ASCH_PIN_ELECTRICAL electrical
ASCH_PIN_SYMBOL::PTYPE symbolInnerEdge
ASCH_RECORD_ORIENTATION orientation
std::vector< VECTOR2I > points
ASCH_POLYLINE_LINESTYLE LineStyle
std::vector< VECTOR2I > Points
ASCH_POWER_PORT_STYLE style
ASCH_RECORD_ORIENTATION orientation
ASCH_SHEET_ENTRY_SIDE side
ASCH_RECORD_ORIENTATION orientation
std::vector< VECTOR2I > points
wxString componentdescription
wxString sourcelibraryname
ASCH_TEXT_FRAME_ALIGNMENT Alignment
std::vector< VECTOR2I > points
int m_primaryConnectionPosition
ASCH_SHEET_ENTRY_SIDE m_harnessConnectorSide
std::vector< HARNESS_PORT > m_ports
PARSE_FILE_GUARD(SCH_IO_ALTIUM *aOwner, std::vector< wxString > aKeys)
PARSE_FILE_GUARD & operator=(const PARSE_FILE_GUARD &)=delete
std::vector< wxString > m_keys
PARSE_FILE_GUARD(SCH_IO_ALTIUM *aOwner, const wxString &aKey)
PARSE_FILE_GUARD(const PARSE_FILE_GUARD &)=delete
A simple container for sheet instance information.
@ USER
The field ID hasn't been set yet; field is invalid.
@ INTERSHEET_REFS
Global label cross-reference page numbers.
@ DESCRIPTION
Field Description of part, i.e. "1/4W 1% Metal Film Resistor".
@ FOOTPRINT
Field Name Module PCB, i.e. "16DIP300".
@ REFERENCE
Field Reference of part, i.e. "IC21".
@ VALUE
Field Value of part, i.e. "3.3K".
KIBIS top(path, &reporter)
static std::vector< int > candidates(const SEGMENT_INDEX &aIndex, const SEG &aQuery, int aPadding)
SHAPE_CIRCLE circle(c.m_circle_center, c.m_circle_radius)
wxString result
Test unit parsing edge cases and error handling.
GR_TEXT_H_ALIGN_T
This is API surface mapped to common.types.HorizontalAlignment.
GR_TEXT_V_ALIGN_T
This is API surface mapped to common.types.VertialAlignment.
VECTOR2< int32_t > VECTOR2I
Definition of file extensions used in Kicad.