25#include <wx/filename.h>
27#include <wx/xml/xml.h>
48 aChildNode->GetName(), aParentNode->GetName() ) );
56const std::map<CADSTAR_ARCHIVE_PARSER::TEXT_FIELD_NAME, wxString>
58 { { TEXT_FIELD_NAME::DESIGN_TITLE, wxT(
"DESIGN_TITLE" ) },
59 { TEXT_FIELD_NAME::SHORT_JOBNAME, wxT(
"SHORT_JOBNAME" ) },
60 { TEXT_FIELD_NAME::LONG_JOBNAME, wxT(
"LONG_JOBNAME" ) },
61 { TEXT_FIELD_NAME::NUM_OF_SHEETS, wxT(
"##" ) },
62 { TEXT_FIELD_NAME::SHEET_NUMBER, wxT(
"#" ) },
63 { TEXT_FIELD_NAME::SHEET_NAME, wxT(
"SHEETNAME" ) },
64 { TEXT_FIELD_NAME::VARIANT_NAME, wxT(
"VARIANT_NAME" ) },
65 { TEXT_FIELD_NAME::VARIANT_DESCRIPTION, wxT(
"VARIANT_DESCRIPTION" ) },
66 { TEXT_FIELD_NAME::REG_USER, wxT(
"REG_USER" ) },
67 { TEXT_FIELD_NAME::COMPANY_NAME, wxT(
"COMPANY_NAME" ) },
68 { TEXT_FIELD_NAME::CURRENT_USER, wxT(
"CURRENT_USER" ) },
69 { TEXT_FIELD_NAME::DATE, wxT(
"DATE" ) },
70 { TEXT_FIELD_NAME::TIME, wxT(
"TIME" ) },
71 { TEXT_FIELD_NAME::MACHINE_NAME, wxT(
"MACHINE_NAME" ) } };
76 wxASSERT( aNode->GetName() == wxT(
"FORMAT" ) );
86 wxASSERT( aNode->GetName() == wxT(
"TIMESTAMP" ) );
100 wxASSERT( aNode->GetName() == wxT(
"HEADER" ) );
104 for( ; cNode; cNode = cNode->
GetNext() )
106 wxString
nodeName = cNode->GetName();
110 Format.Parse( cNode, aContext );
112 else if(
nodeName == wxT(
"JOBFILE" ) )
116 else if(
nodeName == wxT(
"JOBTITLE" ) )
120 else if(
nodeName == wxT(
"GENERATOR" ) )
124 else if(
nodeName == wxT(
"RESOLUTION" ) )
128 if( ( subNode->GetName() == wxT(
"METRIC" ) )
143 else if(
nodeName == wxT(
"TIMESTAMP" ) )
157 wxASSERT( aNode->GetName() == wxT(
"VMASTER" ) || aNode->GetName() == wxT(
"VARIANT" ) );
161 if( aNode->GetName() == wxT(
"VMASTER" ) )
177 wxASSERT( aNode->GetName() == wxT(
"VHIERARCHY" ) );
181 for( ; cNode; cNode = cNode->
GetNext() )
183 if( cNode->GetName() == wxT(
"VMASTER" ) || cNode->GetName() == wxT(
"VARIANT" ) )
186 variant.
Parse( cNode, aContext );
187 Variants.insert( std::make_pair( variant.
ID, variant ) );
199 wxASSERT( aNode->GetName() == wxT(
"LINECODE" ) );
209 if( !cNode || cNode->GetName() != wxT(
"STYLE" ) )
214 if( styleStr == wxT(
"SOLID" ) )
218 else if( styleStr == wxT(
"DASH" ) )
222 else if( styleStr == wxT(
"DASHDOT" ) )
226 else if( styleStr == wxT(
"DASHDOTDOT" ) )
230 else if( styleStr == wxT(
"DOT" ) )
237 wxString::Format(
"LINECODE -> %s",
Name ) );
244 wxASSERT( aNode->GetName() == wxT(
"HATCH" ) );
251 if( !cNode || cNode->GetName() != wxT(
"ORIENT" ) )
260 wxASSERT( aNode->GetName() == wxT(
"HATCHCODE" ) );
266 wxString
location = wxString::Format(
"HATCHCODE -> %s",
Name );
268 for( ; cNode; cNode = cNode->
GetNext() )
270 if( cNode->GetName() != wxT(
"HATCH" ) )
277 hatch.
Parse( cNode, aContext );
285 wxASSERT( aNode->GetName() == wxT(
"FONT" ) );
293 for( ; cNode; cNode = cNode->
GetNext() )
295 wxString cNodeName = cNode->GetName();
297 if( cNodeName == wxT(
"ITALIC" ) )
299 else if( cNodeName == wxT(
"KERNING" ) )
309 wxASSERT( aNode->GetName() == wxT(
"TEXTCODE" ) );
322 if( cNode->GetName() == wxT(
"FONT" ) )
323 Font.Parse( cNode, aContext );
332 wxASSERT( aNode->GetName() == wxT(
"ROUTEREASSIGN" ) );
339 for( ; cNode; cNode = cNode->
GetNext() )
341 wxString cNodeName = cNode->GetName();
343 if( cNodeName == wxT(
"NECKWIDTH" ) )
345 else if( cNodeName == wxT(
"SROUTEWIDTH" ) )
347 else if( cNodeName == wxT(
"MINWIDTH" ) )
349 else if( cNodeName == wxT(
"MAXWIDTH" ) )
359 wxASSERT( aNode->GetName() == wxT(
"ROUTECODE" ) );
367 for( ; cNode; cNode = cNode->
GetNext() )
369 wxString cNodeName = cNode->GetName();
371 if( cNodeName == wxT(
"NECKWIDTH" ) )
375 else if( cNodeName == wxT(
"SROUTEWIDTH" ) )
379 else if( cNodeName == wxT(
"MINWIDTH" ) )
383 else if( cNodeName == wxT(
"MAXWIDTH" ) )
387 else if( cNodeName == wxT(
"ROUTEREASSIGN" ) )
390 routereassign.
Parse( cNode, aContext );
409 wxASSERT( aNode->GetName() == wxT(
"E" ) );
415 wxString::Format(
"%s->%s", aNode->
GetParent()->GetName(),
423 wxASSERT( aNode->GetName() == wxT(
"PT" ) );
432 wxASSERT( aNode->GetName() == wxT(
"PT" ) );
441 wxString aNodeName = aNode->GetName();
443 if( aNodeName == wxT(
"PT" ) || aNodeName == wxT(
"ACWARC" ) || aNodeName == wxT(
"CWARC" )
444 || aNodeName == wxT(
"CWSEMI" ) || aNodeName == wxT(
"ACWSEMI" ) )
459 wxString aNodeName = aNode->GetName();
461 if( aNodeName == wxT(
"PT" ) )
466 End.Parse( aNode, aContext );
468 else if( aNodeName == wxT(
"ACWARC" ) || aNodeName == wxT(
"CWARC" ) )
470 if( aNodeName == wxT(
"ACWARC" ) )
480 else if( aNodeName == wxT(
"ACWSEMI" ) || aNodeName == wxT(
"CWSEMI" ) )
482 if( aNodeName == wxT(
"ACWSEMI" ) )
496 wxASSERT_MSG(
true, wxT(
"Unknown VERTEX type" ) );
502 const std::function<
VECTOR2I(
const VECTOR2I& )> aCadstarToKicadPointCallback,
503 int aAccuracy )
const
507 aChainToAppendTo->
Append( aCadstarToKicadPointCallback(
End ) );
511 wxCHECK_MSG( aChainToAppendTo->
PointCount() > 0, ,
512 "Can't append an arc to vertex to an empty chain" );
515 aCadstarToKicadPointCallback ),
521 const std::function<
VECTOR2I(
const VECTOR2I& )> aCadstarToKicadPointCallback )
const
524 "Can't build an arc for a straight segment!" );
527 VECTOR2I endPoint = aCadstarToKicadPointCallback(
End );
531 centerPoint = ( startPoint / 2 ) + ( endPoint / 2 );
533 centerPoint = aCadstarToKicadPointCallback(
Center );
539 VECTOR2I transform = aCadstarToKicadPointCallback( { 500, 500 } )
540 - aCadstarToKicadPointCallback( { 0, 0 } );
542 if( ( transform.
x > 0 && transform.
y < 0 ) || ( transform.
x < 0 && transform.
y > 0 ) )
543 clockwise = !clockwise;
553 wxASSERT( aNode->GetName() == wxT(
"CUTOUT" ) );
561 wxString aNodeName = aNode->GetName();
563 if( aNodeName == wxT(
"OPENSHAPE" ) || aNodeName == wxT(
"OUTLINE" )
564 || aNodeName == wxT(
"SOLID" ) || aNodeName == wxT(
"HATCHED" ) )
579 wxString aNodeName = aNode->GetName();
581 if( aNodeName == wxT(
"OPENSHAPE" ) )
588 else if( aNodeName == wxT(
"OUTLINE" ) )
595 else if( aNodeName == wxT(
"SOLID" ) )
602 else if( aNodeName == wxT(
"HATCHED" ) )
611 wxASSERT_MSG(
true, wxT(
"Unknown SHAPE type" ) );
616 const std::function<
VECTOR2I(
const VECTOR2I& )> aCadstarToKicadPointCallback,
617 int aMaxError )
const
624 for(
const auto& vertex :
Vertices )
625 vertex.AppendToChain( &outline, aCadstarToKicadPointCallback, aMaxError );
640 const std::function<
VECTOR2I(
const VECTOR2I& )> aCadstarToKicadPointCallback,
641 int aMaxError )
const
650 for(
const auto& cutout :
Cutouts )
654 if( cutout.Vertices.size() == 0 )
657 for(
const auto& cutoutVertex : cutout.Vertices )
658 cutoutVertex.AppendToChain( &hole, aCadstarToKicadPointCallback, aMaxError );
663 cutout.Vertices.at( 0 ).AppendToChain( &hole, aCadstarToKicadPointCallback, aMaxError );
674 wxASSERT( aNode->GetName() == wxT(
"UNITS" ) );
678 if( unit == wxT(
"CENTIMETER" ) )
680 else if( unit == wxT(
"INCH" ) )
682 else if( unit == wxT(
"METER" ) )
684 else if( unit == wxT(
"MICROMETRE" ) )
686 else if( unit == wxT(
"MM" ) )
688 else if( unit == wxT(
"THOU" ) )
690 else if( unit == wxT(
"DESIGN" ) )
701 wxASSERT( aNode->GetName() == wxT(
"ANGUNITS" ) );
705 if( angUnitStr == wxT(
"DEGREES" ) )
707 else if( angUnitStr == wxT(
"RADIANS" ) )
721 wxString aNodeName = aNode->GetName();
723 if( aNodeName == wxT(
"FRACTIONALGRID" ) || aNodeName == wxT(
"STEPGRID" ) )
732 wxASSERT(
IsGrid( aNode ) );
734 wxString aNodeName = aNode->GetName();
736 if( aNodeName == wxT(
"FRACTIONALGRID" ) )
738 else if( aNodeName == wxT(
"STEPGRID" ) )
741 wxASSERT_MSG(
true, wxT(
"Unknown Grid Type" ) );
751 wxASSERT( aNode->GetName() == wxT(
"GRIDS" ) );
755 for( ; cNode; cNode = cNode->
GetNext() )
757 wxString cNodeName = cNode->GetName();
759 if( cNodeName == wxT(
"WORKINGGRID" ) )
765 wxString found = workingGridNode ? workingGridNode->GetName() : wxString(
"(empty)" );
773 else if( cNodeName == wxT(
"SCREENGRID" ) )
779 wxString found = screenGridNode ? screenGridNode->GetName() : wxString(
"(empty)" );
790 userGrid.
Parse( cNode, aContext );
803 wxString cNodeName = aChildNode->GetName();
805 if( cNodeName == wxT(
"UNITS" ) )
809 else if( cNodeName == wxT(
"UNITSPRECISION" ) )
813 else if( cNodeName == wxT(
"INTERLINEGAP" ) )
817 else if( cNodeName == wxT(
"BARLINEGAP" ) )
821 else if( cNodeName == wxT(
"ALLOWBARTEXT" ) )
825 else if( cNodeName == wxT(
"ANGULARPRECISION" ) )
829 else if( cNodeName == wxT(
"DESIGNORIGIN" ) )
833 else if( cNodeName == wxT(
"DESIGNAREA" ) )
836 DesignArea = std::make_pair( pts[0], pts[1] );
838 else if( cNodeName == wxT(
"DESIGNREF" ) )
842 else if( cNodeName == wxT(
"DESIGNLIMIT" ) )
846 else if( cNodeName == wxT(
"PINNOOFFSET" ) )
850 else if( cNodeName == wxT(
"PINNOANGLE" ) )
865 wxASSERT( aNode->GetName() == wxT(
"SETTINGS" ) );
869 for( ; cNode; cNode = cNode->
GetNext() )
871 wxString cNodeName = cNode->GetName();
884 static const std::map<TEXT_FIELD_NAME, wxString> txtTokens =
908 wxString remainingStr = aTextString;
911 while( remainingStr.size() > 0 )
914 size_t startpos = remainingStr.Find( wxT(
"<@" ) );
916 if(
static_cast<int>( startpos ) == wxNOT_FOUND )
919 returnStr += remainingStr;
924 returnStr += remainingStr.SubString( 0, startpos - 1 );
926 if( ( startpos + 2 ) >= remainingStr.size() )
929 remainingStr = remainingStr.Mid( startpos + 2 );
934 for( std::pair<TEXT_FIELD_NAME, wxString> txtF : txtTokens )
936 if( remainingStr.StartsWith( txtF.second ) )
938 foundField = txtF.first;
946 returnStr += wxT(
"<@" );
951 size_t endpos = remainingStr.Find( wxT(
"@>" ) );
953 if(
static_cast<int>( endpos ) == wxNOT_FOUND )
957 returnStr += wxT(
"<@" ) + remainingStr;
961 size_t valueStart = txtTokens.at( foundField ).size();
962 wxString fieldValue = remainingStr.SubString( valueStart, endpos - 1 );
968 wxASSERT_MSG( fieldValue.at( 0 ) ==
'"',
"Expected '\"' as the first character" );
970 size_t splitPos = fieldValue.find_first_of(
'"', 1 );
971 address = fieldValue.SubString( 1, splitPos - 1 );
976 wxASSERT_MSG( remainingStr.EndsWith( wxT(
"@>" ) ),
977 "Expected '@>' at the end of a hyperlink" );
979 fieldValue = remainingStr.SubString( valueStart + splitPos + 1,
980 remainingStr.Length() - 3 );
982 remainingStr = wxEmptyString;
986 fieldValue = fieldValue.Mid( splitPos + 1 );
1027 returnStr += fieldValue;
1032 wxFileName fn( address );
1033 wxString fieldFmt = wxT(
"FROM_FILE_%s_%s" );
1034 wxString fieldName = wxString::Format( fieldFmt, fn.GetName(), fn.GetExt() );
1043 fieldName = wxString::Format( fieldFmt, fn.GetName(), fn.GetExt() )
1044 + wxString::Format( wxT(
"_%d" ), version++ );
1048 returnStr += wxT(
"${" ) + fieldName + wxT(
"}" );
1060 wxFAIL_MSG(
"We should have already covered this scenario above" );
1065 if( ( endpos + 2 ) >= remainingStr.size() )
1068 remainingStr = remainingStr.Mid( endpos + 2 );
1077 wxASSERT( aNode->GetName() == wxT(
"ALIGN" ) );
1081 if( alignmentStr == wxT(
"BOTTOMCENTER" ) )
1083 else if( alignmentStr == wxT(
"BOTTOMLEFT" ) )
1085 else if( alignmentStr == wxT(
"BOTTOMRIGHT" ) )
1087 else if( alignmentStr == wxT(
"CENTERCENTER" ) )
1089 else if( alignmentStr == wxT(
"CENTERLEFT" ) )
1091 else if( alignmentStr == wxT(
"CENTERRIGHT" ) )
1093 else if( alignmentStr == wxT(
"TOPCENTER" ) )
1095 else if( alignmentStr == wxT(
"TOPLEFT" ) )
1097 else if( alignmentStr == wxT(
"TOPRIGHT" ) )
1109 wxASSERT( aNode->GetName() == wxT(
"JUSTIFICATION" ) );
1113 if( justificationStr == wxT(
"LEFT" ) )
1115 else if( justificationStr == wxT(
"RIGHT" ) )
1117 else if( justificationStr == wxT(
"CENTER" ) )
1128 wxASSERT( aNode->GetName() == wxT(
"READABILITY" ) );
1132 if( readabilityStr == wxT(
"BOTTOM_TO_TOP" ) )
1134 else if( readabilityStr == wxT(
"TOP_TO_BOTTOM" ) )
1154 wxString cNodeName = aChildNode->GetName();
1156 if( cNodeName == wxT(
"PT" ) )
1157 Position.Parse( aChildNode, aContext );
1158 else if( cNodeName == wxT(
"ORIENT" ) )
1160 else if( cNodeName == wxT(
"MIRROR" ) )
1162 else if( cNodeName == wxT(
"FIX" ) )
1164 else if( cNodeName == wxT(
"ALIGN" ) )
1166 else if( cNodeName == wxT(
"JUSTIFICATION" ) )
1177 wxASSERT( aNode->GetName() == wxT(
"ATTRLOC" ) );
1184 for( ; cNode; cNode = cNode->
GetNext() )
1199 wxASSERT( aNode->GetName() == wxT(
"COLUMNORDER" ) );
1210 wxASSERT( aNode->GetName() == wxT(
"COLUMNWIDTH" ) );
1221 wxASSERT( aNode->GetName() == wxT(
"ATTRNAME" ) );
1227 wxString
location = wxString::Format(
"ATTRNAME -> %s",
Name );
1229 for( ; cNode; cNode = cNode->
GetNext() )
1231 wxString cNodeName = cNode->GetName();
1233 if( cNodeName == wxT(
"ATTROWNER" ) )
1237 if( attOwnerVal == wxT(
"ALL_ITEMS" ) )
1239 else if( attOwnerVal == wxT(
"AREA" ) )
1241 else if( attOwnerVal == wxT(
"BOARD" ) )
1243 else if( attOwnerVal == wxT(
"COMPONENT" ) )
1245 else if( attOwnerVal == wxT(
"CONNECTION" ) )
1247 else if( attOwnerVal == wxT(
"COPPER" ) )
1249 else if( attOwnerVal == wxT(
"DOCSYMBOL" ) )
1251 else if( attOwnerVal == wxT(
"FIGURE" ) )
1253 else if( attOwnerVal == wxT(
"NET" ) )
1255 else if( attOwnerVal == wxT(
"NETCLASS" ) )
1257 else if( attOwnerVal == wxT(
"PART" ) )
1259 else if( attOwnerVal == wxT(
"PART_DEFINITION" ) )
1261 else if( attOwnerVal == wxT(
"PIN" ) )
1263 else if( attOwnerVal == wxT(
"SIGNALREF" ) )
1265 else if( attOwnerVal == wxT(
"SYMBOL" ) )
1267 else if( attOwnerVal == wxT(
"SYMDEF" ) )
1269 else if( attOwnerVal == wxT(
"TEMPLATE" ) )
1271 else if( attOwnerVal == wxT(
"TESTPOINT" ) )
1276 else if( cNodeName == wxT(
"ATTRUSAGE" ) )
1280 if( attUsageVal == wxT(
"BOTH" ) )
1282 else if( attUsageVal == wxT(
"COMPONENT" ) )
1284 else if( attUsageVal == wxT(
"PART_DEFINITION" ) )
1286 else if( attUsageVal == wxT(
"PART_LIBRARY" ) )
1288 else if( attUsageVal == wxT(
"SYMBOL" ) )
1293 else if( cNodeName == wxT(
"NOTRANSFER" ) )
1297 else if( cNodeName == wxT(
"COLUMNORDER" ) )
1300 cOrder.
Parse( cNode, aContext );
1303 else if( cNodeName == wxT(
"COLUMNWIDTH" ) )
1306 cWidth.
Parse( cNode, aContext );
1309 else if( cNodeName == wxT(
"COLUMNINVISIBLE" ) )
1323 wxASSERT( aNode->GetName() == wxT(
"ATTR" ) );
1330 for( ; cNode; cNode = cNode->
GetNext() )
1332 if( cNode->GetName() == wxT(
"READONLY" ) )
1336 else if( cNode->GetName() == wxT(
"ATTRLOC" ) )
1351 wxASSERT( aNode->GetName() == wxT(
"TEXTLOC" ) );
1354 bool attributeIDisSet =
false;
1356 if( attributeStr == wxT(
"PART_NAME" ) )
1359 attributeIDisSet =
true;
1361 else if( attributeStr == wxT(
"COMP_NAME" ) )
1364 attributeIDisSet =
true;
1366 else if( attributeStr == wxT(
"COMP_NAME2" ) )
1369 attributeIDisSet =
true;
1371 else if( attributeStr == wxT(
"SYMBOL_NAME" ) )
1374 attributeIDisSet =
true;
1376 else if( attributeStr == wxT(
"LINK_ORIGIN" ) )
1379 attributeIDisSet =
true;
1381 else if( attributeStr == wxT(
"SIGNALNAME_ORIGIN" ) )
1384 attributeIDisSet =
true;
1386 else if( attributeStr == wxT(
"ATTRREF" ) )
1389 attributeIDisSet =
false;
1402 for( ; cNode; cNode = cNode->
GetNext() )
1404 wxString cNodeName = cNode->GetName();
1410 else if( !attributeIDisSet && cNodeName == wxT(
"ATTRREF" ) )
1413 attributeIDisSet =
true;
1415 else if( cNodeName == wxT(
"ORIENT" ) )
1419 else if( cNodeName == wxT(
"MIRROR" ) )
1423 else if( cNodeName == wxT(
"FIX" ) )
1427 else if( cNodeName == wxT(
"ALIGN" ) )
1431 else if( cNodeName == wxT(
"JUSTIFICATION" ) )
1448 wxASSERT( aNode->GetName() == wxT(
"NETCLASS" ) );
1454 wxString
location = wxString::Format(
"NETCLASS -> %s",
Name );
1456 for( ; cNode; cNode = cNode->
GetNext() )
1458 wxString cNodeName = cNode->GetName();
1460 if( cNodeName == wxT(
"ATTR" ) )
1463 attribute_val.
Parse( cNode, aContext );
1476 wxASSERT( aNode->GetName() == wxT(
"SPCCLASSNAME" ) );
1485 wxString
nodeName = aChildNode->GetName();
1487 if(
nodeName == wxT(
"LINECODE" ) )
1490 linecode.
Parse( aChildNode, aContext );
1491 LineCodes.insert( std::make_pair( linecode.
ID, linecode ) );
1493 else if(
nodeName == wxT(
"HATCHCODE" ) )
1496 hatchcode.
Parse( aChildNode, aContext );
1497 HatchCodes.insert( std::make_pair( hatchcode.
ID, hatchcode ) );
1499 else if(
nodeName == wxT(
"TEXTCODE" ) )
1502 textcode.
Parse( aChildNode, aContext );
1503 TextCodes.insert( std::make_pair( textcode.
ID, textcode ) );
1505 else if(
nodeName == wxT(
"ROUTECODE" ) )
1508 routecode.
Parse( aChildNode, aContext );
1509 RouteCodes.insert( std::make_pair( routecode.
ID, routecode ) );
1511 else if(
nodeName == wxT(
"ATTRNAME" ) )
1514 attrname.
Parse( aChildNode, aContext );
1517 else if(
nodeName == wxT(
"NETCLASS" ) )
1520 netclass.
Parse( aChildNode, aContext );
1521 NetClasses.insert( std::make_pair( netclass.
ID, netclass ) );
1523 else if(
nodeName == wxT(
"SPCCLASSNAME" ) )
1526 spcclassname.
Parse( aChildNode, aContext );
1540 wxASSERT( aNode->GetName() == wxT(
"SWAPRULE" ) );
1545 if( swapRuleStr == wxT(
"NO_SWAP" ) )
1547 else if( swapRuleStr == wxT(
"USE_SWAP_LAYER" ) )
1558 wxASSERT( aNode->GetName() == wxT(
"REUSEBLOCK" ) );
1566 for( ; cNode; cNode = cNode->
GetNext() )
1568 wxString cNodeName = cNode->GetName();
1570 if( cNodeName == wxT(
"MIRROR" ) )
1572 else if( cNodeName == wxT(
"ORIENT" ) )
1588 wxASSERT( aNode->GetName() == wxT(
"REUSEBLOCKREF" ) );
1599 wxASSERT( aNode->GetName() == wxT(
"GROUP" ) );
1606 for( ; cNode; cNode = cNode->
GetNext() )
1608 wxString cNodeName = cNode->GetName();
1610 if( cNodeName == wxT(
"FIX" ) )
1612 else if( cNodeName == wxT(
"TRANSFER" ) )
1614 else if( cNodeName == wxT(
"GROUPREF" ) )
1616 else if( cNodeName == wxT(
"REUSEBLOCKREF" ) )
1626 wxASSERT( aNode->GetName() == wxT(
"FIGURE" ) );
1633 bool shapeIsInitialised =
false;
1634 wxString
location = wxString::Format(
"Figure %s",
ID );
1639 for( ; cNode; cNode = cNode->
GetNext() )
1641 wxString cNodeName = cNode->GetName();
1643 if( !shapeIsInitialised &&
Shape.IsShape( cNode ) )
1645 Shape.Parse( cNode, aContext );
1646 shapeIsInitialised =
true;
1648 else if( cNodeName == wxT(
"SWAPRULE" ) )
1652 else if( cNodeName == wxT(
"FIX" ) )
1656 else if( cNodeName == wxT(
"GROUPREF" ) )
1661 else if( cNodeName == wxT(
"REUSEBLOCKREF" ) )
1665 else if( cNodeName == wxT(
"ATTR" ) )
1668 attr.
Parse( cNode, aContext );
1681 Parse( aNode, aContext,
true );
1688 wxASSERT( aNode->GetName() == wxT(
"TEXT" ) );
1704 for( ; cNode; cNode = cNode->
GetNext() )
1706 wxString cNodeName = cNode->GetName();
1708 if( cNodeName == wxT(
"PT" ) )
1710 else if( cNodeName == wxT(
"ORIENT" ) )
1712 else if( cNodeName == wxT(
"MIRROR" ) )
1714 else if( cNodeName == wxT(
"FIX" ) )
1716 else if( cNodeName == wxT(
"SWAPRULE" ) )
1718 else if( cNodeName == wxT(
"ALIGN" ) )
1720 else if( cNodeName == wxT(
"JUSTIFICATION" ) )
1722 else if( cNodeName == wxT(
"GROUPREF" ) )
1724 else if( cNodeName == wxT(
"REUSEBLOCKREF" ) )
1740 wxASSERT( aNode->GetName() == wxT(
"SYMDEF" ) );
1750 wxString cNodeName = aChildNode->GetName();
1752 if( cNodeName == wxT(
"PT" ) )
1754 Origin.Parse( aChildNode, aContext );
1756 else if( cNodeName == wxT(
"STUB" ) )
1760 else if( cNodeName == wxT(
"VERSION" ) )
1764 else if( cNodeName == wxT(
"FIGURE" ) )
1767 figure.
Parse( aChildNode, aContext );
1768 Figures.insert( std::make_pair( figure.
ID, figure ) );
1770 else if( cNodeName == wxT(
"TEXT" ) )
1773 txt.
Parse( aChildNode, aContext );
1774 Texts.insert( std::make_pair( txt.
ID, txt ) );
1776 else if( cNodeName == wxT(
"TEXTLOC" ) )
1779 textloc.
Parse( aChildNode, aContext );
1782 else if( cNodeName == wxT(
"ATTR" ) )
1785 attrVal.
Parse( aChildNode, aContext );
1799 wxASSERT( aNode->GetName() == wxT(
"GATEDEFINITION" ) );
1812 wxASSERT( aNode->GetName() == wxT(
"PINTYPE" ) );
1816 std::map<wxString, CADSTAR_PIN_TYPE> pinTypeMap = {
1827 if( pinTypeMap.find( pinTypeStr ) == pinTypeMap.end() )
1833 return pinTypeMap[pinTypeStr];
1839 wxASSERT( aNode->GetName() == wxT(
"PARTDEFINITIONPIN" ) );
1845 for( ; cNode; cNode = cNode->
GetNext() )
1847 wxString cNodeName = cNode->GetName();
1849 if( cNodeName == wxT(
"PINNAME" ) )
1853 else if( cNodeName == wxT(
"PINLABEL" ) )
1857 else if( cNodeName == wxT(
"PINSIGNAL" ) )
1861 else if( cNodeName == wxT(
"PINTERM" ) )
1866 else if( cNodeName == wxT(
"PINTYPE" ) )
1870 else if( cNodeName == wxT(
"PINLOAD" ) )
1874 else if( cNodeName == wxT(
"PINPOSITION" ) )
1878 else if( cNodeName == wxT(
"PINIDENTIFIER" ) )
1892 wxASSERT( aNode->GetName() == wxT(
"PARTPIN" ) );
1898 for( ; cNode; cNode = cNode->
GetNext() )
1900 wxString cNodeName = cNode->GetName();
1902 if( cNodeName == wxT(
"PINNAME" ) )
1904 else if( cNodeName == wxT(
"PINTYPE" ) )
1906 else if( cNodeName == wxT(
"PINIDENTIFIER" ) )
1917 wxASSERT( aNode->GetName() == wxT(
"PINEQUIVALENCE" ) );
1919 wxXmlAttribute* xmlAttribute = aNode->GetAttributes();
1921 for( ; xmlAttribute; xmlAttribute = xmlAttribute->GetNext() )
1928 if( !xmlAttribute->GetValue().ToLong( &pinId ) )
1941 wxASSERT( aNode->GetName() == wxT(
"SWAPGATE" ) );
1943 wxXmlAttribute* xmlAttribute = aNode->GetAttributes();
1945 for( ; xmlAttribute; xmlAttribute = xmlAttribute->GetNext() )
1952 if( !xmlAttribute->GetValue().ToLong( &pinId ) )
1965 wxASSERT( aNode->GetName() == wxT(
"SWAPGROUP" ) );
1971 for( ; cNode; cNode = cNode->
GetNext() )
1973 wxString cNodeName = cNode->GetName();
1975 if( cNodeName == wxT(
"EXTERNAL" ) )
1979 else if( cNodeName == wxT(
"SWAPGATE" ) )
1982 swapGate.
Parse( cNode, aContext );
1995 wxASSERT( aNode->GetName() == wxT(
"PARTDEFINITION" ) );
2001 for( ; cNode; cNode = cNode->
GetNext() )
2003 wxString cNodeName = cNode->GetName();
2005 if( cNodeName == wxT(
"HIDEPINNAMES" ) )
2009 else if( cNodeName == wxT(
"MAXPIN" ) )
2013 else if( cNodeName == wxT(
"GATEDEFINITION" ) )
2016 gate.
Parse( cNode, aContext );
2019 else if( cNodeName == wxT(
"PARTDEFINITIONPIN" ) )
2022 pin.Parse( cNode, aContext );
2023 Pins.insert( std::make_pair(
pin.ID,
pin ) );
2025 else if( cNodeName == wxT(
"ATTR" ) )
2028 attr.
Parse( cNode, aContext );
2031 else if( cNodeName == wxT(
"PINEQUIVALENCE" ) )
2034 pinEq.
Parse( cNode, aContext );
2037 else if( cNodeName == wxT(
"SWAPGROUP" ) )
2040 swapGroup.
Parse( cNode, aContext );
2053 wxASSERT( aNode->GetName() == wxT(
"PART" ) );
2060 for( ; cNode; cNode = cNode->
GetNext() )
2062 wxString cNodeName = cNode->GetName();
2064 if( cNodeName == wxT(
"VERSION" ) )
2068 else if( cNodeName == wxT(
"HIDEPINNAMES" ) )
2072 else if( cNodeName == wxT(
"PARTDEFINITION" ) )
2076 else if( cNodeName == wxT(
"PARTPIN" ) )
2079 pin.Parse( cNode, aContext );
2082 else if( cNodeName == wxT(
"ATTR" ) )
2085 attr.
Parse( cNode, aContext );
2098 wxASSERT( aNode->GetName() == wxT(
"PARTS" ) );
2102 for( ; cNode; cNode = cNode->
GetNext() )
2104 wxString cNodeName = cNode->GetName();
2106 if( cNodeName == wxT(
"PART" ) )
2109 part.
Parse( cNode, aContext );
2125 wxASSERT( aNode->GetName() == wxT(
"JPT" ) );
2135 wxString cNodeName = aChildNode->GetName();
2137 if( cNodeName == wxT(
"PT" ) )
2138 Location.Parse( aChildNode, aContext );
2139 else if( cNodeName == wxT(
"FIX" ) )
2141 else if( cNodeName == wxT(
"GROUPREF" ) )
2143 else if( cNodeName == wxT(
"REUSEBLOCKREF" ) )
2157 for( ; cNode; cNode = cNode->
GetNext() )
2170 wxASSERT( aNode->GetName() == wxT(
"CONN" ) );
2181 wxString cNodeName = aChildNode->GetName();
2183 if( cNodeName == wxT(
"FIX" ) )
2187 else if( cNodeName == wxT(
"HIDDEN" ) )
2191 else if( cNodeName == wxT(
"GROUPREF" ) )
2195 else if( cNodeName == wxT(
"REUSEBLOCKREF" ) )
2199 else if( cNodeName == wxT(
"ATTR" ) )
2202 attrVal.
Parse( aChildNode, aContext );
2216 wxASSERT( aNode->GetName() == wxT(
"NET" ) );
2224 wxString cNodeName = aChildNode->GetName();
2226 if( cNodeName == wxT(
"NETCODE" ) )
2230 else if( cNodeName == wxT(
"SIGNAME" ) )
2234 else if( cNodeName == wxT(
"SIGNUM" ) )
2238 else if( cNodeName == wxT(
"HIGHLIT" ) )
2242 else if( cNodeName == wxT(
"JPT" ) )
2245 jpt.
Parse( aChildNode, aContext );
2246 Junctions.insert( std::make_pair( jpt.
ID, jpt ) );
2248 else if( cNodeName == wxT(
"NETCLASSREF" ) )
2252 else if( cNodeName == wxT(
"SPACINGCLASS" ) )
2256 else if( cNodeName == wxT(
"ATTR" ) )
2259 attrVal.
Parse( aChildNode, aContext );
2273 wxASSERT( aNode->GetName() == wxT(
"DOCSYMBOL" ) );
2280 bool originParsed =
false;
2282 for( ; cNode; cNode = cNode->
GetNext() )
2284 wxString cNodeName = cNode->GetName();
2286 if( !originParsed && cNodeName == wxT(
"PT" ) )
2288 Origin.Parse( cNode, aContext );
2289 originParsed =
true;
2291 else if( cNodeName == wxT(
"GROUPREF" ) )
2295 else if( cNodeName == wxT(
"REUSEBLOCKREF" ) )
2299 else if( cNodeName == wxT(
"FIX" ) )
2303 else if( cNodeName == wxT(
"MIRROR" ) )
2307 else if( cNodeName == wxT(
"READABILITY" ) )
2311 else if( cNodeName == wxT(
"ORIENT" ) )
2315 else if( cNodeName == wxT(
"ATTR" ) )
2318 attr.
Parse( cNode, aContext );
2321 else if( cNodeName == wxT(
"SCALE" ) )
2339 wxASSERT( aNode->GetName() == wxT(
"DFLTSETTINGS" ) );
2345 for( ; cNode; cNode = cNode->
GetNext() )
2347 wxString cNodeName = cNode->GetName();
2349 if( cNodeName == wxT(
"INVISIBLE" ) )
2363 wxASSERT( aNode->GetName() == wxT(
"ATTRCOL" ) );
2370 for( ; cNode; cNode = cNode->
GetNext() )
2372 wxString cNodeName = cNode->GetName();
2374 if( cNodeName == wxT(
"INVISIBLE" ) )
2378 else if( cNodeName == wxT(
"NOTPICKABLE" ) )
2392 wxASSERT( aNode->GetName() == wxT(
"ATTRCOLORS" ) );
2396 for( ; cNode; cNode = cNode->
GetNext() )
2398 wxString cNodeName = cNode->GetName();
2400 if( cNodeName == wxT(
"DFLTSETTINGS" ) )
2404 else if( cNodeName == wxT(
"ATTRCOL" ) )
2407 attrcol.
Parse( cNode, aContext );
2410 else if( cNodeName == wxT(
"INVISIBLE" ) )
2424 wxASSERT( aNode->GetName() == wxT(
"PARTNAMECOL" ) );
2430 for( ; cNode; cNode = cNode->
GetNext() )
2432 wxString cNodeName = cNode->GetName();
2434 if( cNodeName == wxT(
"INVISIBLE" ) )
2438 else if( cNodeName == wxT(
"NOTPICKABLE" ) )
2452 static const wxString c_numAttributes = wxT(
"numAttributes" );
2455 long numAttributes = 0;
2457 if( aNode->GetAttribute( c_numAttributes, &
result ) )
2459 numAttributes = wxAtol(
result );
2460 aNode->DeleteAttribute( c_numAttributes );
2464#if wxUSE_UNICODE_WCHAR
2465 std::wstring numAttrStr = std::to_wstring( numAttributes );
2467 std::string numAttrStr = std::to_string( numAttributes );
2472 wxString paramName = wxT(
"attr" );
2473 paramName << numAttrStr;
2480 const wxString& aFileTypeIdentifier,
2483 KEYWORD emptyKeywords[1] = {};
2484 XNODE* rootNode =
nullptr;
2485 XNODE* cNode =
nullptr;
2486 XNODE* iNode =
nullptr;
2488 bool cadstarFileCheckDone =
false;
2490 wxCSConv win1252( wxT(
"windows-1252" ) );
2491 wxMBConv* conv = &win1252;
2495 FILE* fp = wxFopen( aFileName, wxT(
"rt" ) );
2498 THROW_IO_ERROR( wxString::Format(
_(
"Cannot open file '%s'" ), aFileName ) );
2500 fseek( fp, 0
L, SEEK_END );
2501 long fileSize = ftell( fp );
2504 DSNLEXER lexer( emptyKeywords, 0,
nullptr, fp, aFileName );
2506 auto currentProgress = [&]() ->
double
2508 return static_cast<double>( ftell( fp ) ) / fileSize;
2511 double previousReportedProgress = -1.0;
2515 if( aProgressReporter && ( currentProgress() - previousReportedProgress ) > 0.01 )
2525 previousReportedProgress = currentProgress();
2539 THROW_IO_ERROR(
_(
"The selected file is not valid or might be corrupt!" ) );
2545 str = wxString( lexer.
CurText(), *conv );
2546 cNode =
new XNODE( wxXML_ELEMENT_NODE, str );
2555 iNode->AddChild( cNode );
2557 else if( !cadstarFileCheckDone )
2559 if( cNode->GetName() != aFileTypeIdentifier )
2562 THROW_IO_ERROR(
_(
"The selected file is not valid or might be corrupt!" ) );
2565 cadstarFileCheckDone =
true;
2572 str = wxString( lexer.
CurText(), *conv );
2580 THROW_IO_ERROR(
_(
"The selected file is not valid or might be corrupt!" ) );
2585 if( iNode !=
nullptr )
2588 THROW_IO_ERROR(
_(
"The selected file is not valid or might be corrupt!" ) );
2599 THROW_IO_ERROR(
_(
"The selected file is not valid or might be corrupt!" ) );
2608 return aAttribute->GetName() != wxT(
"numAttributes" );
2615#if wxUSE_UNICODE_WCHAR
2616 std::wstring idStr = std::to_wstring( aID );
2618 std::string idStr = std::to_string( aID );
2621 wxString attrName = wxS(
"attr" );
2626 if( !aNode->GetAttribute( attrName, &retVal ) )
2631 return wxEmptyString;
2665 if( aNode && aNode->
GetNext() )
2673 if( aNode->
GetChildren()->GetName() == wxT(
"E" ) )
2683 std::vector<POINT> retVal;
2687 for( ; cNode; cNode = cNode->
GetNext() )
2689 if( cNode->GetName() == wxT(
"PT" ) )
2695 pt.
Parse( cNode, aContext );
2702 retVal.push_back( pt );
2704 else if( aTestAllChildNodes )
2711 && retVal.size() !=
static_cast<size_t>( aExpectedNumPoints ) )
2714 _(
"Unexpected number of points in '%s'. Found %d but expected %d." ),
2715 aNode->GetName(), retVal.size(), aExpectedNumPoints ) );
2725 std::vector<VERTEX> retVal;
2729 for( ; cNode; cNode = cNode->
GetNext() )
2737 vertex.
Parse( cNode, aContext );
2744 retVal.push_back( vertex );
2746 else if( aTestAllChildNodes )
2759 std::vector<CUTOUT> retVal;
2763 for( ; cNode; cNode = cNode->
GetNext() )
2765 if( cNode->GetName() == wxT(
"CUTOUT" ) )
2771 cutout.
Parse( cNode, aContext );
2778 retVal.push_back( cutout );
2780 else if( aTestAllChildNodes )
2795 for( ; childNodes; childNodes = childNodes->
GetNext() )
2803 XNODE* aRootNode, std::vector<wxString> aSubNodeChildrenToCount )
2808 for( ; level1Node; level1Node = level1Node->
GetNext() )
2810 for( wxString childNodeName : aSubNodeChildrenToCount )
2812 if( level1Node->GetName() == childNodeName )
2825 wxString escapedText = aCadstarString;
2827 escapedText.Replace( wxT(
"'" ), wxT(
"~" ) );
2835 if( !aKiCadTextItem->
GetText().IsEmpty() )
2842 int numExtraLines =
text.Replace(
"\n",
"\n" );
2843 numExtraLines -=
text.at(
text.size() - 1 ) ==
'\n';
2844 positionOffset.
x *= numExtraLines;
2845 positionOffset.
y *= numExtraLines;
2847 aKiCadTextItem->
Offset( positionOffset );
2853 const wxString& aAlternateName )
2855 if( aAlternateName.IsEmpty() )
CADSTAR_PIN_POSITION
Positioning of pin names can be in one of four quadrants.
CADSTAR_PIN_TYPE
file: cadstar_archive_objects.h Contains common object definitions
@ OUTPUT_NOT_OR
Output pin not OR tieable.
@ TRISTATE_DRIVER
Tristate output pin.
@ OUTPUT_OR
Output pin OR tieable.
@ UNCOMMITTED
Uncommitted pin (default)
@ TRISTATE_INPUT
Tristate input pin.
@ TRISTATE_BIDIR
Tristate bi-directional driver pin.
@ OUTPUT_NOT_NORM_OR
Output pin not normally OR tieable.
static void reThrowWithParentContext(const IO_ERROR &aError, XNODE *aChildNode, XNODE *aParentNode)
Helper functions and common defines between schematic and PCB Archive files.
#define SYMBOL_NAME_ATTRID
Symbol Name attribute ID - used for placement of designators on the schematic.
#define SIGNALNAME_ORIGIN_ATTRID
#define WARN_UNKNOWN_NODE_IO_ERROR(nodename, location)
#define THROW_MISSING_NODE_IO_ERROR(nodename, location)
#define THROW_UNKNOWN_NODE_IO_ERROR(nodename, location)
#define LINK_ORIGIN_ATTRID
#define COMPONENT_NAME_2_ATTRID
Component Name 2 Attribute ID - typically used for indicating the placement of designators in placeme...
#define THROW_UNKNOWN_PARAMETER_IO_ERROR(param, location)
#define COMPONENT_NAME_ATTRID
Component Name Attribute ID - typically used for placement of designators on silk screen.
#define WARN_UNKNOWN_PARAMETER_IO_ERROR(param, location)
#define THROW_MISSING_PARAMETER_IO_ERROR(param, location)
#define THROW_PARSING_IO_ERROR(param, location)
READABILITY
Sets the readability direction of text.
@ BOTTOM_TO_TOP
When text is vertical, show it rotated 90 degrees anticlockwise.
@ TOP_TO_BOTTOM
When text is vertical, show it rotated 90 degrees clockwise.
@ ANTICLOCKWISE_SEMICIRCLE
@ STEPGRID
Param1 = X Step, Param2 = Y Step. A standard x,y grid.
@ FRACTIONALGRID
Param1 = Units, Param2 = Divisor.
SWAP_RULE
Corresponds to "Display when" Item property.
@ USE_SWAP_LAYER
Display when Mirrored.
@ NO_SWAP
Display when Unmirrored.
static UNITS ParseUnits(XNODE *aNode)
static ALIGNMENT ParseAlignment(XNODE *aNode)
static const std::map< TEXT_FIELD_NAME, wxString > CADSTAR_TO_KICAD_FIELDS
Map between CADSTAR fields and KiCad text variables.
TEXT_FIELD_NAME
These are special fields in text objects enclosed between the tokens '<@' and '>' such as <@[FIELD_NA...
@ NONE
Synthetic for flagging.
static SWAP_RULE ParseSwapRule(XNODE *aNode)
ALIGNMENT
From CADSTAR Help: "Text Alignment enables you to define the position of an alignment origin for all ...
@ NO_ALIGNMENT
NO_ALIGNMENT has different meaning depending on the object type.
static const long UNDEFINED_VALUE
static wxString generateLibName(const wxString &aRefName, const wxString &aAlternateName)
static void CheckNoNextNodes(XNODE *aNode)
static std::vector< CUTOUT > ParseAllChildCutouts(XNODE *aNode, PARSER_CONTEXT *aContext, bool aTestAllChildNodes=false)
If no children are present, it just returns an empty vector (without throwing an exception).
static XNODE * LoadArchiveFile(const wxString &aFileName, const wxString &aFileTypeIdentifier, PROGRESS_REPORTER *aProgressReporter=nullptr)
Reads a CADSTAR Archive file (S-parameter format).
static JUSTIFICATION ParseJustification(XNODE *aNode)
static wxString ParseTextFields(const wxString &aTextString, PARSER_CONTEXT *aParserContext)
Replaces CADSTAR fields for the equivalent in KiCad and stores the field values in aParserContext.
@ PART_DEFINITION
From CADSTAR Help: Assigned to Parts library Definitions and displayed by the Library searcher.
@ BOTH
From CADSTAR Help: Assigned to both Schematic symbols and PCB components, and displayed on Schematic ...
@ COMPONENT
From CADSTAR Help: Assigned to PCB components and displayed on PCB designs.
@ SYMBOL
From CADSTAR Help: Assigned to Schematic Symbols and displayed on Schematic Designs.
@ PART_LIBRARY
From CADSTAR Help: Only used by non-Cadstar applications.
static std::vector< VERTEX > ParseAllChildVertices(XNODE *aNode, PARSER_CONTEXT *aContext, bool aTestAllChildNodes=false)
If no children are present, it just returns an empty vector (without throwing an exception).
static void FixTextPositionNoAlignment(EDA_TEXT *aKiCadTextItem)
Correct the position of a text element that had NO_ALIGNMENT in CADSTAR.
static ANGUNITS ParseAngunits(XNODE *aNode)
long PART_DEFINITION_PIN_ID
Pin identifier in the part definition.
@ OUTLINE
Unfilled closed shape.
@ OPENSHAPE
Unfilled open shape. Cannot have cutouts.
@ SOLID
Filled closed shape (solid fill).
@ HATCHED
Filled closed shape (hatch fill).
static const double TXT_HEIGHT_RATIO
CADSTAR fonts are drawn on a 24x24 integer matrix, where the each axis goes from 0 to 24.
static wxString GetXmlAttributeIDString(XNODE *aNode, unsigned int aID, bool aIsRequired=true)
void checkPoint()
Updates m_progressReporter or throws if user canceled.
static bool IsValidAttribute(wxXmlAttribute *aAttribute)
static READABILITY ParseReadability(XNODE *aNode)
static std::vector< POINT > ParseAllChildPoints(XNODE *aNode, PARSER_CONTEXT *aContext, bool aTestAllChildNodes=false, int aExpectedNumPoints=UNDEFINED_VALUE)
If no children are present, it just returns an empty vector (without throwing an exception).
@ DESIGN
Inherits from design units (assumed Assignments->Technology->Units)
static wxString HandleTextOverbar(wxString aCadstarString)
Convert a string with CADSTAR overbar characters to equivalent in KiCad.
static void CheckNoChildNodes(XNODE *aNode)
static long GetXmlAttributeIDLong(XNODE *aNode, unsigned int aID, bool aIsRequired=true)
JUSTIFICATION
From CADSTAR Help: "Multi Line Text can also be justified as Left, Centre or Right.
static void ParseChildEValue(XNODE *aNode, PARSER_CONTEXT *aContext, EVALUE &aValueToParse)
static long GetNumberOfStepsForReporting(XNODE *aRootNode, std::vector< wxString > aSubNodeChildrenToCount)
PROGRESS_REPORTER * m_progressReporter
static long GetNumberOfChildNodes(XNODE *aNode)
static void InsertAttributeAtEnd(XNODE *aNode, wxString aValue)
@ PART_DEFINITION
Only library Attributes.
@ PART
Only library Attributes.
Implement a lexical analyzer for the SPECCTRA DSN file format.
const char * CurText() const
Return a pointer to the current token's text.
int NextTok()
Return the next token found in the input file or DSN_EOF when reaching the end of file.
A mix-in class (via multiple inheritance) that handles texts such as labels, parts,...
virtual const wxString & GetText() const
Return the string associated with the text object.
virtual void Offset(const VECTOR2I &aOffset)
virtual EDA_ANGLE GetTextAngle() const
int GetInterline(const RENDER_SETTINGS *aSettings) const
Return the distance between two lines of text.
Hold an error message and may be used when throwing exceptions containing meaningful error messages.
virtual const wxString Problem() const
what was the problem?
A progress reporter interface for use in multi-threaded environments.
virtual bool KeepRefreshing(bool aWait=false)=0
Update the UI (if any).
virtual void SetCurrentProgress(double aProgress)=0
Set the progress value to aProgress (0..1).
SHAPE_ARC & ConstructFromStartEndCenter(const VECTOR2I &aStart, const VECTOR2I &aEnd, const VECTOR2I &aCenter, bool aClockwise=false, double aWidth=0)
Constructs this arc from the given start, end and center.
Represent a polyline containing arcs as well as line segments: A chain of connected line and/or arc s...
virtual const VECTOR2I GetPoint(int aIndex) const override
void SetClosed(bool aClosed)
Mark the line chain as closed (i.e.
int PointCount() const
Return the number of points (vertices) in this line chain.
void Append(int aX, int aY, bool aAllowDuplication=false)
Append a new point at the end of the line chain.
const VECTOR2I & CPoint(int aIndex) const
Return a reference to a given point in the line chain.
Represent a set of closed polygons.
int AddOutline(const SHAPE_LINE_CHAIN &aOutline)
Adds a new outline to the set and returns its index.
int AddHole(const SHAPE_LINE_CHAIN &aHole, int aOutline=-1)
Adds a new hole to the given outline (default: last) and returns its index.
An extension of wxXmlNode that can format its contents as KiCad-style s-expressions.
XNODE * GetParent() const
XNODE * GetChildren() const
void AddAttribute(const wxString &aName, const wxString &aValue) override
#define THROW_IO_ERROR(msg)
macro which captures the "call site" values of FILE_, __FUNCTION & LINE
This file contains miscellaneous commonly used macros and functions.
#define KI_FALLTHROUGH
The KI_FALLTHROUGH macro is to be used when switch statement cases should purposely fallthrough from ...
static wxString nodeName(const wxString &aSymbolPin)
wxString ConvertToNewOverbarNotation(const wxString &aOldStr)
Convert the old ~...~ overbar notation to the new ~{...} one.
wxString EscapeString(const wxString &aSource, ESCAPE_CONTEXT aContext)
The Escape/Unescape routines use HTML-entity-reference-style encoding to handle characters which are:...
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
DFLTSETTINGS DefaultSettings
std::map< ATTRIBUTE_ID, ATTRCOL > AttributeColors
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
void ParseIdentifiers(XNODE *aNode, PARSER_CONTEXT *aContext)
virtual void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
JUSTIFICATION Justification
Note: Justification has no effect on single lines of text.
ALIGNMENT Alignment
In CADSTAR The default alignment for a TEXT object (when "(No Alignment()" is selected) Bottom Left o...
bool ParseSubNode(XNODE *aChildNode, PARSER_CONTEXT *aContext)
ATTRIBUTE_LOCATION AttributeLocation
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
bool HasLocation
Flag to know if this ATTRIBUTE_VALUE has a location i.e.
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
NOTE from CADSTAR help: To convert a Part Definition Attribute into a hyperlink, prefix the attribute...
std::vector< COLUMNWIDTH > ColumnWidths
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
bool NoTransfer
True="All Design Types", False="Current Design Type" "All Design Types" Description from CADSTAR Help...
std::vector< COLUMNORDER > ColumnOrders
wxString Name
Parenthesis aren't permitted in user attributes in CADSTAR.
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
std::vector< ATTRIBUTE_VALUE > Attributes
std::map< SPACING_CLASS_ID, SPCCLASSNAME > SpacingClassNames
std::map< LINECODE_ID, LINECODE > LineCodes
std::map< NETCLASS_ID, CADSTAR_NETCLASS > NetClasses
bool ParseSubNode(XNODE *aChildNode, PARSER_CONTEXT *aContext)
std::map< HATCHCODE_ID, HATCHCODE > HatchCodes
std::map< ATTRIBUTE_ID, ATTRNAME > AttributeNames
std::map< ROUTECODE_ID, ROUTECODE > RouteCodes
std::map< TEXTCODE_ID, TEXTCODE > TextCodes
Represent a cutout in a closed shape (e.g.
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
std::vector< VERTEX > Vertices
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
long ScaleRatioNumerator
Documentation symbols can be arbitrarily scaled when added to a design.
std::map< ATTRIBUTE_ID, ATTRIBUTE_VALUE > AttributeValues
long ScaleRatioDenominator
Documentation symbols can be arbitrarily scaled when added to a design.
POINT Origin
Origin of the component (this is used as the reference point when placing the component in the design...
REUSEBLOCKREF ReuseBlockRef
GROUP_ID GroupID
If not empty, this component is part of a group.
LAYER_ID LayerID
Move all objects in the Symdef to this layer.
DOCUMENTATION_SYMBOL_ID ID
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
SYMDEF_ID SymdefID
Normally documentation symbols only have TEXT, FIGURE and TEXT_LOCATION objects which are all drawn o...
Represent a floating value in E notation.
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
long Modifier2
It seems this is always 0 regardless of settings.
bool KerningPairs
From CADSTAR Help: "Kerning Pairs is for causing the system to automatically reduce the spacing...
long Modifier1
It seems this is related to weight. 400=Normal, 700=Bold.
GRID ScreenGrid
From CADSTAR Help: "There is one Screen Grid, which is visible as dots on the screen.
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
std::vector< GRID > UserGrids
List of predefined grids created by the user.
static bool IsGrid(XNODE *aNode)
long Param1
Either Units or X step, depending on Type (see GRID_TYPE for more details)
long Param2
Either Divisor or Y step, depending on Type (see GRID_TYPE for more details)
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
GROUP_ID GroupID
If not empty, this GROUP is part of another GROUP.
bool Transfer
If true, the group is transferred to PCB.
REUSEBLOCKREF ReuseBlockRef
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
std::vector< HATCH > Hatches
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
long OrientAngle
1/1000 of a Degree
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
std::map< ATTRIBUTE_ID, ATTRIBUTE_VALUE > AttributeValues
It is possible to add attributes solely to a particular connection.
REUSEBLOCKREF ReuseBlockRef
void ParseIdentifiers(XNODE *aNode, PARSER_CONTEXT *aContext)
GROUP_ID GroupID
If not empty, this connection is part of a group.
bool ParseSubNode(XNODE *aChildNode, PARSER_CONTEXT *aContext)
GROUP_ID GroupID
If not empty, this JUNCTION is part of a group.
bool ParseSubNode(XNODE *aChildNode, PARSER_CONTEXT *aContext)
virtual void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
void ParseIdentifiers(XNODE *aNode, PARSER_CONTEXT *aContext)
NETELEMENT_ID ID
First character is "J".
REUSEBLOCKREF ReuseBlockRef
ROUTECODE_ID RouteCodeID
"NETCODE" subnode
bool ParseSubNode(XNODE *aChildNode, PARSER_CONTEXT *aContext)
wxString Name
This is undefined (wxEmptyString) if the net is unnamed.
std::map< NETELEMENT_ID, JUNCTION > Junctions
void ParseIdentifiers(XNODE *aNode, PARSER_CONTEXT *aContext)
NETCLASS_ID NetClassID
The net might not have a net class, in which case it will be wxEmptyString ("NETCLASSREF" subnode)
SPACING_CLASS_ID SpacingClassID
The net might not have a spacing class, in which case it will be wxEmptyString ("SPACINGCLASS" subnod...
std::map< ATTRIBUTE_ID, ATTRIBUTE_VALUE > AttributeValues
long SignalNum
This is undefined if the net has been given a name.
std::map< TEXT_FIELD_NAME, wxString > TextFieldToValuesMap
Values for the text field elements used in the CADSTAR design extracted from the text element instanc...
std::map< wxString, wxString > FilenamesToTextMap
CADSTAR doesn't have user defined text fields but does allow loading text from a file.
std::map< wxString, wxString > TextToHyperlinksMap
KiCad doesn't support hyperlinks but we use this map to display warning messages after import.
std::set< TEXT_FIELD_NAME > InconsistentTextFields
Text fields need to be updated in CADSTAR and it is possible that they are not consistent across text...
std::function< void()> CheckPointCallback
Callback function to report progress.
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
std::map< PART_ID, PART > PartDefinitions
< "GATEDEFINITION" node name
long PinCount
Number of pins (terminals) in the symbol.
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
GATE_ID ID
Usually "A", "B", "C", etc.
wxString Alternate
Symbol alternate name in the symbol library.
wxString Name
Symbol name in the symbol library.
< "PINEQUIVALENCE" Node name
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
std::vector< PART_DEFINITION_PIN_ID > PinIDs
All the pins in this vector are equivalent and can be swapped with each other.
< "PARTDEFINITIONPIN" node name
wxString Label
This Can be empty (subnode= "PINLABEL") From CADSTAR Help: "Pin Labels are an optional replacement fo...
wxString Name
Can be empty.
long Load
The electrical current expected on the pin (It is unclear what the units are, but only accepted value...
CADSTAR_PIN_POSITION Position
The pin names will use these positions when the symbol is added to a design subnode="PINPOSITION".
TERMINAL_ID TerminalPin
(subnode="PINTERM", param1)
wxString Identifier
This should match a pad identifier in the component footprint subnode="PINIDENTIFIER".
GATE_ID TerminalGate
(subnode="PINTERM", param0)
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
wxString Signal
Usually for Power/Ground pins, (subnode="PINSIGNAL")
PART_DEFINITION_PIN_ID ID
CADSTAR_PIN_TYPE Type
subnode="PINTYPE"
< "SWAPGATE" Node name (represents an "Element")
std::vector< PART_DEFINITION_PIN_ID > PinIDs
The pins in this vector describe a "gate".
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
wxString GateName
Optional.
std::vector< SWAP_GATE > SwapGates
Each of the elements in this vector can be swapped with each other - i.e.
bool External
Determines if this swap group is external (and internal) or internal only.
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
bool HidePinNames
Specifies whether to display the pin names/identifier in the schematic symbol or not.
std::map< GATE_ID, GATE > GateSymbols
std::vector< PIN_EQUIVALENCE > PinEquivalences
wxString Name
This name can be different to the PART name.
long MaxPinCount
Optional parameter which is used for specifying the number of electrical pins on the PCB component sy...
std::map< ATTRIBUTE_ID, ATTRIBUTE_VALUE > AttributeValues
Some attributes are defined within the part definition, whilst others are defined in the part.
std::map< PART_DEFINITION_PIN_ID, PIN > Pins
std::vector< SWAP_GROUP > SwapGroups
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
static CADSTAR_PIN_TYPE GetPinType(XNODE *aNode)
std::map< PART_PIN_ID, PART_PIN > PartPins
It is unclear why there are two "Pin" structures in CPA files... PART_PIN seems to be a reduced versi...
std::map< ATTRIBUTE_ID, ATTRIBUTE_VALUE > AttributeValues
Some attributes are defined within the part definition, whilst others are defined in the part itself.
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
bool HidePinNames
This seems to be a duplicate of DEFINITION::HidePinNames Possibly only used in older file formats?
Represent a point in x,y coordinates.
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
REUSEBLOCK_ID ReuseBlockID
wxString ItemReference
For Components, this references the designator in the reuse file.
bool IsEmpty()
Determines if this is empty (i.e. no design reuse associated)
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
wxString FileName
Filename of the reuse block (usually a .pcb). Used for reloading.
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
std::vector< ROUTEREASSIGN > RouteReassigns
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
UNITS Units
Units to display for linear dimensions.
long PinNoAngle
The angle at which the Pin ID is positioned relative to a terminal.
long InterlineGap
For CADSTAR font only, distance between lines of text, expressed as a percentage of the text height (...
long BarlineGap
For CADSTAR font only, distance between top bar and character, expressed as a percentage of the text ...
virtual void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
bool AllowBarredText
Specifies if barring is allowed in the design.
std::pair< POINT, POINT > DesignArea
long AngularPrecision
Number of decimal points to display for angular dimensions.
long UnitDisplPrecision
Number of decimal points to display for linear dimensions.
bool ParseSubNode(XNODE *aChildNode, PARSER_CONTEXT *aContext)
long PinNoOffset
The distance, of a Pin Name/Identifier from its parent terminal.
SHAPE_POLY_SET ConvertToPolySet(const std::function< VECTOR2I(const VECTOR2I &)> aCadstarToKicadPointCallback, int aAccuracy) const
std::vector< VERTEX > Vertices
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
wxString HatchCodeID
Only Applicable for HATCHED Type.
static bool IsShape(XNODE *aNode)
std::vector< CUTOUT > Cutouts
Not Applicable to OPENSHAPE Type.
SHAPE_LINE_CHAIN OutlineAsChain(const std::function< VECTOR2I(const VECTOR2I &)> aCadstarToKicadPointCallback, int aAccuracy) const
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
std::map< FIGURE_ID, FIGURE > Figures
std::map< ATTRIBUTE_ID, TEXT_LOCATION > TextLocations
This contains location of any attributes, including designator position.
POINT Origin
Origin of the component (this is used as the reference point when placing the component in the design...
wxString Alternate
This is in addition to ReferenceName.
bool ParseSubNode(XNODE *aChildNode, PARSER_CONTEXT *aContext)
std::map< TEXT_ID, TEXT > Texts
bool Stub
When the CADSTAR Archive file is exported without the component library, if components on the board a...
wxString ReferenceName
This is the name which identifies the symbol in the library Multiple components may exist with the sa...
void ParseIdentifiers(XNODE *aNode, PARSER_CONTEXT *aContext)
std::map< ATTRIBUTE_ID, ATTRIBUTE_VALUE > AttributeValues
These attributes might also have a location.
wxString BuildLibName() const
long Version
Version is a sequential integer number to identify discrepancies between the library and the design.
long Width
Defaults to 0 if using system fonts or, if using CADSTAR font, default to equal height (1:1 aspect ra...
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
Corresponds to CADSTAR "origin".
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
REUSEBLOCKREF ReuseBlockRef
ALIGNMENT Alignment
In CADSTAR The default alignment for a TEXT object (when "(No Alignment)" is selected) Bottom Left of...
JUSTIFICATION Justification
Note: has no effect on single lines of text.
GROUP_ID GroupID
If not empty, this FIGURE is part of a group.
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
std::map< VARIANT_ID, VARIANT > Variants
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
< Nodename = "VARIANT" or "VMASTER" (master variant
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
VARIANT_ID ParentID
if empty, then this one is the master
Represents a vertex in a shape.
static bool IsVertex(XNODE *aNode)
SHAPE_ARC BuildArc(const VECTOR2I &aPrevPoint, const std::function< VECTOR2I(const VECTOR2I &)> aCadstarToKicadPointCallback) const
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
void AppendToChain(SHAPE_LINE_CHAIN *aChainToAppendTo, const std::function< VECTOR2I(const VECTOR2I &)> aCadstarToKicadPointCallback, int aAccuracy) const
Hold a keyword string and its unique integer token.
wxString result
Test unit parsing edge cases and error handling.
void RotatePoint(int *pX, int *pY, const EDA_ANGLE &aAngle)
Calculate the new point of coord coord pX, pY, for a rotation center 0, 0.
VECTOR2< int32_t > VECTOR2I