25#include <wx/filename.h>
27#include <wx/xml/xml.h>
43const std::map<CADSTAR_ARCHIVE_PARSER::TEXT_FIELD_NAME, wxString>
45 { { TEXT_FIELD_NAME::DESIGN_TITLE, wxT(
"DESIGN_TITLE" ) },
46 { TEXT_FIELD_NAME::SHORT_JOBNAME, wxT(
"SHORT_JOBNAME" ) },
47 { TEXT_FIELD_NAME::LONG_JOBNAME, wxT(
"LONG_JOBNAME" ) },
48 { TEXT_FIELD_NAME::NUM_OF_SHEETS, wxT(
"##" ) },
49 { TEXT_FIELD_NAME::SHEET_NUMBER, wxT(
"#" ) },
50 { TEXT_FIELD_NAME::SHEET_NAME, wxT(
"SHEETNAME" ) },
51 { TEXT_FIELD_NAME::VARIANT_NAME, wxT(
"VARIANT_NAME" ) },
52 { TEXT_FIELD_NAME::VARIANT_DESCRIPTION, wxT(
"VARIANT_DESCRIPTION" ) },
53 { TEXT_FIELD_NAME::REG_USER, wxT(
"REG_USER" ) },
54 { TEXT_FIELD_NAME::COMPANY_NAME, wxT(
"COMPANY_NAME" ) },
55 { TEXT_FIELD_NAME::CURRENT_USER, wxT(
"CURRENT_USER" ) },
56 { TEXT_FIELD_NAME::DATE, wxT(
"DATE" ) },
57 { TEXT_FIELD_NAME::TIME, wxT(
"TIME" ) },
58 { TEXT_FIELD_NAME::MACHINE_NAME, wxT(
"MACHINE_NAME" ) } };
63 wxASSERT( aNode->GetName() == wxT(
"FORMAT" ) );
73 wxASSERT( aNode->GetName() == wxT(
"TIMESTAMP" ) );
87 wxASSERT( aNode->GetName() == wxT(
"HEADER" ) );
91 for( ; cNode; cNode = cNode->
GetNext() )
93 wxString nodeName = cNode->GetName();
95 if( nodeName == wxT(
"FORMAT" ) )
97 Format.Parse( cNode, aContext );
99 else if( nodeName == wxT(
"JOBFILE" ) )
103 else if( nodeName == wxT(
"JOBTITLE" ) )
107 else if( nodeName == wxT(
"GENERATOR" ) )
111 else if( nodeName == wxT(
"RESOLUTION" ) )
115 if( ( subNode->GetName() == wxT(
"METRIC" ) )
130 else if( nodeName == wxT(
"TIMESTAMP" ) )
144 wxASSERT( aNode->GetName() == wxT(
"VMASTER" ) || aNode->GetName() == wxT(
"VARIANT" ) );
148 if( aNode->GetName() == wxT(
"VMASTER" ) )
164 wxASSERT( aNode->GetName() == wxT(
"VHIERARCHY" ) );
168 for( ; cNode; cNode = cNode->
GetNext() )
170 if( cNode->GetName() == wxT(
"VMASTER" ) || cNode->GetName() == wxT(
"VARIANT" ) )
173 variant.
Parse( cNode, aContext );
174 Variants.insert( std::make_pair( variant.
ID, variant ) );
186 wxASSERT( aNode->GetName() == wxT(
"LINECODE" ) );
196 if( !cNode || cNode->GetName() != wxT(
"STYLE" ) )
201 if( styleStr == wxT(
"SOLID" ) )
205 else if( styleStr == wxT(
"DASH" ) )
209 else if( styleStr == wxT(
"DASHDOT" ) )
213 else if( styleStr == wxT(
"DASHDOTDOT" ) )
217 else if( styleStr == wxT(
"DOT" ) )
224 wxString::Format(
"LINECODE -> %s",
Name ) );
231 wxASSERT( aNode->GetName() == wxT(
"HATCH" ) );
238 if( !cNode || cNode->GetName() != wxT(
"ORIENT" ) )
247 wxASSERT( aNode->GetName() == wxT(
"HATCHCODE" ) );
253 wxString
location = wxString::Format(
"HATCHCODE -> %s",
Name );
255 for( ; cNode; cNode = cNode->
GetNext() )
257 if( cNode->GetName() != wxT(
"HATCH" ) )
261 hatch.
Parse( cNode, aContext );
269 wxASSERT( aNode->GetName() == wxT(
"FONT" ) );
277 for( ; cNode; cNode = cNode->
GetNext() )
279 wxString cNodeName = cNode->GetName();
281 if( cNodeName == wxT(
"ITALIC" ) )
283 else if( cNodeName == wxT(
"KERNING" ) )
293 wxASSERT( aNode->GetName() == wxT(
"TEXTCODE" ) );
306 if( cNode->GetName() == wxT(
"FONT" ) )
307 Font.Parse( cNode, aContext );
316 wxASSERT( aNode->GetName() == wxT(
"ROUTEREASSIGN" ) );
323 for( ; cNode; cNode = cNode->
GetNext() )
325 wxString cNodeName = cNode->GetName();
327 if( cNodeName == wxT(
"NECKWIDTH" ) )
329 else if( cNodeName == wxT(
"SROUTEWIDTH" ) )
331 else if( cNodeName == wxT(
"MINWIDTH" ) )
333 else if( cNodeName == wxT(
"MAXWIDTH" ) )
343 wxASSERT( aNode->GetName() == wxT(
"ROUTECODE" ) );
351 for( ; cNode; cNode = cNode->
GetNext() )
353 wxString cNodeName = cNode->GetName();
355 if( cNodeName == wxT(
"NECKWIDTH" ) )
359 else if( cNodeName == wxT(
"SROUTEWIDTH" ) )
363 else if( cNodeName == wxT(
"MINWIDTH" ) )
367 else if( cNodeName == wxT(
"MAXWIDTH" ) )
371 else if( cNodeName == wxT(
"ROUTEREASSIGN" ) )
374 routereassign.
Parse( cNode, aContext );
393 wxASSERT( aNode->GetName() == wxT(
"E" ) );
399 wxString::Format(
"%s->%s", aNode->
GetParent()->GetName(),
407 wxASSERT( aNode->GetName() == wxT(
"PT" ) );
416 wxASSERT( aNode->GetName() == wxT(
"PT" ) );
425 wxString aNodeName = aNode->GetName();
427 if( aNodeName == wxT(
"PT" ) || aNodeName == wxT(
"ACWARC" ) || aNodeName == wxT(
"CWARC" )
428 || aNodeName == wxT(
"CWSEMI" ) || aNodeName == wxT(
"ACWSEMI" ) )
443 wxString aNodeName = aNode->GetName();
445 if( aNodeName == wxT(
"PT" ) )
450 End.Parse( aNode, aContext );
452 else if( aNodeName == wxT(
"ACWARC" ) || aNodeName == wxT(
"CWARC" ) )
454 if( aNodeName == wxT(
"ACWARC" ) )
464 else if( aNodeName == wxT(
"ACWSEMI" ) || aNodeName == wxT(
"CWSEMI" ) )
466 if( aNodeName == wxT(
"ACWSEMI" ) )
480 wxASSERT_MSG(
true, wxT(
"Unknown VERTEX type" ) );
486 const std::function<
VECTOR2I(
const VECTOR2I& )> aCadstarToKicadPointCallback,
487 int aAccuracy )
const
491 aChainToAppendTo->
Append( aCadstarToKicadPointCallback(
End ) );
495 wxCHECK_MSG( aChainToAppendTo->
PointCount() > 0, ,
496 "Can't append an arc to vertex to an empty chain" );
499 aCadstarToKicadPointCallback ),
505 const std::function<
VECTOR2I(
const VECTOR2I& )> aCadstarToKicadPointCallback )
const
508 "Can't build an arc for a straight segment!" );
511 VECTOR2I endPoint = aCadstarToKicadPointCallback(
End );
515 centerPoint = ( startPoint / 2 ) + ( endPoint / 2 );
517 centerPoint = aCadstarToKicadPointCallback(
Center );
523 VECTOR2I transform = aCadstarToKicadPointCallback( { 500, 500 } )
524 - aCadstarToKicadPointCallback( { 0, 0 } );
526 if( ( transform.
x > 0 && transform.
y < 0 ) || ( transform.
x < 0 && transform.
y > 0 ) )
527 clockwise = !clockwise;
537 wxASSERT( aNode->GetName() == wxT(
"CUTOUT" ) );
545 wxString aNodeName = aNode->GetName();
547 if( aNodeName == wxT(
"OPENSHAPE" ) || aNodeName == wxT(
"OUTLINE" )
548 || aNodeName == wxT(
"SOLID" ) || aNodeName == wxT(
"HATCHED" ) )
563 wxString aNodeName = aNode->GetName();
565 if( aNodeName == wxT(
"OPENSHAPE" ) )
572 else if( aNodeName == wxT(
"OUTLINE" ) )
579 else if( aNodeName == wxT(
"SOLID" ) )
586 else if( aNodeName == wxT(
"HATCHED" ) )
595 wxASSERT_MSG(
true, wxT(
"Unknown SHAPE type" ) );
600 const std::function<
VECTOR2I(
const VECTOR2I& )> aCadstarToKicadPointCallback,
601 int aMaxError )
const
608 for(
const auto& vertex :
Vertices )
609 vertex.AppendToChain( &outline, aCadstarToKicadPointCallback, aMaxError );
624 const std::function<
VECTOR2I(
const VECTOR2I& )> aCadstarToKicadPointCallback,
625 int aMaxError )
const
634 for(
const auto& cutout :
Cutouts )
638 if( cutout.Vertices.size() == 0 )
641 for(
const auto& cutoutVertex : cutout.Vertices )
642 cutoutVertex.AppendToChain( &hole, aCadstarToKicadPointCallback, aMaxError );
647 cutout.Vertices.at( 0 ).AppendToChain( &hole, aCadstarToKicadPointCallback, aMaxError );
658 wxASSERT( aNode->GetName() == wxT(
"UNITS" ) );
662 if( unit == wxT(
"CENTIMETER" ) )
664 else if( unit == wxT(
"INCH" ) )
666 else if( unit == wxT(
"METER" ) )
668 else if( unit == wxT(
"MICROMETRE" ) )
670 else if( unit == wxT(
"MM" ) )
672 else if( unit == wxT(
"THOU" ) )
674 else if( unit == wxT(
"DESIGN" ) )
685 wxASSERT( aNode->GetName() == wxT(
"ANGUNITS" ) );
689 if( angUnitStr == wxT(
"DEGREES" ) )
691 else if( angUnitStr == wxT(
"RADIANS" ) )
702 wxString aNodeName = aNode->GetName();
704 if( aNodeName == wxT(
"FRACTIONALGRID" ) || aNodeName == wxT(
"STEPGRID" ) )
713 wxASSERT(
IsGrid( aNode ) );
715 wxString aNodeName = aNode->GetName();
717 if( aNodeName == wxT(
"FRACTIONALGRID" ) )
719 else if( aNodeName == wxT(
"STEPGRID" ) )
722 wxASSERT_MSG(
true, wxT(
"Unknown Grid Type" ) );
732 wxASSERT( aNode->GetName() == wxT(
"GRIDS" ) );
736 for( ; cNode; cNode = cNode->
GetNext() )
738 wxString cNodeName = cNode->GetName();
740 if( cNodeName == wxT(
"WORKINGGRID" ) )
747 workingGridNode->GetName(), wxT(
"GRIDS -> WORKINGGRID" ) );
754 else if( cNodeName == wxT(
"SCREENGRID" ) )
761 screenGridNode->GetName(), wxT(
"GRIDS -> SCREENGRID" ) );
771 userGrid.
Parse( cNode, aContext );
780 wxString cNodeName = aChildNode->GetName();
782 if( cNodeName == wxT(
"UNITS" ) )
786 else if( cNodeName == wxT(
"UNITSPRECISION" ) )
790 else if( cNodeName == wxT(
"INTERLINEGAP" ) )
794 else if( cNodeName == wxT(
"BARLINEGAP" ) )
798 else if( cNodeName == wxT(
"ALLOWBARTEXT" ) )
802 else if( cNodeName == wxT(
"ANGULARPRECISION" ) )
806 else if( cNodeName == wxT(
"DESIGNORIGIN" ) )
810 else if( cNodeName == wxT(
"DESIGNAREA" ) )
813 DesignArea = std::make_pair( pts[0], pts[1] );
815 else if( cNodeName == wxT(
"DESIGNREF" ) )
819 else if( cNodeName == wxT(
"DESIGNLIMIT" ) )
823 else if( cNodeName == wxT(
"PINNOOFFSET" ) )
827 else if( cNodeName == wxT(
"PINNOANGLE" ) )
842 wxASSERT( aNode->GetName() == wxT(
"SETTINGS" ) );
846 for( ; cNode; cNode = cNode->
GetNext() )
848 wxString cNodeName = cNode->GetName();
861 static const std::map<TEXT_FIELD_NAME, wxString> txtTokens =
885 wxString remainingStr = aTextString;
888 while( remainingStr.size() > 0 )
891 size_t startpos = remainingStr.Find( wxT(
"<@" ) );
893 if(
static_cast<int>( startpos ) == wxNOT_FOUND )
896 returnStr += remainingStr;
901 returnStr += remainingStr.SubString( 0, startpos - 1 );
903 if( ( startpos + 2 ) >= remainingStr.size() )
906 remainingStr = remainingStr.Mid( startpos + 2 );
911 for( std::pair<TEXT_FIELD_NAME, wxString> txtF : txtTokens )
913 if( remainingStr.StartsWith( txtF.second ) )
915 foundField = txtF.first;
923 returnStr += wxT(
"<@" );
928 size_t endpos = remainingStr.Find( wxT(
"@>" ) );
930 if(
static_cast<int>( endpos ) == wxNOT_FOUND )
934 returnStr += wxT(
"<@" ) + remainingStr;
938 size_t valueStart = txtTokens.at( foundField ).size();
939 wxString fieldValue = remainingStr.SubString( valueStart, endpos - 1 );
945 wxASSERT_MSG( fieldValue.at( 0 ) ==
'"',
"Expected '\"' as the first character" );
947 size_t splitPos = fieldValue.find_first_of(
'"', 1 );
948 address = fieldValue.SubString( 1, splitPos - 1 );
953 wxASSERT_MSG( remainingStr.EndsWith( wxT(
"@>" ) ),
954 "Expected '@>' at the end of a hyperlink" );
956 fieldValue = remainingStr.SubString( valueStart + splitPos + 1,
957 remainingStr.Length() - 3 );
959 remainingStr = wxEmptyString;
963 fieldValue = fieldValue.Mid( splitPos + 1 );
1004 returnStr += fieldValue;
1009 wxFileName fn( address );
1010 wxString fieldFmt = wxT(
"FROM_FILE_%s_%s" );
1011 wxString fieldName = wxString::Format( fieldFmt, fn.GetName(), fn.GetExt() );
1020 fieldName = wxString::Format( fieldFmt, fn.GetName(), fn.GetExt() )
1021 + wxString::Format( wxT(
"_%d" ), version++ );
1025 returnStr += wxT(
"${" ) + fieldName + wxT(
"}" );
1037 wxFAIL_MSG(
"We should have already covered this scenario above" );
1042 if( ( endpos + 2 ) >= remainingStr.size() )
1045 remainingStr = remainingStr.Mid( endpos + 2 );
1054 wxASSERT( aNode->GetName() == wxT(
"ALIGN" ) );
1058 if( alignmentStr == wxT(
"BOTTOMCENTER" ) )
1060 else if( alignmentStr == wxT(
"BOTTOMLEFT" ) )
1062 else if( alignmentStr == wxT(
"BOTTOMRIGHT" ) )
1064 else if( alignmentStr == wxT(
"CENTERCENTER" ) )
1066 else if( alignmentStr == wxT(
"CENTERLEFT" ) )
1068 else if( alignmentStr == wxT(
"CENTERRIGHT" ) )
1070 else if( alignmentStr == wxT(
"TOPCENTER" ) )
1072 else if( alignmentStr == wxT(
"TOPLEFT" ) )
1074 else if( alignmentStr == wxT(
"TOPRIGHT" ) )
1086 wxASSERT( aNode->GetName() == wxT(
"JUSTIFICATION" ) );
1090 if( justificationStr == wxT(
"LEFT" ) )
1092 else if( justificationStr == wxT(
"RIGHT" ) )
1094 else if( justificationStr == wxT(
"CENTER" ) )
1105 wxASSERT( aNode->GetName() == wxT(
"READABILITY" ) );
1109 if( readabilityStr == wxT(
"BOTTOM_TO_TOP" ) )
1111 else if( readabilityStr == wxT(
"TOP_TO_BOTTOM" ) )
1131 wxString cNodeName = aChildNode->GetName();
1133 if( cNodeName == wxT(
"PT" ) )
1134 Position.Parse( aChildNode, aContext );
1135 else if( cNodeName == wxT(
"ORIENT" ) )
1137 else if( cNodeName == wxT(
"MIRROR" ) )
1139 else if( cNodeName == wxT(
"FIX" ) )
1141 else if( cNodeName == wxT(
"ALIGN" ) )
1143 else if( cNodeName == wxT(
"JUSTIFICATION" ) )
1154 wxASSERT( aNode->GetName() == wxT(
"ATTRLOC" ) );
1161 for( ; cNode; cNode = cNode->
GetNext() )
1176 wxASSERT( aNode->GetName() == wxT(
"COLUMNORDER" ) );
1187 wxASSERT( aNode->GetName() == wxT(
"COLUMNWIDTH" ) );
1198 wxASSERT( aNode->GetName() == wxT(
"ATTRNAME" ) );
1204 wxString
location = wxString::Format(
"ATTRNAME -> %s",
Name );
1206 for( ; cNode; cNode = cNode->
GetNext() )
1208 wxString cNodeName = cNode->GetName();
1210 if( cNodeName == wxT(
"ATTROWNER" ) )
1214 if( attOwnerVal == wxT(
"ALL_ITEMS" ) )
1216 else if( attOwnerVal == wxT(
"AREA" ) )
1218 else if( attOwnerVal == wxT(
"BOARD" ) )
1220 else if( attOwnerVal == wxT(
"COMPONENT" ) )
1222 else if( attOwnerVal == wxT(
"CONNECTION" ) )
1224 else if( attOwnerVal == wxT(
"COPPER" ) )
1226 else if( attOwnerVal == wxT(
"DOCSYMBOL" ) )
1228 else if( attOwnerVal == wxT(
"FIGURE" ) )
1230 else if( attOwnerVal == wxT(
"NET" ) )
1232 else if( attOwnerVal == wxT(
"NETCLASS" ) )
1234 else if( attOwnerVal == wxT(
"PART" ) )
1236 else if( attOwnerVal == wxT(
"PART_DEFINITION" ) )
1238 else if( attOwnerVal == wxT(
"PIN" ) )
1240 else if( attOwnerVal == wxT(
"SIGNALREF" ) )
1242 else if( attOwnerVal == wxT(
"SYMBOL" ) )
1244 else if( attOwnerVal == wxT(
"SYMDEF" ) )
1246 else if( attOwnerVal == wxT(
"TEMPLATE" ) )
1248 else if( attOwnerVal == wxT(
"TESTPOINT" ) )
1253 else if( cNodeName == wxT(
"ATTRUSAGE" ) )
1257 if( attUsageVal == wxT(
"BOTH" ) )
1259 else if( attUsageVal == wxT(
"COMPONENT" ) )
1261 else if( attUsageVal == wxT(
"PART_DEFINITION" ) )
1263 else if( attUsageVal == wxT(
"PART_LIBRARY" ) )
1265 else if( attUsageVal == wxT(
"SYMBOL" ) )
1270 else if( cNodeName == wxT(
"NOTRANSFER" ) )
1274 else if( cNodeName == wxT(
"COLUMNORDER" ) )
1277 cOrder.
Parse( cNode, aContext );
1280 else if( cNodeName == wxT(
"COLUMNWIDTH" ) )
1283 cWidth.
Parse( cNode, aContext );
1286 else if( cNodeName == wxT(
"COLUMNINVISIBLE" ) )
1300 wxASSERT( aNode->GetName() == wxT(
"ATTR" ) );
1307 for( ; cNode; cNode = cNode->
GetNext() )
1309 if( cNode->GetName() == wxT(
"READONLY" ) )
1313 else if( cNode->GetName() == wxT(
"ATTRLOC" ) )
1328 wxASSERT( aNode->GetName() == wxT(
"TEXTLOC" ) );
1331 bool attributeIDisSet =
false;
1333 if( attributeStr == wxT(
"PART_NAME" ) )
1336 attributeIDisSet =
true;
1338 else if( attributeStr == wxT(
"COMP_NAME" ) )
1341 attributeIDisSet =
true;
1343 else if( attributeStr == wxT(
"COMP_NAME2" ) )
1346 attributeIDisSet =
true;
1348 else if( attributeStr == wxT(
"SYMBOL_NAME" ) )
1351 attributeIDisSet =
true;
1353 else if( attributeStr == wxT(
"LINK_ORIGIN" ) )
1356 attributeIDisSet =
true;
1358 else if( attributeStr == wxT(
"SIGNALNAME_ORIGIN" ) )
1361 attributeIDisSet =
true;
1363 else if( attributeStr == wxT(
"ATTRREF" ) )
1366 attributeIDisSet =
false;
1379 for( ; cNode; cNode = cNode->
GetNext() )
1381 wxString cNodeName = cNode->GetName();
1387 else if( !attributeIDisSet && cNodeName == wxT(
"ATTRREF" ) )
1390 attributeIDisSet =
true;
1392 else if( cNodeName == wxT(
"ORIENT" ) )
1396 else if( cNodeName == wxT(
"MIRROR" ) )
1400 else if( cNodeName == wxT(
"FIX" ) )
1404 else if( cNodeName == wxT(
"ALIGN" ) )
1408 else if( cNodeName == wxT(
"JUSTIFICATION" ) )
1425 wxASSERT( aNode->GetName() == wxT(
"NETCLASS" ) );
1431 wxString
location = wxString::Format(
"NETCLASS -> %s",
Name );
1433 for( ; cNode; cNode = cNode->
GetNext() )
1435 wxString cNodeName = cNode->GetName();
1437 if( cNodeName == wxT(
"ATTR" ) )
1440 attribute_val.
Parse( cNode, aContext );
1453 wxASSERT( aNode->GetName() == wxT(
"SPCCLASSNAME" ) );
1462 wxString nodeName = aChildNode->GetName();
1464 if( nodeName == wxT(
"LINECODE" ) )
1467 linecode.
Parse( aChildNode, aContext );
1468 LineCodes.insert( std::make_pair( linecode.
ID, linecode ) );
1470 else if( nodeName == wxT(
"HATCHCODE" ) )
1473 hatchcode.
Parse( aChildNode, aContext );
1474 HatchCodes.insert( std::make_pair( hatchcode.
ID, hatchcode ) );
1476 else if( nodeName == wxT(
"TEXTCODE" ) )
1479 textcode.
Parse( aChildNode, aContext );
1480 TextCodes.insert( std::make_pair( textcode.
ID, textcode ) );
1482 else if( nodeName == wxT(
"ROUTECODE" ) )
1485 routecode.
Parse( aChildNode, aContext );
1486 RouteCodes.insert( std::make_pair( routecode.
ID, routecode ) );
1488 else if( nodeName == wxT(
"ATTRNAME" ) )
1491 attrname.
Parse( aChildNode, aContext );
1494 else if( nodeName == wxT(
"NETCLASS" ) )
1497 netclass.
Parse( aChildNode, aContext );
1498 NetClasses.insert( std::make_pair( netclass.
ID, netclass ) );
1500 else if( nodeName == wxT(
"SPCCLASSNAME" ) )
1503 spcclassname.
Parse( aChildNode, aContext );
1517 wxASSERT( aNode->GetName() == wxT(
"SWAPRULE" ) );
1522 if( swapRuleStr == wxT(
"NO_SWAP" ) )
1524 else if( swapRuleStr == wxT(
"USE_SWAP_LAYER" ) )
1535 wxASSERT( aNode->GetName() == wxT(
"REUSEBLOCK" ) );
1543 for( ; cNode; cNode = cNode->
GetNext() )
1545 wxString cNodeName = cNode->GetName();
1547 if( cNodeName == wxT(
"MIRROR" ) )
1549 else if( cNodeName == wxT(
"ORIENT" ) )
1565 wxASSERT( aNode->GetName() == wxT(
"REUSEBLOCKREF" ) );
1576 wxASSERT( aNode->GetName() == wxT(
"GROUP" ) );
1583 for( ; cNode; cNode = cNode->
GetNext() )
1585 wxString cNodeName = cNode->GetName();
1587 if( cNodeName == wxT(
"FIX" ) )
1589 else if( cNodeName == wxT(
"TRANSFER" ) )
1591 else if( cNodeName == wxT(
"GROUPREF" ) )
1593 else if( cNodeName == wxT(
"REUSEBLOCKREF" ) )
1603 wxASSERT( aNode->GetName() == wxT(
"FIGURE" ) );
1610 bool shapeIsInitialised =
false;
1611 wxString
location = wxString::Format(
"Figure %s",
ID );
1616 for( ; cNode; cNode = cNode->
GetNext() )
1618 wxString cNodeName = cNode->GetName();
1620 if( !shapeIsInitialised &&
Shape.IsShape( cNode ) )
1622 Shape.Parse( cNode, aContext );
1623 shapeIsInitialised =
true;
1625 else if( cNodeName == wxT(
"SWAPRULE" ) )
1629 else if( cNodeName == wxT(
"FIX" ) )
1633 else if( cNodeName == wxT(
"GROUPREF" ) )
1638 else if( cNodeName == wxT(
"REUSEBLOCKREF" ) )
1642 else if( cNodeName == wxT(
"ATTR" ) )
1645 attr.
Parse( cNode, aContext );
1658 Parse( aNode, aContext,
true );
1665 wxASSERT( aNode->GetName() == wxT(
"TEXT" ) );
1681 for( ; cNode; cNode = cNode->
GetNext() )
1683 wxString cNodeName = cNode->GetName();
1685 if( cNodeName == wxT(
"PT" ) )
1687 else if( cNodeName == wxT(
"ORIENT" ) )
1689 else if( cNodeName == wxT(
"MIRROR" ) )
1691 else if( cNodeName == wxT(
"FIX" ) )
1693 else if( cNodeName == wxT(
"SWAPRULE" ) )
1695 else if( cNodeName == wxT(
"ALIGN" ) )
1697 else if( cNodeName == wxT(
"JUSTIFICATION" ) )
1699 else if( cNodeName == wxT(
"GROUPREF" ) )
1701 else if( cNodeName == wxT(
"REUSEBLOCKREF" ) )
1717 wxASSERT( aNode->GetName() == wxT(
"SYMDEF" ) );
1727 wxString cNodeName = aChildNode->GetName();
1729 if( cNodeName == wxT(
"PT" ) )
1731 Origin.Parse( aChildNode, aContext );
1733 else if( cNodeName == wxT(
"STUB" ) )
1737 else if( cNodeName == wxT(
"VERSION" ) )
1741 else if( cNodeName == wxT(
"FIGURE" ) )
1744 figure.
Parse( aChildNode, aContext );
1745 Figures.insert( std::make_pair( figure.
ID, figure ) );
1747 else if( cNodeName == wxT(
"TEXT" ) )
1750 txt.
Parse( aChildNode, aContext );
1751 Texts.insert( std::make_pair( txt.
ID, txt ) );
1753 else if( cNodeName == wxT(
"TEXTLOC" ) )
1756 textloc.
Parse( aChildNode, aContext );
1759 else if( cNodeName == wxT(
"ATTR" ) )
1762 attrVal.
Parse( aChildNode, aContext );
1776 wxASSERT( aNode->GetName() == wxT(
"GATEDEFINITION" ) );
1789 wxASSERT( aNode->GetName() == wxT(
"PINTYPE" ) );
1793 std::map<wxString, CADSTAR_PIN_TYPE> pinTypeMap = {
1804 if( pinTypeMap.find( pinTypeStr ) == pinTypeMap.end() )
1807 return pinTypeMap[pinTypeStr];
1813 wxASSERT( aNode->GetName() == wxT(
"PARTDEFINITIONPIN" ) );
1819 for( ; cNode; cNode = cNode->
GetNext() )
1821 wxString cNodeName = cNode->GetName();
1823 if( cNodeName == wxT(
"PINNAME" ) )
1827 else if( cNodeName == wxT(
"PINLABEL" ) )
1831 else if( cNodeName == wxT(
"PINSIGNAL" ) )
1835 else if( cNodeName == wxT(
"PINTERM" ) )
1840 else if( cNodeName == wxT(
"PINTYPE" ) )
1844 else if( cNodeName == wxT(
"PINLOAD" ) )
1848 else if( cNodeName == wxT(
"PINPOSITION" ) )
1852 else if( cNodeName == wxT(
"PINIDENTIFIER" ) )
1866 wxASSERT( aNode->GetName() == wxT(
"PARTPIN" ) );
1872 for( ; cNode; cNode = cNode->
GetNext() )
1874 wxString cNodeName = cNode->GetName();
1876 if( cNodeName == wxT(
"PINNAME" ) )
1878 else if( cNodeName == wxT(
"PINTYPE" ) )
1880 else if( cNodeName == wxT(
"PINIDENTIFIER" ) )
1891 wxASSERT( aNode->GetName() == wxT(
"PINEQUIVALENCE" ) );
1893 wxXmlAttribute* xmlAttribute = aNode->GetAttributes();
1895 for( ; xmlAttribute; xmlAttribute = xmlAttribute->GetNext() )
1902 if( !xmlAttribute->GetValue().ToLong( &pinId ) )
1915 wxASSERT( aNode->GetName() == wxT(
"SWAPGATE" ) );
1917 wxXmlAttribute* xmlAttribute = aNode->GetAttributes();
1919 for( ; xmlAttribute; xmlAttribute = xmlAttribute->GetNext() )
1926 if( !xmlAttribute->GetValue().ToLong( &pinId ) )
1939 wxASSERT( aNode->GetName() == wxT(
"SWAPGROUP" ) );
1945 for( ; cNode; cNode = cNode->
GetNext() )
1947 wxString cNodeName = cNode->GetName();
1949 if( cNodeName == wxT(
"EXTERNAL" ) )
1953 else if( cNodeName == wxT(
"SWAPGATE" ) )
1956 swapGate.
Parse( cNode, aContext );
1969 wxASSERT( aNode->GetName() == wxT(
"PARTDEFINITION" ) );
1975 for( ; cNode; cNode = cNode->
GetNext() )
1977 wxString cNodeName = cNode->GetName();
1979 if( cNodeName == wxT(
"HIDEPINNAMES" ) )
1983 else if( cNodeName == wxT(
"MAXPIN" ) )
1987 else if( cNodeName == wxT(
"GATEDEFINITION" ) )
1990 gate.
Parse( cNode, aContext );
1993 else if( cNodeName == wxT(
"PARTDEFINITIONPIN" ) )
1996 pin.Parse( cNode, aContext );
1997 Pins.insert( std::make_pair(
pin.ID,
pin ) );
1999 else if( cNodeName == wxT(
"ATTR" ) )
2002 attr.
Parse( cNode, aContext );
2005 else if( cNodeName == wxT(
"PINEQUIVALENCE" ) )
2008 pinEq.
Parse( cNode, aContext );
2011 else if( cNodeName == wxT(
"SWAPGROUP" ) )
2014 swapGroup.
Parse( cNode, aContext );
2027 wxASSERT( aNode->GetName() == wxT(
"PART" ) );
2034 for( ; cNode; cNode = cNode->
GetNext() )
2036 wxString cNodeName = cNode->GetName();
2038 if( cNodeName == wxT(
"VERSION" ) )
2042 else if( cNodeName == wxT(
"HIDEPINNAMES" ) )
2046 else if( cNodeName == wxT(
"PARTDEFINITION" ) )
2050 else if( cNodeName == wxT(
"PARTPIN" ) )
2053 pin.Parse( cNode, aContext );
2056 else if( cNodeName == wxT(
"ATTR" ) )
2059 attr.
Parse( cNode, aContext );
2072 wxASSERT( aNode->GetName() == wxT(
"PARTS" ) );
2076 for( ; cNode; cNode = cNode->
GetNext() )
2078 wxString cNodeName = cNode->GetName();
2080 if( cNodeName == wxT(
"PART" ) )
2083 part.
Parse( cNode, aContext );
2099 wxASSERT( aNode->GetName() == wxT(
"JPT" ) );
2109 wxString cNodeName = aChildNode->GetName();
2111 if( cNodeName == wxT(
"PT" ) )
2112 Location.Parse( aChildNode, aContext );
2113 else if( cNodeName == wxT(
"FIX" ) )
2115 else if( cNodeName == wxT(
"GROUPREF" ) )
2117 else if( cNodeName == wxT(
"REUSEBLOCKREF" ) )
2131 for( ; cNode; cNode = cNode->
GetNext() )
2144 wxASSERT( aNode->GetName() == wxT(
"CONN" ) );
2155 wxString cNodeName = aChildNode->GetName();
2157 if( cNodeName == wxT(
"FIX" ) )
2161 else if( cNodeName == wxT(
"HIDDEN" ) )
2165 else if( cNodeName == wxT(
"GROUPREF" ) )
2169 else if( cNodeName == wxT(
"REUSEBLOCKREF" ) )
2173 else if( cNodeName == wxT(
"ATTR" ) )
2176 attrVal.
Parse( aChildNode, aContext );
2190 wxASSERT( aNode->GetName() == wxT(
"NET" ) );
2198 wxString cNodeName = aChildNode->GetName();
2200 if( cNodeName == wxT(
"NETCODE" ) )
2204 else if( cNodeName == wxT(
"SIGNAME" ) )
2208 else if( cNodeName == wxT(
"SIGNUM" ) )
2212 else if( cNodeName == wxT(
"HIGHLIT" ) )
2216 else if( cNodeName == wxT(
"JPT" ) )
2219 jpt.
Parse( aChildNode, aContext );
2220 Junctions.insert( std::make_pair( jpt.
ID, jpt ) );
2222 else if( cNodeName == wxT(
"NETCLASSREF" ) )
2226 else if( cNodeName == wxT(
"SPACINGCLASS" ) )
2230 else if( cNodeName == wxT(
"ATTR" ) )
2233 attrVal.
Parse( aChildNode, aContext );
2247 wxASSERT( aNode->GetName() == wxT(
"DOCSYMBOL" ) );
2254 bool originParsed =
false;
2256 for( ; cNode; cNode = cNode->
GetNext() )
2258 wxString cNodeName = cNode->GetName();
2260 if( !originParsed && cNodeName == wxT(
"PT" ) )
2262 Origin.Parse( cNode, aContext );
2263 originParsed =
true;
2265 else if( cNodeName == wxT(
"GROUPREF" ) )
2269 else if( cNodeName == wxT(
"REUSEBLOCKREF" ) )
2273 else if( cNodeName == wxT(
"FIX" ) )
2277 else if( cNodeName == wxT(
"MIRROR" ) )
2281 else if( cNodeName == wxT(
"READABILITY" ) )
2285 else if( cNodeName == wxT(
"ORIENT" ) )
2289 else if( cNodeName == wxT(
"ATTR" ) )
2292 attr.
Parse( cNode, aContext );
2295 else if( cNodeName == wxT(
"SCALE" ) )
2313 wxASSERT( aNode->GetName() == wxT(
"DFLTSETTINGS" ) );
2319 for( ; cNode; cNode = cNode->
GetNext() )
2321 wxString cNodeName = cNode->GetName();
2323 if( cNodeName == wxT(
"INVISIBLE" ) )
2337 wxASSERT( aNode->GetName() == wxT(
"ATTRCOL" ) );
2344 for( ; cNode; cNode = cNode->
GetNext() )
2346 wxString cNodeName = cNode->GetName();
2348 if( cNodeName == wxT(
"INVISIBLE" ) )
2352 else if( cNodeName == wxT(
"NOTPICKABLE" ) )
2366 wxASSERT( aNode->GetName() == wxT(
"ATTRCOLORS" ) );
2370 for( ; cNode; cNode = cNode->
GetNext() )
2372 wxString cNodeName = cNode->GetName();
2374 if( cNodeName == wxT(
"DFLTSETTINGS" ) )
2378 else if( cNodeName == wxT(
"ATTRCOL" ) )
2381 attrcol.
Parse( cNode, aContext );
2384 else if( cNodeName == wxT(
"INVISIBLE" ) )
2398 wxASSERT( aNode->GetName() == wxT(
"PARTNAMECOL" ) );
2404 for( ; cNode; cNode = cNode->
GetNext() )
2406 wxString cNodeName = cNode->GetName();
2408 if( cNodeName == wxT(
"INVISIBLE" ) )
2412 else if( cNodeName == wxT(
"NOTPICKABLE" ) )
2426 static const wxString c_numAttributes = wxT(
"numAttributes" );
2429 long numAttributes = 0;
2431 if( aNode->GetAttribute( c_numAttributes, &
result ) )
2433 numAttributes = wxAtol(
result );
2434 aNode->DeleteAttribute( c_numAttributes );
2438#if wxUSE_UNICODE_WCHAR
2439 std::wstring numAttrStr = std::to_wstring( numAttributes );
2441 std::string numAttrStr = std::to_string( numAttributes );
2444 aNode->AddAttribute( c_numAttributes, numAttrStr );
2446 wxString paramName = wxT(
"attr" );
2447 paramName << numAttrStr;
2449 aNode->AddAttribute( paramName, aValue );
2454 const wxString& aFileTypeIdentifier,
2457 KEYWORD emptyKeywords[1] = {};
2458 XNODE* rootNode =
nullptr;
2459 XNODE* cNode =
nullptr;
2460 XNODE* iNode =
nullptr;
2462 bool cadstarFileCheckDone =
false;
2464 wxCSConv win1252( wxT(
"windows-1252" ) );
2465 wxMBConv* conv = &win1252;
2469 FILE* fp = wxFopen( aFileName, wxT(
"rt" ) );
2472 THROW_IO_ERROR( wxString::Format(
_(
"Cannot open file '%s'" ), aFileName ) );
2474 fseek( fp, 0L, SEEK_END );
2475 long fileSize = ftell( fp );
2478 DSNLEXER lexer( emptyKeywords, 0,
nullptr, fp, aFileName );
2480 auto currentProgress = [&]() ->
double
2482 return static_cast<double>( ftell( fp ) ) / fileSize;
2485 double previousReportedProgress = -1.0;
2489 if( aProgressReporter && ( currentProgress() - previousReportedProgress ) > 0.01 )
2499 previousReportedProgress = currentProgress();
2513 THROW_IO_ERROR(
_(
"The selected file is not valid or might be corrupt!" ) );
2519 str = wxString( lexer.
CurText(), *conv );
2520 cNode =
new XNODE( wxXML_ELEMENT_NODE, str );
2529 iNode->AddChild( cNode );
2531 else if( !cadstarFileCheckDone )
2533 if( cNode->GetName() != aFileTypeIdentifier )
2536 THROW_IO_ERROR(
_(
"The selected file is not valid or might be corrupt!" ) );
2539 cadstarFileCheckDone =
true;
2546 str = wxString( lexer.
CurText(), *conv );
2554 THROW_IO_ERROR(
_(
"The selected file is not valid or might be corrupt!" ) );
2559 if( iNode !=
nullptr )
2562 THROW_IO_ERROR(
_(
"The selected file is not valid or might be corrupt!" ) );
2573 THROW_IO_ERROR(
_(
"The selected file is not valid or might be corrupt!" ) );
2582 return aAttribute->GetName() != wxT(
"numAttributes" );
2589#if wxUSE_UNICODE_WCHAR
2590 std::wstring idStr = std::to_wstring( aID );
2592 std::string idStr = std::to_string( aID );
2595 wxString attrName = wxS(
"attr" );
2600 if( !aNode->GetAttribute( attrName, &retVal ) )
2605 return wxEmptyString;
2639 if( aNode && aNode->
GetNext() )
2647 if( aNode->
GetChildren()->GetName() == wxT(
"E" ) )
2657 std::vector<POINT> retVal;
2661 for( ; cNode; cNode = cNode->
GetNext() )
2663 if( cNode->GetName() == wxT(
"PT" ) )
2667 pt.
Parse( cNode, aContext );
2668 retVal.push_back( pt );
2670 else if( aTestAllChildNodes )
2677 && retVal.size() !=
static_cast<size_t>( aExpectedNumPoints ) )
2680 _(
"Unexpected number of points in '%s'. Found %d but expected %d." ),
2681 aNode->GetName(), retVal.size(), aExpectedNumPoints ) );
2691 std::vector<VERTEX> retVal;
2695 for( ; cNode; cNode = cNode->
GetNext() )
2701 vertex.
Parse( cNode, aContext );
2702 retVal.push_back( vertex );
2704 else if( aTestAllChildNodes )
2717 std::vector<CUTOUT> retVal;
2721 for( ; cNode; cNode = cNode->
GetNext() )
2723 if( cNode->GetName() == wxT(
"CUTOUT" ) )
2727 cutout.
Parse( cNode, aContext );
2728 retVal.push_back( cutout );
2730 else if( aTestAllChildNodes )
2745 for( ; childNodes; childNodes = childNodes->
GetNext() )
2753 XNODE* aRootNode, std::vector<wxString> aSubNodeChildrenToCount )
2758 for( ; level1Node; level1Node = level1Node->
GetNext() )
2760 for( wxString childNodeName : aSubNodeChildrenToCount )
2762 if( level1Node->GetName() == childNodeName )
2775 wxString escapedText = aCadstarString;
2777 escapedText.Replace( wxT(
"'" ), wxT(
"~" ) );
2785 if( !aKiCadTextItem->
GetText().IsEmpty() )
2792 int numExtraLines =
text.Replace(
"\n",
"\n" );
2793 numExtraLines -=
text.at(
text.size() - 1 ) ==
'\n';
2794 positionOffset.
x *= numExtraLines;
2795 positionOffset.
y *= numExtraLines;
2797 aKiCadTextItem->
Offset( positionOffset );
2803 const wxString& aAlternateName )
2805 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.
@ TRISTATE_INPUT
Tristate input pin.
@ TRISTATE_BIDIR
Tristate bi-directional driver pin.
@ OUTPUT_NOT_NORM_OR
Output pin not normally OR tieable.
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 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 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,...
const EDA_ANGLE & GetTextAngle() const
virtual const wxString & GetText() const
Return the string associated with the text object.
void Offset(const VECTOR2I &aOffset)
int GetInterline(const RENDER_SETTINGS *aSettings) const
Return the distance between two lines of text.
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.
Hold an XML or S-expression element.
XNODE * GetParent() const
XNODE * GetChildren() const
#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 ...
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 o...
JUSTIFICATION Justification
Note: Justification 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