Browse Source

Properly handle Altium harnesses

Altium harnesses are imported as buses in KiCad, using bus aliases to
represent the harness elements

Fixes https://gitlab.com/kicad/code/kicad/-/issues/16852
Seth Hillbrand 10 months ago
parent
commit
cf2827c6ec
  1. 23
      eeschema/sch_io/altium/altium_parser_sch.cpp
  2. 37
      eeschema/sch_io/altium/altium_parser_sch.h
  3. 571
      eeschema/sch_io/altium/sch_io_altium.cpp
  4. 23
      eeschema/sch_io/altium/sch_io_altium.h

23
eeschema/sch_io/altium/altium_parser_sch.cpp

@ -521,12 +521,12 @@ ASCH_SIGNAL_HARNESS::ASCH_SIGNAL_HARNESS( const std::map<wxString, wxString>& aP
for( int i = 1; i <= locationCount; i++ )
{
const wxString si = std::to_string( i );
Points.emplace_back( ReadKiCadUnitFrac( aProps, "X" + si ),
points.emplace_back( ReadKiCadUnitFrac( aProps, "X" + si ),
-ReadKiCadUnitFrac( aProps, "Y" + si ) );
}
Color = ALTIUM_PROPS_UTILS::ReadInt( aProps, "COLOR", 0 );
LineWidth = ReadKiCadUnitFrac( aProps, "LINEWIDTH" );
color = ALTIUM_PROPS_UTILS::ReadInt( aProps, "COLOR", 0 );
lineWidth = ReadKiCadUnitFrac( aProps, "LINEWIDTH" );
}
@ -536,16 +536,18 @@ ASCH_HARNESS_CONNECTOR::ASCH_HARNESS_CONNECTOR( const std::map<wxString, wxStrin
wxASSERT( ReadRecord( aProps ) == ALTIUM_SCH_RECORD::HARNESS_CONNECTOR );
Location = VECTOR2I( ReadKiCadUnitFrac( aProps, "LOCATION.X" ),
m_location = VECTOR2I( ReadKiCadUnitFrac( aProps, "LOCATION.X" ),
-ReadKiCadUnitFrac( aProps, "LOCATION.Y" ) );
Size = VECTOR2I( ReadKiCadUnitFrac( aProps, "XSIZE" ), ReadKiCadUnitFrac( aProps, "YSIZE" ) );
m_size = VECTOR2I( ReadKiCadUnitFrac( aProps, "XSIZE" ), ReadKiCadUnitFrac( aProps, "YSIZE" ) );
Color = ALTIUM_PROPS_UTILS::ReadInt( aProps, "COLOR", 0 );
AreaColor = ALTIUM_PROPS_UTILS::ReadInt( aProps, "AREACOLOR", 0 );
m_color = ALTIUM_PROPS_UTILS::ReadInt( aProps, "COLOR", 0 );
m_areaColor = ALTIUM_PROPS_UTILS::ReadInt( aProps, "AREACOLOR", 0 );
indexinsheet = 0;
LineWidth = 0;;
LocationPrimaryConnectionPosition = 0;
m_lineWidth = 0;;
m_primaryConnectionPosition = ALTIUM_PROPS_UTILS::ReadInt( aProps, "PRIMARYCONNECTIONPOSITION", 0 );
m_harnessConnectorSide = ReadEnum<ASCH_SHEET_ENTRY_SIDE>( aProps, "SIDE", 0, 3, ASCH_SHEET_ENTRY_SIDE::RIGHT );
}
@ -687,8 +689,7 @@ ASCH_PORT::ASCH_PORT( const std::map<wxString, wxString>& aProps ) :
FontID = ALTIUM_PROPS_UTILS::ReadInt( aProps, "TEXTFONTID", 0 );
TextColor = ALTIUM_PROPS_UTILS::ReadInt( aProps, "TEXTCOLOR", 0 );
Alignment = ReadEnum<ASCH_TEXT_FRAME_ALIGNMENT>( aProps, "ALIGNMENT", 1, 3,
ASCH_TEXT_FRAME_ALIGNMENT::LEFT );
m_align = ReadEnum<ASCH_PORT_ALIGNMENT>( aProps, "ALIGNMENT", 0, 2, ASCH_PORT_ALIGNMENT::CENTER );
}

37
eeschema/sch_io/altium/altium_parser_sch.h

@ -365,6 +365,14 @@ enum class ASCH_TEXT_FRAME_ALIGNMENT
};
enum class ASCH_PORT_ALIGNMENT
{
CENTER = 0,
RIGHT = 1,
LEFT = 2
};
struct ASCH_LABEL : ASCH_OWNER_INTERFACE
{
VECTOR2I location;
@ -522,13 +530,13 @@ struct ASCH_LINE : ASCH_OWNER_INTERFACE, ASCH_BORDER_INTERFACE
struct ASCH_SIGNAL_HARNESS : ASCH_OWNER_INTERFACE
{
VECTOR2I Point1;
VECTOR2I Point2;
VECTOR2I point1;
VECTOR2I point2;
std::vector<VECTOR2I> Points;
std::vector<VECTOR2I> points;
int Color;
int LineWidth;
int color;
int lineWidth;
explicit ASCH_SIGNAL_HARNESS( const std::map<wxString, wxString>& aProps );
};
@ -536,17 +544,14 @@ struct ASCH_SIGNAL_HARNESS : ASCH_OWNER_INTERFACE
struct ASCH_HARNESS_CONNECTOR : ASCH_OWNER_INTERFACE
{
VECTOR2I Location;
VECTOR2I Size;
VECTOR2I m_location;
VECTOR2I m_size;
int AreaColor;
int Color;
int LineWidth;
//int locationX; // keep just in case
//int locationY;
int LocationPrimaryConnectionPosition;
//int xSize; // keep just in case
//int ySize;
int m_areaColor;
int m_color;
int m_lineWidth;
int m_primaryConnectionPosition;
ASCH_SHEET_ENTRY_SIDE m_harnessConnectorSide;
explicit ASCH_HARNESS_CONNECTOR( const std::map<wxString, wxString>& aProps );
};
@ -689,7 +694,7 @@ struct ASCH_PORT : ASCH_OWNER_INTERFACE
int TextColor;
int FontID;
ASCH_TEXT_FRAME_ALIGNMENT Alignment;
ASCH_PORT_ALIGNMENT m_align;
ASCH_PORT_IOTYPE IOtype;
ASCH_PORT_STYLE Style;

571
eeschema/sch_io/altium/sch_io_altium.cpp

@ -56,6 +56,7 @@
#include <compoundfilereader.h>
#include <font/fontconfig.h>
#include <geometry/ellipse.h>
#include <geometry/shape_utils.h>
#include <string_utils.h>
#include <sch_edit_frame.h>
#include <wildcards_and_files_ext.h>
@ -465,6 +466,16 @@ SCH_SHEET* SCH_IO_ALTIUM::LoadSchematicFile( const wxString& aFileName, SCHEMATI
ParseAltiumSch( aFileName );
if( m_reporter )
{
for( auto& [msg, severity] : m_errorMessages )
{
m_reporter->Report( msg, severity );
}
}
m_errorMessages.clear();
m_pi->SaveLibrary( getLibFileName().GetFullPath() );
SCH_SCREENS allSheets( m_rootSheet );
@ -517,6 +528,229 @@ SCH_SHEET* SCH_IO_ALTIUM::getCurrentSheet()
}
void SCH_IO_ALTIUM::CreateAliases()
{
std::vector<SCH_LINE*> busLines;
std::map<VECTOR2I, std::vector<SCH_LINE*>> busLineMap;
for( auto elem : getCurrentScreen()->Items().OfType( SCH_LINE_T) )
{
SCH_LINE* line = static_cast<SCH_LINE*>( elem );
if( line->IsBus() )
{
busLines.push_back( line );
busLineMap[ line->GetStartPoint() ].push_back( line );
busLineMap[ line->GetEndPoint() ].push_back( line );
}
}
std::function<SCH_LABEL*(VECTOR2I, std::set<SCH_LINE*>&)> walkBusLine =
[&]( VECTOR2I aStart, std::set<SCH_LINE*>& aVisited ) -> SCH_LABEL*
{
auto it = busLineMap.find( aStart );
if( it == busLineMap.end() )
return nullptr;
for( SCH_LINE* line : it->second )
{
// Skip lines we've already checked to avoid cycles
if( aVisited.count( line ) )
continue;
aVisited.insert( line );
for( auto elem : getCurrentScreen()->Items().
Overlapping( SCH_LABEL_T, line->GetBoundingBox() ) )
{
SCH_LABEL* label = static_cast<SCH_LABEL*>( elem );
if( line->HitTest( label->GetPosition() ) )
return label;
}
SCH_LABEL* result = walkBusLine( KIGEOM::GetOtherEnd( line->GetSeg(), aStart ),
aVisited );
if( result )
return result;
}
return nullptr;
};
for( auto& [_, harness] : m_altiumHarnesses )
{
SCH_SCREEN* screen = getCurrentScreen();
wxCHECK( screen, /* void */ );
std::shared_ptr<BUS_ALIAS> alias = std::make_shared<BUS_ALIAS>( screen);
alias->SetName( harness.m_name );
for( auto& port : harness.m_ports )
alias->Members().push_back( port.m_name );
screen->AddBusAlias( alias );
VECTOR2I pos;
BOX2I box( harness.m_location, harness.m_size );
SCH_LINE* busLine = nullptr;
for( auto elem : getCurrentScreen()->Items().Overlapping(
SCH_LINE_T, box ) )
{
SCH_LINE* line = static_cast<SCH_LINE*>( elem );
if( !line->IsBus() )
continue;
busLine = line;
for( VECTOR2I pt : line->GetConnectionPoints() )
{
if( box.Contains( pt ) )
{
pos = pt;
break;
}
}
}
if( !busLine )
{
for( auto elem : getCurrentScreen()->Items().Overlapping(
SCH_HIER_LABEL_T, box ) )
{
SCH_HIERLABEL* label = static_cast<SCH_HIERLABEL*>( elem );
pos = label->GetPosition();
VECTOR2I center = box.GetCenter();
int delta_x = center.x - pos.x;
int delta_y = center.y - pos.y;
if( std::abs( delta_x ) > std::abs( delta_y ) )
{
busLine = new SCH_LINE( pos, SCH_LAYER_ID::LAYER_BUS );
busLine->SetEndPoint( VECTOR2I( center.x, pos.y ) );
busLine->SetFlags( IS_NEW );
screen->Append( busLine );
}
else
{
busLine = new SCH_LINE( pos, SCH_LAYER_ID::LAYER_BUS );
busLine->SetEndPoint( VECTOR2I( pos.x, center.y ) );
busLine->SetFlags( IS_NEW );
screen->Append( busLine );
}
break;
}
}
if( !busLine )
continue;
std::set<SCH_LINE*> visited;
SCH_LABEL* label = walkBusLine( pos, visited );
// Altium supports two different naming conventions for harnesses. If there is a specific
// harness name, then the nets inside the harness will be named harnessname.netname.
// However, if there is no harness name, the nets will be named just netname.
// KiCad bus labels need some special handling to be recognized as bus labels
if( label && !label->GetText().StartsWith( wxT( "{" ) ) )
label->SetText( label->GetText() + wxT( "{" ) + harness.m_name + wxT( "}" ) );
if( !label )
{
label = new SCH_LABEL( busLine->GetStartPoint(), wxT( "{" ) + harness.m_name + wxT( "}" ) );
label->SetVertJustify( GR_TEXT_V_ALIGN_BOTTOM );
if( busLine->GetEndPoint().x < busLine->GetStartPoint().x )
label->SetHorizJustify( GR_TEXT_H_ALIGN_RIGHT );
else
label->SetHorizJustify( GR_TEXT_H_ALIGN_LEFT );
screen->Append( label );
}
// Draw the bus line from the individual ports to the harness
bool isVertical = true;
if( harness.m_ports.size() > 1 )
{
VECTOR2I first = harness.m_ports.front().m_location;
VECTOR2I last = harness.m_ports.back().m_location;
if( first.y == last.y )
isVertical = false;
}
if( isVertical )
{
VECTOR2I bottom = harness.m_ports.front().m_entryLocation;
VECTOR2I top = harness.m_ports.front().m_entryLocation;
int delta_space = EDA_UNIT_UTILS::Mils2IU( schIUScale, 100 );
for( HARNESS::HARNESS_PORT& port : harness.m_ports )
{
if( port.m_entryLocation.y > bottom.y )
bottom = port.m_entryLocation;
if( port.m_entryLocation.y < top.y )
top = port.m_entryLocation;
}
VECTOR2I last_pt;
SCH_LINE* line = new SCH_LINE( bottom, SCH_LAYER_ID::LAYER_BUS );
line->SetStartPoint( bottom );
line->SetEndPoint( top );
line->SetLineWidth( busLine->GetLineWidth() );
line->SetLineColor( busLine->GetLineColor() );
getCurrentScreen()->Append( line );
last_pt = ( busLine->GetStartPoint() - line->GetEndPoint() ).SquaredEuclideanNorm() <
( busLine->GetStartPoint() - line->GetStartPoint() ).SquaredEuclideanNorm()
? line->GetEndPoint()
: line->GetStartPoint();
// If the busline is not on the save y coordinate as the bus/wire connectors, add a short
// hop to bring the bus down to the level of the connectors
if( last_pt.y != busLine->GetStartPoint().y )
{
line = new SCH_LINE( last_pt, SCH_LAYER_ID::LAYER_BUS );
line->SetStartPoint( last_pt );
line->SetEndPoint( last_pt
+ VECTOR2I( alg::signbit( busLine->GetStartPoint().x - last_pt.x )
? -delta_space: delta_space, 0 ) );
line->SetLineWidth( busLine->GetLineWidth() );
line->SetLineColor( busLine->GetLineColor() );
getCurrentScreen()->Append( line );
last_pt = line->GetEndPoint();
line = new SCH_LINE( last_pt, SCH_LAYER_ID::LAYER_BUS );
line->SetStartPoint( last_pt );
line->SetEndPoint( last_pt + VECTOR2I( 0, busLine->GetStartPoint().y - last_pt.y ) );
line->SetLineWidth( busLine->GetLineWidth() );
line->SetLineColor( busLine->GetLineColor() );
getCurrentScreen()->Append( line );
last_pt = line->GetEndPoint();
}
line = new SCH_LINE( last_pt, SCH_LAYER_ID::LAYER_BUS );
line->SetStartPoint( last_pt );
line->SetEndPoint( busLine->GetStartPoint() );
line->SetLineWidth( busLine->GetLineWidth() );
line->SetLineColor( busLine->GetLineColor() );
getCurrentScreen()->Append( line );
}
}
}
void SCH_IO_ALTIUM::ParseAltiumSch( const wxString& aFileName )
{
// Load path may be different from the project path.
@ -591,7 +825,7 @@ void SCH_IO_ALTIUM::ParseAltiumSch( const wxString& aFileName )
msg.Printf( _( "The file name for sheet %s is undefined, this is probably an"
" Altium signal harness that got converted to a sheet." ),
sheet->GetName() );
m_reporter->Report( msg );
m_errorMessages.emplace( msg, SEVERITY::RPT_SEVERITY_INFO );
sheet->SetScreen( new SCH_SCREEN( m_schematic ) );
continue;
}
@ -614,6 +848,7 @@ void SCH_IO_ALTIUM::ParseAltiumSch( const wxString& aFileName )
wxCHECK2( screen, continue );
m_sheetPath.push_back( sheet );
m_sheets.clear();
ParseAltiumSch( loadAltiumFileName.GetFullPath() );
// Map the loaded Altium file to the project file.
@ -655,7 +890,7 @@ void SCH_IO_ALTIUM::ParseStorage( const ALTIUM_COMPOUND_FILE& aAltiumSchFile )
// throw IO Error.
if( reader.GetRemainingBytes() != 0 )
{
m_reporter->Report( wxString::Format( _( "Storage file not fully parsed "
m_errorMessages.emplace( wxString::Format( _( "Storage file not fully parsed "
"(%d bytes remaining)." ),
reader.GetRemainingBytes() ),
RPT_SEVERITY_ERROR );
@ -701,12 +936,15 @@ void SCH_IO_ALTIUM::ParseAdditional( const ALTIUM_COMPOUND_FILE& aAltiumSchFile
for( const ASCH_PORT& port : m_altiumHarnessPortsCurrentSheet )
ParseHarnessPort( port );
CreateAliases();
if( reader.HasParsingError() )
THROW_IO_ERROR( "stream was not parsed correctly!" );
if( reader.GetRemainingBytes() != 0 )
THROW_IO_ERROR( "stream is not fully parsed" );
m_altiumHarnesses.clear();
m_altiumHarnessPortsCurrentSheet.clear();
}
@ -899,6 +1137,10 @@ void SCH_IO_ALTIUM::ParseASCIISchematic( const wxString& aFileName )
for( const ASCH_PORT& port : m_altiumPortsCurrentSheet )
ParsePort( port );
// Add the aliases used for harnesses
CreateAliases();
m_altiumHarnesses.clear();
m_altiumPortsCurrentSheet.clear();
m_altiumComponents.clear();
m_altiumTemplates.clear();
@ -939,7 +1181,7 @@ void SCH_IO_ALTIUM::ParseRecord( int index, std::map<wxString, wxString>& proper
break;
case ALTIUM_SCH_RECORD::IEEE_SYMBOL:
m_reporter->Report( _( "Record 'IEEE_SYMBOL' not handled." ), RPT_SEVERITY_INFO );
m_errorMessages.emplace( _( "Record 'IEEE_SYMBOL' not handled." ), RPT_SEVERITY_INFO );
break;
case ALTIUM_SCH_RECORD::LABEL:
@ -1058,7 +1300,7 @@ void SCH_IO_ALTIUM::ParseRecord( int index, std::map<wxString, wxString>& proper
break;
case ALTIUM_SCH_RECORD::PARAMETER_SET:
m_reporter->Report( _( "Parameter Set not currently supported." ), RPT_SEVERITY_ERROR );
m_errorMessages.emplace( _( "Parameter Set not currently supported." ), RPT_SEVERITY_ERROR );
break;
case ALTIUM_SCH_RECORD::IMPLEMENTATION_LIST:
@ -1083,7 +1325,7 @@ void SCH_IO_ALTIUM::ParseRecord( int index, std::map<wxString, wxString>& proper
break;
case ALTIUM_SCH_RECORD::COMPILE_MASK:
m_reporter->Report( _( "Compile mask not currently supported." ), RPT_SEVERITY_ERROR );
m_errorMessages.emplace( _( "Compile mask not currently supported." ), RPT_SEVERITY_ERROR );
break;
case ALTIUM_SCH_RECORD::HYPERLINK:
@ -1108,11 +1350,11 @@ void SCH_IO_ALTIUM::ParseRecord( int index, std::map<wxString, wxString>& proper
break;
case ALTIUM_SCH_RECORD::BLANKET:
m_reporter->Report( _( "Blanket not currently supported." ), RPT_SEVERITY_ERROR );
m_errorMessages.emplace( _( "Blanket not currently supported." ), RPT_SEVERITY_ERROR );
break;
default:
m_reporter->Report(
m_errorMessages.emplace(
wxString::Format( _( "Unknown or unexpected record id %d found in %s." ), recordId,
aSectionName ),
RPT_SEVERITY_ERROR );
@ -1171,7 +1413,7 @@ void SCH_IO_ALTIUM::ParseComponent( int aIndex, const std::map<wxString, wxStrin
{
const ASCH_SYMBOL& currentSymbol = m_altiumComponents.at( aIndex );
m_reporter->Report( wxString::Format( _( "Symbol \"%s\" in sheet \"%s\" at index %d "
m_errorMessages.emplace( wxString::Format( _( "Symbol \"%s\" in sheet \"%s\" at index %d "
"replaced with symbol \"%s\"." ),
currentSymbol.libreference,
sheetName,
@ -1265,7 +1507,7 @@ void SCH_IO_ALTIUM::ParsePin( const std::map<wxString, wxString>& aProperties,
if( libSymbolIt == m_libSymbols.end() )
{
// TODO: e.g. can depend on Template (RECORD=39
m_reporter->Report( wxString::Format( wxT( "Pin's owner (%d) not found." ),
m_errorMessages.emplace( wxString::Format( wxT( "Pin's owner (%d) not found." ),
elem.ownerindex ),
RPT_SEVERITY_DEBUG );
return;
@ -1327,7 +1569,7 @@ void SCH_IO_ALTIUM::ParsePin( const std::map<wxString, wxString>& aProperties,
break;
default:
m_reporter->Report( _( "Pin has unexpected orientation." ), RPT_SEVERITY_WARNING );
m_errorMessages.emplace( _( "Pin has unexpected orientation." ), RPT_SEVERITY_WARNING );
break;
}
@ -1375,15 +1617,15 @@ void SCH_IO_ALTIUM::ParsePin( const std::map<wxString, wxString>& aProperties,
case ASCH_PIN_ELECTRICAL::UNKNOWN:
default:
pin->SetType( ELECTRICAL_PINTYPE::PT_UNSPECIFIED );
m_reporter->Report( _( "Pin has unexpected electrical type." ), RPT_SEVERITY_WARNING );
m_errorMessages.emplace( _( "Pin has unexpected electrical type." ), RPT_SEVERITY_WARNING );
break;
}
if( elem.symbolOuterEdge == ASCH_PIN_SYMBOL::UNKNOWN )
m_reporter->Report( _( "Pin has unexpected outer edge type." ), RPT_SEVERITY_WARNING );
m_errorMessages.emplace( _( "Pin has unexpected outer edge type." ), RPT_SEVERITY_WARNING );
if( elem.symbolInnerEdge == ASCH_PIN_SYMBOL::UNKNOWN )
m_reporter->Report( _( "Pin has unexpected inner edge type." ), RPT_SEVERITY_WARNING );
m_errorMessages.emplace( _( "Pin has unexpected inner edge type." ), RPT_SEVERITY_WARNING );
if( elem.symbolOuterEdge == ASCH_PIN_SYMBOL::NEGATED )
{
@ -1562,7 +1804,7 @@ void SCH_IO_ALTIUM::ParseLabel( const std::map<wxString, wxString>& aProperties,
textItem->SetItalic( font.Italic );
}
textItem->SetFlags(IS_NEW );
textItem->SetFlags( IS_NEW );
SCH_SCREEN* screen = getCurrentScreen();
wxCHECK( screen, /* void */ );
@ -1583,7 +1825,7 @@ void SCH_IO_ALTIUM::ParseLabel( const std::map<wxString, wxString>& aProperties,
if( libSymbolIt == m_libSymbols.end() )
{
// TODO: e.g. can depend on Template (RECORD=39
m_reporter->Report( wxString::Format( wxT( "Label's owner (%d) not found." ),
m_errorMessages.emplace( wxString::Format( wxT( "Label's owner (%d) not found." ),
elem.ownerindex ),
RPT_SEVERITY_DEBUG );
return;
@ -1724,7 +1966,7 @@ void SCH_IO_ALTIUM::AddLibTextBox( const ASCH_TEXT_FRAME *aElem, std::vector<LIB
if( libSymbolIt == m_libSymbols.end() )
{
// TODO: e.g. can depend on Template (RECORD=39
m_reporter->Report(
m_errorMessages.emplace(
wxString::Format( wxT( "Label's owner (%d) not found." ), aElem->ownerindex ),
RPT_SEVERITY_DEBUG );
return;
@ -1795,7 +2037,7 @@ void SCH_IO_ALTIUM::ParseBezier( const std::map<wxString, wxString>& aProperties
if( elem.points.size() < 2 )
{
m_reporter->Report( wxString::Format( _( "Bezier has %d control points. At least 2 are "
m_errorMessages.emplace( wxString::Format( _( "Bezier has %d control points. At least 2 are "
"expected." ),
static_cast<int>( elem.points.size() ) ),
RPT_SEVERITY_WARNING );
@ -1862,7 +2104,7 @@ void SCH_IO_ALTIUM::ParseBezier( const std::map<wxString, wxString>& aProperties
if( libSymbolIt == m_libSymbols.end() )
{
// TODO: e.g. can depend on Template (RECORD=39
m_reporter->Report( wxString::Format( wxT( "Bezier's owner (%d) not found." ),
m_errorMessages.emplace( wxString::Format( wxT( "Bezier's owner (%d) not found." ),
elem.ownerindex ),
RPT_SEVERITY_DEBUG );
return;
@ -1995,7 +2237,7 @@ void SCH_IO_ALTIUM::ParsePolyline( const std::map<wxString, wxString>& aProperti
if( libSymbolIt == m_libSymbols.end() )
{
// TODO: e.g. can depend on Template (RECORD=39
m_reporter->Report( wxString::Format( wxT( "Polyline's owner (%d) not found." ),
m_errorMessages.emplace( wxString::Format( wxT( "Polyline's owner (%d) not found." ),
elem.ownerindex ),
RPT_SEVERITY_DEBUG );
return;
@ -2066,7 +2308,7 @@ void SCH_IO_ALTIUM::ParsePolygon( const std::map<wxString, wxString>& aPropertie
if( libSymbolIt == m_libSymbols.end() )
{
// TODO: e.g. can depend on Template (RECORD=39
m_reporter->Report( wxString::Format( wxT( "Polygon's owner (%d) not found." ),
m_errorMessages.emplace( wxString::Format( wxT( "Polygon's owner (%d) not found." ),
elem.ownerindex ),
RPT_SEVERITY_DEBUG );
return;
@ -2148,7 +2390,7 @@ void SCH_IO_ALTIUM::ParseRoundRectangle( const std::map<wxString, wxString>& aPr
if( libSymbolIt == m_libSymbols.end() )
{
// TODO: e.g. can depend on Template (RECORD=39
m_reporter->Report( wxString::Format( wxT( "Rounded rectangle's owner (%d) not "
m_errorMessages.emplace( wxString::Format( wxT( "Rounded rectangle's owner (%d) not "
"found." ),
elem.ownerindex ),
RPT_SEVERITY_DEBUG );
@ -2268,7 +2510,7 @@ void SCH_IO_ALTIUM::ParseArc( const std::map<wxString, wxString>& aProperties,
if( libSymbolIt == m_libSymbols.end() )
{
// TODO: e.g. can depend on Template (RECORD=39
m_reporter->Report( wxString::Format( wxT( "Arc's owner (%d) not found." ),
m_errorMessages.emplace( wxString::Format( wxT( "Arc's owner (%d) not found." ),
elem.ownerindex ),
RPT_SEVERITY_DEBUG );
return;
@ -2369,7 +2611,7 @@ void SCH_IO_ALTIUM::ParseEllipticalArc( const std::map<wxString, wxString>& aPro
if( libSymbolIt == m_libSymbols.end() )
{
// TODO: e.g. can depend on Template (RECORD=39
m_reporter->Report( wxString::Format( wxT( "Elliptical Arc's owner (%d) not found." ),
m_errorMessages.emplace( wxString::Format( wxT( "Elliptical Arc's owner (%d) not found." ),
elem.ownerindex ),
RPT_SEVERITY_DEBUG );
return;
@ -2469,7 +2711,7 @@ void SCH_IO_ALTIUM::ParsePieChart( const std::map<wxString, wxString>& aProperti
if( libSymbolIt == m_libSymbols.end() )
{
// TODO: e.g. can depend on Template (RECORD=39
m_reporter->Report( wxString::Format( wxT( "Piechart's owner (%d) not found." ),
m_errorMessages.emplace( wxString::Format( wxT( "Piechart's owner (%d) not found." ),
elem.ownerindex ),
RPT_SEVERITY_DEBUG );
return;
@ -2582,7 +2824,7 @@ void SCH_IO_ALTIUM::ParseEllipse( const std::map<wxString, wxString>& aPropertie
if( libSymbolIt == m_libSymbols.end() )
{
// TODO: e.g. can depend on Template (RECORD=39
m_reporter->Report( wxString::Format( wxT( "Ellipse's owner (%d) not found." ),
m_errorMessages.emplace( wxString::Format( wxT( "Ellipse's owner (%d) not found." ),
elem.ownerindex ),
RPT_SEVERITY_DEBUG );
return;
@ -2687,7 +2929,7 @@ void SCH_IO_ALTIUM::ParseCircle( const std::map<wxString, wxString>& aProperties
if( libSymbolIt == m_libSymbols.end() )
{
// TODO: e.g. can depend on Template (RECORD=39
m_reporter->Report( wxString::Format( wxT( "Ellipse's owner (%d) not found." ),
m_errorMessages.emplace( wxString::Format( wxT( "Ellipse's owner (%d) not found." ),
elem.ownerindex ),
RPT_SEVERITY_DEBUG );
return;
@ -2749,7 +2991,7 @@ void SCH_IO_ALTIUM::ParseLine( const std::map<wxString, wxString>& aProperties,
if( libSymbolIt == m_libSymbols.end() )
{
// TODO: e.g. can depend on Template (RECORD=39
m_reporter->Report( wxString::Format( wxT( "Line's owner (%d) not found." ),
m_errorMessages.emplace( wxString::Format( wxT( "Line's owner (%d) not found." ),
elem.ownerindex ),
RPT_SEVERITY_DEBUG );
return;
@ -2793,21 +3035,22 @@ void SCH_IO_ALTIUM::ParseSignalHarness( const std::map<wxString, wxString>& aPro
SCH_SCREEN* screen = getCurrentScreen();
wxCHECK( screen, /* void */ );
SCH_SHAPE* poly = new SCH_SHAPE( SHAPE_T::POLY );
for( VECTOR2I& point : elem.Points )
poly->AddPoint( point + m_sheetOffset );
poly->SetStroke( STROKE_PARAMS( elem.LineWidth, LINE_STYLE::SOLID,
GetColorFromInt( elem.Color ) ) );
poly->SetFlags( IS_NEW );
for( size_t ii = 0; ii < elem.points.size() - 1; ii++ )
{
SCH_LINE* line = new SCH_LINE( elem.points[ii] + m_sheetOffset,
SCH_LAYER_ID::LAYER_BUS );
line->SetEndPoint( elem.points[ii + 1] + m_sheetOffset );
line->SetStroke( STROKE_PARAMS( elem.lineWidth, LINE_STYLE::SOLID,
GetColorFromInt( elem.color ) ) );
screen->Append( poly );
line->SetFlags( IS_NEW );
screen->Append( line );
}
}
else
{
// No clue if this situation can ever exist
m_reporter->Report( wxT( "Signal harness, belonging to the part is not currently "
m_errorMessages.emplace( wxT( "Signal harness, belonging to the part is not currently "
"supported." ), RPT_SEVERITY_DEBUG );
}
}
@ -2820,30 +3063,38 @@ void SCH_IO_ALTIUM::ParseHarnessConnector( int aIndex, const std::map<wxString,
if( ShouldPutItemOnSheet( elem.ownerindex ) )
{
SCH_SCREEN* currentScreen = getCurrentScreen();
wxCHECK( currentScreen, /* void */ );
SCH_SHEET* sheet = new SCH_SHEET( getCurrentSheet(), elem.Location + m_sheetOffset,
elem.Size );
sheet->SetScreen( new SCH_SCREEN( m_schematic ) );
sheet->SetBackgroundColor( GetColorFromInt( elem.AreaColor ) );
sheet->SetBorderColor( GetColorFromInt( elem.Color ) );
currentScreen->Append( sheet );
m_harnessEntryParent = aIndex + m_harnessOwnerIndexOffset;
auto [it, _] = m_altiumHarnesses.insert( { m_harnessEntryParent, HARNESS()} );
SCH_SHEET_PATH sheetpath = m_sheetPath;
sheetpath.push_back( sheet );
HARNESS& harness = it->second;
HARNESS::HARNESS_PORT& port = harness.m_entry;
harness.m_location = elem.m_location + m_sheetOffset;
harness.m_size = elem.m_size;
sheetpath.SetPageNumber( "Harness #" );
VECTOR2I pos = elem.m_location + m_sheetOffset;
VECTOR2I size = elem.m_size;
m_harnessEntryParent = aIndex + m_harnessOwnerIndexOffset;
m_sheets.insert( { m_harnessEntryParent, sheet } );
switch( elem.m_harnessConnectorSide )
{
default:
case ASCH_SHEET_ENTRY_SIDE::LEFT:
port.m_location = { pos.x, pos.y + elem.m_primaryConnectionPosition };
break;
case ASCH_SHEET_ENTRY_SIDE::RIGHT:
port.m_location = { pos.x + size.x, pos.y + elem.m_primaryConnectionPosition };
break;
case ASCH_SHEET_ENTRY_SIDE::TOP:
port.m_location = { pos.x + elem.m_primaryConnectionPosition, pos.y };
break;
case ASCH_SHEET_ENTRY_SIDE::BOTTOM:
port.m_location = { pos.x + elem.m_primaryConnectionPosition, pos.y + size.y };
break;
}
}
else
{
// I have no clue if this situation can ever exist
m_reporter->Report( wxT( "Harness connector, belonging to the part is not currently "
m_errorMessages.emplace( wxT( "Harness connector, belonging to the part is not currently "
"supported." ),
RPT_SEVERITY_DEBUG );
}
@ -2854,49 +3105,53 @@ void SCH_IO_ALTIUM::ParseHarnessEntry( const std::map<wxString, wxString>& aProp
{
ASCH_HARNESS_ENTRY elem( aProperties );
const auto& sheetIt = m_sheets.find( m_harnessEntryParent );
auto harnessIt = m_altiumHarnesses.find( m_harnessEntryParent );
if( sheetIt == m_sheets.end() )
if( harnessIt == m_altiumHarnesses.end() )
{
m_reporter->Report( wxString::Format( wxT( "Harness entry's parent (%d) not found." ),
m_errorMessages.emplace( wxString::Format( wxT( "Harness entry's parent (%d) not found." ),
SCH_IO_ALTIUM::m_harnessEntryParent ),
RPT_SEVERITY_DEBUG );
return;
}
SCH_SHEET_PIN* sheetPin = new SCH_SHEET_PIN( sheetIt->second );
sheetIt->second->AddPin( sheetPin );
HARNESS& harness = harnessIt->second;
HARNESS::HARNESS_PORT port;
port.m_name = elem.Name;
port.m_harnessConnectorSide = elem.Side;
sheetPin->SetText( elem.Name );
sheetPin->SetShape( LABEL_FLAG_SHAPE::L_UNSPECIFIED );
VECTOR2I pos = sheetIt->second->GetPosition();
VECTOR2I size = sheetIt->second->GetSize();
VECTOR2I pos = harness.m_location;
VECTOR2I size = harness.m_size;
int quadrant = 1;
switch( elem.Side )
{
default:
case ASCH_SHEET_ENTRY_SIDE::LEFT:
sheetPin->SetPosition( { pos.x, pos.y + elem.DistanceFromTop } );
sheetPin->SetSpinStyle( SPIN_STYLE::LEFT );
sheetPin->SetSide( SHEET_SIDE::LEFT );
port.m_location = { pos.x, pos.y + elem.DistanceFromTop };
break;
case ASCH_SHEET_ENTRY_SIDE::RIGHT:
sheetPin->SetPosition( { pos.x + size.x, pos.y + elem.DistanceFromTop } );
sheetPin->SetSpinStyle( SPIN_STYLE::RIGHT );
sheetPin->SetSide( SHEET_SIDE::RIGHT );
quadrant = 4;
port.m_location = { pos.x + size.x, pos.y + elem.DistanceFromTop };
break;
case ASCH_SHEET_ENTRY_SIDE::TOP:
sheetPin->SetPosition( { pos.x + elem.DistanceFromTop, pos.y } );
sheetPin->SetSpinStyle( SPIN_STYLE::UP );
sheetPin->SetSide( SHEET_SIDE::TOP );
port.m_location = { pos.x + elem.DistanceFromTop, pos.y };
break;
case ASCH_SHEET_ENTRY_SIDE::BOTTOM:
sheetPin->SetPosition( { pos.x + elem.DistanceFromTop, pos.y + size.y } );
sheetPin->SetSpinStyle( SPIN_STYLE::BOTTOM );
sheetPin->SetSide( SHEET_SIDE::BOTTOM );
quadrant = 2;
port.m_location = { pos.x + elem.DistanceFromTop, pos.y + size.y };
break;
}
SCH_SCREEN* screen = getCurrentScreen();
wxCHECK( screen, /* void */ );
SCH_BUS_WIRE_ENTRY* entry = new SCH_BUS_WIRE_ENTRY( port.m_location, quadrant );
port.m_entryLocation = entry->GetPosition() + entry->GetSize();
entry->SetFlags( IS_NEW );
screen->Append( entry );
harness.m_ports.emplace_back( port );
}
@ -2904,46 +3159,19 @@ void SCH_IO_ALTIUM::ParseHarnessType( const std::map<wxString, wxString>& aPrope
{
ASCH_HARNESS_TYPE elem( aProperties );
const auto& sheetIt = m_sheets.find( m_harnessEntryParent );
auto harnessIt = m_altiumHarnesses.find( m_harnessEntryParent );
if( sheetIt == m_sheets.end() )
if( harnessIt == m_altiumHarnesses.end() )
{
m_reporter->Report( wxString::Format( wxT( "Harness type's parent (%d) not found." ),
m_harnessEntryParent ),
m_errorMessages.emplace( wxString::Format( wxT( "Harness type's parent (%d) not found." ),
SCH_IO_ALTIUM::m_harnessEntryParent ),
RPT_SEVERITY_DEBUG );
return;
}
SCH_FIELD& sheetNameField = sheetIt->second->GetFields()[SHEETNAME];
sheetNameField.SetPosition( elem.Location + m_sheetOffset );
sheetNameField.SetText( elem.Text );
// Always set as visible so user is aware about ( !elem.isHidden );
sheetNameField.SetVisible( true );
SetTextPositioning( &sheetNameField, ASCH_LABEL_JUSTIFICATION::BOTTOM_LEFT,
ASCH_RECORD_ORIENTATION::RIGHTWARDS );
sheetNameField.SetTextColor( GetColorFromInt( elem.Color ) );
SCH_FIELD& sheetFileName = sheetIt->second->GetFields()[SHEETFILENAME];
sheetFileName.SetText( elem.Text + wxT( "." ) + FILEEXT::KiCadSchematicFileExtension );
HARNESS& harness = harnessIt->second;
harness.m_name = elem.Text;
wxFileName fn( m_schematic->Prj().GetProjectPath(), elem.Text,
FILEEXT::KiCadSchematicFileExtension );
wxString fullPath = fn.GetFullPath();
fullPath.Replace( wxT( "\\" ), wxT( "/" ) );
SCH_SCREEN* screen = sheetIt->second->GetScreen();
wxCHECK( screen, /* void */ );
screen->SetFileName( fullPath );
m_reporter->Report( wxString::Format( _( "Altium's harness connector (%s) was imported as a "
"hierarchical sheet. Please review the imported "
"schematic." ),
elem.Text ),
RPT_SEVERITY_WARNING );
}
@ -2984,7 +3212,7 @@ void SCH_IO_ALTIUM::ParseRectangle( const std::map<wxString, wxString>& aPropert
if( libSymbolIt == m_libSymbols.end() )
{
// TODO: e.g. can depend on Template (RECORD=39
m_reporter->Report( wxString::Format( wxT( "Rectangle's owner (%d) not found." ),
m_errorMessages.emplace( wxString::Format( wxT( "Rectangle's owner (%d) not found." ),
elem.ownerindex ),
RPT_SEVERITY_DEBUG );
return;
@ -3063,7 +3291,7 @@ void SCH_IO_ALTIUM::ParseSheetEntry( const std::map<wxString, wxString>& aProper
if( sheetIt == m_sheets.end() )
{
m_reporter->Report( wxString::Format( wxT( "Sheet entry's owner (%d) not found." ),
m_errorMessages.emplace( wxString::Format( wxT( "Sheet entry's owner (%d) not found." ),
elem.ownerindex ),
RPT_SEVERITY_DEBUG );
return;
@ -3440,7 +3668,7 @@ void SCH_IO_ALTIUM::ParsePowerPort( const std::map<wxString, wxString>& aPropert
break;
default:
m_reporter->Report( _( "Pin has unexpected orientation." ), RPT_SEVERITY_WARNING );
m_errorMessages.emplace( _( "Pin has unexpected orientation." ), RPT_SEVERITY_WARNING );
break;
}
@ -3450,67 +3678,7 @@ void SCH_IO_ALTIUM::ParsePowerPort( const std::map<wxString, wxString>& aPropert
void SCH_IO_ALTIUM::ParseHarnessPort( const ASCH_PORT& aElem )
{
SCH_TEXTBOX* textBox = new SCH_TEXTBOX();
textBox->SetText( aElem.Name );
textBox->SetTextColor( GetColorFromInt( aElem.TextColor ) );
int height = aElem.Height;
if( height <= 0 )
height = schIUScale.MilsToIU( 100 ); // chose default 50 grid
textBox->SetStartX( ( aElem.Location + m_sheetOffset ).x );
textBox->SetStartY( ( aElem.Location + m_sheetOffset ).y - ( height / 2 ) );
textBox->SetEndX( ( aElem.Location + m_sheetOffset ).x + ( aElem.Width ) );
textBox->SetEndY( ( aElem.Location + m_sheetOffset ).y + ( height / 2 ) );
textBox->SetFillColor( HARNESS_PORT_COLOR_DEFAULT_BACKGROUND );
textBox->SetFillMode( FILL_T::FILLED_WITH_COLOR );
textBox->SetStroke( STROKE_PARAMS( 2, LINE_STYLE::DEFAULT,
HARNESS_PORT_COLOR_DEFAULT_OUTLINE ) );
switch( aElem.Alignment )
{
default:
case ASCH_TEXT_FRAME_ALIGNMENT::LEFT:
textBox->SetHorizJustify( GR_TEXT_H_ALIGN_LEFT );
break;
case ASCH_TEXT_FRAME_ALIGNMENT::CENTER:
textBox->SetHorizJustify( GR_TEXT_H_ALIGN_CENTER );
break;
case ASCH_TEXT_FRAME_ALIGNMENT::RIGHT:
textBox->SetHorizJustify( GR_TEXT_H_ALIGN_RIGHT );
break;
}
size_t fontId = static_cast<int>( aElem.FontID );
if( m_altiumSheet && fontId > 0 && fontId <= m_altiumSheet->fonts.size() )
{
const ASCH_SHEET_FONT& font = m_altiumSheet->fonts.at( fontId - 1 );
textBox->SetTextSize( { font.Size / 2, font.Size / 2 } );
// Must come after SetTextSize()
textBox->SetBold( font.Bold );
textBox->SetItalic( font.Italic );
//textBox->SetFont( //how to set font, we have a font name here: ( font.fontname );
}
textBox->SetFlags( IS_NEW );
SCH_SCREEN* screen = getCurrentScreen();
wxCHECK( screen, /* void */ );
screen->Append( textBox );
m_reporter->Report( wxString::Format( _( "Altium's harness port (%s) was imported as "
"a text box. Please review the imported "
"schematic." ),
aElem.Name ),
RPT_SEVERITY_WARNING );
ParsePortHelper( aElem );
}
@ -3523,6 +3691,12 @@ void SCH_IO_ALTIUM::ParsePort( const ASCH_PORT& aElem )
return;
}
ParsePortHelper( aElem );
}
void SCH_IO_ALTIUM::ParsePortHelper( const ASCH_PORT& aElem )
{
VECTOR2I start = aElem.Location + m_sheetOffset;
VECTOR2I end = start;
@ -3563,8 +3737,34 @@ void SCH_IO_ALTIUM::ParsePort( const ASCH_PORT& aElem )
if( !connectionFound )
{
m_reporter->Report( wxString::Format( _( "Port %s has no connections." ), aElem.Name ),
for( auto& [ _, harness ] : m_altiumHarnesses )
{
if( harness.m_name.CmpNoCase( aElem.HarnessType ) != 0 )
continue;
BOX2I bbox( harness.m_location, harness.m_size );
bbox.Inflate( 10 );
if( bbox.Contains( start ) )
{
startIsBusTerminal = true;
connectionFound = true;
break;
}
if( bbox.Contains( end ) )
{
endIsBusTerminal = true;
connectionFound = true;
break;
}
}
if( !connectionFound )
{
m_errorMessages.emplace( wxString::Format( _( "Port %s has no connections." ), aElem.Name ),
RPT_SEVERITY_WARNING );
}
}
// Select label position. In case both match, we will add a line later.
@ -3758,7 +3958,7 @@ void SCH_IO_ALTIUM::ParseImage( const std::map<wxString, wxString>& aProperties
{
wxString msg = wxString::Format( _( "Embedded file %s not found in storage." ),
elem.filename );
m_reporter->Report( msg, RPT_SEVERITY_ERROR );
m_errorMessages.emplace( msg, RPT_SEVERITY_ERROR );
return;
}
@ -3773,7 +3973,7 @@ void SCH_IO_ALTIUM::ParseImage( const std::map<wxString, wxString>& aProperties
if( !refImage.ReadImageFile( storagePath ) )
{
m_reporter->Report( wxString::Format( _( "Error reading image %s." ), storagePath ),
m_errorMessages.emplace( wxString::Format( _( "Error reading image %s." ), storagePath ),
RPT_SEVERITY_ERROR );
return;
}
@ -3785,15 +3985,16 @@ void SCH_IO_ALTIUM::ParseImage( const std::map<wxString, wxString>& aProperties
{
if( !wxFileExists( elem.filename ) )
{
m_reporter->Report( wxString::Format( _( "File not found %s." ), elem.filename ),
m_errorMessages.emplace( wxString::Format( _( "File not found %s." ), elem.filename ),
RPT_SEVERITY_ERROR );
return;
}
if( !refImage.ReadImageFile( elem.filename ) )
{
m_reporter->Report( wxString::Format( _( "Error reading image %s." ), elem.filename ),
RPT_SEVERITY_ERROR );
m_errorMessages.emplace(
wxString::Format( _( "Error reading image %s." ), elem.filename ),
RPT_SEVERITY_ERROR );
return;
}
}
@ -3869,7 +4070,7 @@ void SCH_IO_ALTIUM::ParseSheetName( const std::map<wxString, wxString>& aPropert
if( sheetIt == m_sheets.end() )
{
m_reporter->Report( wxString::Format( wxT( "Sheetname's owner (%d) not found." ),
m_errorMessages.emplace( wxString::Format( wxT( "Sheetname's owner (%d) not found." ),
elem.ownerindex ),
RPT_SEVERITY_DEBUG );
return;
@ -3892,7 +4093,7 @@ void SCH_IO_ALTIUM::ParseFileName( const std::map<wxString, wxString>& aProperti
if( sheetIt == m_sheets.end() )
{
m_reporter->Report( wxString::Format( wxT( "Filename's owner (%d) not found." ),
m_errorMessages.emplace( wxString::Format( wxT( "Filename's owner (%d) not found." ),
elem.ownerindex ),
RPT_SEVERITY_DEBUG );
return;
@ -3918,7 +4119,7 @@ void SCH_IO_ALTIUM::ParseDesignator( const std::map<wxString, wxString>& aProper
if( libSymbolIt == m_libSymbols.end() )
{
// TODO: e.g. can depend on Template (RECORD=39
m_reporter->Report( wxString::Format( wxT( "Designator's owner (%d) not found." ),
m_errorMessages.emplace( wxString::Format( wxT( "Designator's owner (%d) not found." ),
elem.ownerindex ),
RPT_SEVERITY_DEBUG );
return;
@ -4221,7 +4422,7 @@ void SCH_IO_ALTIUM::ParseImplementation( const std::map<wxString, wxString>& aPr
if( implementationOwnerIt == m_altiumImplementationList.end() )
{
m_reporter->Report( wxString::Format( wxT( "Implementation's owner (%d) not found." ),
m_errorMessages.emplace( wxString::Format( wxT( "Implementation's owner (%d) not found." ),
elem.ownerindex ),
RPT_SEVERITY_DEBUG );
return;
@ -4231,7 +4432,7 @@ void SCH_IO_ALTIUM::ParseImplementation( const std::map<wxString, wxString>& aPr
if( libSymbolIt == m_libSymbols.end() )
{
m_reporter->Report( wxString::Format( wxT( "Footprint's owner (%d) not found." ),
m_errorMessages.emplace( wxString::Format( wxT( "Footprint's owner (%d) not found." ),
implementationOwnerIt->second ),
RPT_SEVERITY_DEBUG );
return;
@ -4463,7 +4664,7 @@ std::map<wxString,LIB_SYMBOL*> SCH_IO_ALTIUM::ParseLibFile( const ALTIUM_COMPOUN
case ALTIUM_SCH_RECORD::IMAGE: break;
default:
m_reporter->Report( wxString::Format( _( "Unknown or unexpected record id %d found "
m_errorMessages.emplace( wxString::Format( _( "Unknown or unexpected record id %d found "
"in %s." ),
recordId, symbols[0]->GetName() ),
RPT_SEVERITY_ERROR );

23
eeschema/sch_io/altium/sch_io_altium.h

@ -52,6 +52,23 @@ class ALTIUM_COMPOUND_FILE;
static std::vector<LIB_SYMBOL*> nullsym;
static std::vector<int> nullint;
struct HARNESS
{
struct HARNESS_PORT
{
VECTOR2I m_location;
VECTOR2I m_entryLocation;
ASCH_SHEET_ENTRY_SIDE m_harnessConnectorSide;
int m_primaryConnectionPosition;
wxString m_name;
};
wxString m_name;
VECTOR2I m_location;
VECTOR2I m_size;
std::vector<HARNESS_PORT> m_ports;
HARNESS_PORT m_entry;
};
class SCH_IO_ALTIUM : public SCH_IO
{
@ -129,6 +146,7 @@ private:
bool ShouldPutItemOnSheet( int aOwnerindex );
bool IsComponentPartVisible( const ASCH_OWNER_INTERFACE& aElem ) const;
const ASCH_STORAGE_FILE* GetFileFromStorage( const wxString& aFilename ) const;
void CreateAliases();
void AddTextBox( const ASCH_TEXT_FRAME* aElem );
void AddLibTextBox( const ASCH_TEXT_FRAME* aElem, std::vector<LIB_SYMBOL*>& aSymbol = nullsym, std::vector<int>& aFontSize = nullint );
@ -159,6 +177,7 @@ private:
void ParseSheetEntry( const std::map<wxString, wxString>& aProperties );
void ParsePowerPort( const std::map<wxString, wxString>& aProperties );
void ParsePort( const ASCH_PORT& aElem );
void ParsePortHelper( const ASCH_PORT& aElem );
void ParseNoERC( const std::map<wxString, wxString>& aProperties );
void ParseNetLabel( const std::map<wxString, wxString>& aProperties );
void ParseBus( const std::map<wxString, wxString>& aProperties );
@ -215,6 +234,7 @@ private:
// parse harness ports after "FileHeader" was parsed, in 2nd run.
std::vector<ASCH_PORT> m_altiumHarnessPortsCurrentSheet;
std::map<int, HARNESS> m_altiumHarnesses;
// Add offset to all harness ownerIndex'es after parsing FileHeader.
int m_harnessOwnerIndexOffset;
@ -233,6 +253,9 @@ private:
// List of available fonts with font name and font size in pt
std::vector<std::pair<wxString, int>> m_fonts;
// Cache the error messages to avoid duplicate messages
std::unordered_map<wxString, SEVERITY > m_errorMessages;
};
#endif // _SCH_IO_ALTIUM_H_
Loading…
Cancel
Save