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" ) );
102 wxASSERT( aNode->GetName() == wxT(
"HEADER" ) );
106 for( ; cNode; cNode = cNode->
GetNext() )
108 wxString
nodeName = cNode->GetName();
112 Format.Parse( cNode, aContext );
114 else if(
nodeName == wxT(
"JOBFILE" ) )
118 else if(
nodeName == wxT(
"JOBTITLE" ) )
122 else if(
nodeName == wxT(
"GENERATOR" ) )
126 else if(
nodeName == wxT(
"RESOLUTION" ) )
130 if( ( subNode->GetName() == wxT(
"METRIC" ) )
145 else if(
nodeName == wxT(
"TIMESTAMP" ) )
159 wxASSERT( aNode->GetName() == wxT(
"VMASTER" ) || aNode->GetName() == wxT(
"VARIANT" ) );
163 if( aNode->GetName() == wxT(
"VMASTER" ) )
179 wxASSERT( aNode->GetName() == wxT(
"VHIERARCHY" ) );
183 for( ; cNode; cNode = cNode->
GetNext() )
185 if( cNode->GetName() == wxT(
"VMASTER" ) || cNode->GetName() == wxT(
"VARIANT" ) )
188 variant.
Parse( cNode, aContext );
189 Variants.insert( std::make_pair( variant.
ID, variant ) );
201 wxASSERT( aNode->GetName() == wxT(
"LINECODE" ) );
211 if( !cNode || cNode->GetName() != wxT(
"STYLE" ) )
216 if( styleStr == wxT(
"SOLID" ) )
220 else if( styleStr == wxT(
"DASH" ) )
224 else if( styleStr == wxT(
"DASHDOT" ) )
228 else if( styleStr == wxT(
"DASHDOTDOT" ) )
232 else if( styleStr == wxT(
"DOT" ) )
239 wxString::Format(
"LINECODE -> %s",
Name ) );
246 wxASSERT( aNode->GetName() == wxT(
"HATCH" ) );
253 if( !cNode || cNode->GetName() != wxT(
"ORIENT" ) )
262 wxASSERT( aNode->GetName() == wxT(
"HATCHCODE" ) );
268 wxString
location = wxString::Format(
"HATCHCODE -> %s",
Name );
270 for( ; cNode; cNode = cNode->
GetNext() )
272 if( cNode->GetName() != wxT(
"HATCH" ) )
279 hatch.
Parse( cNode, aContext );
287 wxASSERT( aNode->GetName() == wxT(
"FONT" ) );
295 for( ; cNode; cNode = cNode->
GetNext() )
297 wxString cNodeName = cNode->GetName();
299 if( cNodeName == wxT(
"ITALIC" ) )
301 else if( cNodeName == wxT(
"KERNING" ) )
311 wxASSERT( aNode->GetName() == wxT(
"TEXTCODE" ) );
324 if( cNode->GetName() == wxT(
"FONT" ) )
325 Font.Parse( cNode, aContext );
334 wxASSERT( aNode->GetName() == wxT(
"ROUTEREASSIGN" ) );
341 for( ; cNode; cNode = cNode->
GetNext() )
343 wxString cNodeName = cNode->GetName();
345 if( cNodeName == wxT(
"NECKWIDTH" ) )
347 else if( cNodeName == wxT(
"SROUTEWIDTH" ) )
349 else if( cNodeName == wxT(
"MINWIDTH" ) )
351 else if( cNodeName == wxT(
"MAXWIDTH" ) )
361 wxASSERT( aNode->GetName() == wxT(
"ROUTECODE" ) );
369 for( ; cNode; cNode = cNode->
GetNext() )
371 wxString cNodeName = cNode->GetName();
373 if( cNodeName == wxT(
"NECKWIDTH" ) )
377 else if( cNodeName == wxT(
"SROUTEWIDTH" ) )
381 else if( cNodeName == wxT(
"MINWIDTH" ) )
385 else if( cNodeName == wxT(
"MAXWIDTH" ) )
389 else if( cNodeName == wxT(
"ROUTEREASSIGN" ) )
392 routereassign.
Parse( cNode, aContext );
411 wxASSERT( aNode->GetName() == wxT(
"E" ) );
417 wxString::Format(
"%s->%s", aNode->
GetParent()->GetName(),
425 wxASSERT( aNode->GetName() == wxT(
"PT" ) );
434 wxASSERT( aNode->GetName() == wxT(
"PT" ) );
443 wxString aNodeName = aNode->GetName();
445 if( aNodeName == wxT(
"PT" ) || aNodeName == wxT(
"ACWARC" ) || aNodeName == wxT(
"CWARC" )
446 || aNodeName == wxT(
"CWSEMI" ) || aNodeName == wxT(
"ACWSEMI" ) )
461 wxString aNodeName = aNode->GetName();
463 if( aNodeName == wxT(
"PT" ) )
468 End.Parse( aNode, aContext );
470 else if( aNodeName == wxT(
"ACWARC" ) || aNodeName == wxT(
"CWARC" ) )
472 if( aNodeName == wxT(
"ACWARC" ) )
482 else if( aNodeName == wxT(
"ACWSEMI" ) || aNodeName == wxT(
"CWSEMI" ) )
484 if( aNodeName == wxT(
"ACWSEMI" ) )
498 wxASSERT_MSG(
true, wxT(
"Unknown VERTEX type" ) );
504 const std::function<
VECTOR2I(
const VECTOR2I& )> aCadstarToKicadPointCallback,
505 int aAccuracy )
const
509 aChainToAppendTo->
Append( aCadstarToKicadPointCallback(
End ) );
513 wxCHECK_MSG( aChainToAppendTo->
PointCount() > 0, ,
514 "Can't append an arc to vertex to an empty chain" );
517 aCadstarToKicadPointCallback ),
523 const std::function<
VECTOR2I(
const VECTOR2I& )> aCadstarToKicadPointCallback )
const
526 "Can't build an arc for a straight segment!" );
529 VECTOR2I endPoint = aCadstarToKicadPointCallback(
End );
533 centerPoint = ( startPoint / 2 ) + ( endPoint / 2 );
535 centerPoint = aCadstarToKicadPointCallback(
Center );
541 VECTOR2I transform = aCadstarToKicadPointCallback( { 500, 500 } )
542 - aCadstarToKicadPointCallback( { 0, 0 } );
544 if( ( transform.
x > 0 && transform.
y < 0 ) || ( transform.
x < 0 && transform.
y > 0 ) )
545 clockwise = !clockwise;
555 wxASSERT( aNode->GetName() == wxT(
"CUTOUT" ) );
563 wxString aNodeName = aNode->GetName();
565 if( aNodeName == wxT(
"OPENSHAPE" ) || aNodeName == wxT(
"OUTLINE" )
566 || aNodeName == wxT(
"SOLID" ) || aNodeName == wxT(
"HATCHED" ) )
581 wxString aNodeName = aNode->GetName();
583 if( aNodeName == wxT(
"OPENSHAPE" ) )
590 else if( aNodeName == wxT(
"OUTLINE" ) )
597 else if( aNodeName == wxT(
"SOLID" ) )
604 else if( aNodeName == wxT(
"HATCHED" ) )
613 wxASSERT_MSG(
true, wxT(
"Unknown SHAPE type" ) );
618 const std::function<
VECTOR2I(
const VECTOR2I& )> aCadstarToKicadPointCallback,
619 int aMaxError )
const
626 for(
const auto& vertex :
Vertices )
627 vertex.AppendToChain( &outline, aCadstarToKicadPointCallback, aMaxError );
642 const std::function<
VECTOR2I(
const VECTOR2I& )> aCadstarToKicadPointCallback,
643 int aMaxError )
const
652 for(
const auto& cutout :
Cutouts )
656 if( cutout.Vertices.size() == 0 )
659 for(
const auto& cutoutVertex : cutout.Vertices )
660 cutoutVertex.AppendToChain( &hole, aCadstarToKicadPointCallback, aMaxError );
665 cutout.Vertices.at( 0 ).AppendToChain( &hole, aCadstarToKicadPointCallback, aMaxError );
676 wxASSERT( aNode->GetName() == wxT(
"UNITS" ) );
680 if( unit == wxT(
"CENTIMETER" ) )
682 else if( unit == wxT(
"INCH" ) )
684 else if( unit == wxT(
"METER" ) )
686 else if( unit == wxT(
"MICROMETRE" ) )
688 else if( unit == wxT(
"MM" ) )
690 else if( unit == wxT(
"THOU" ) )
692 else if( unit == wxT(
"DESIGN" ) )
703 wxASSERT( aNode->GetName() == wxT(
"ANGUNITS" ) );
707 if( angUnitStr == wxT(
"DEGREES" ) )
709 else if( angUnitStr == wxT(
"RADIANS" ) )
723 wxString aNodeName = aNode->GetName();
725 if( aNodeName == wxT(
"FRACTIONALGRID" ) || aNodeName == wxT(
"STEPGRID" ) )
734 wxASSERT(
IsGrid( aNode ) );
736 wxString aNodeName = aNode->GetName();
738 if( aNodeName == wxT(
"FRACTIONALGRID" ) )
740 else if( aNodeName == wxT(
"STEPGRID" ) )
743 wxASSERT_MSG(
true, wxT(
"Unknown Grid Type" ) );
753 wxASSERT( aNode->GetName() == wxT(
"GRIDS" ) );
757 for( ; cNode; cNode = cNode->
GetNext() )
759 wxString cNodeName = cNode->GetName();
761 if( cNodeName == wxT(
"WORKINGGRID" ) )
767 wxString found = workingGridNode ? workingGridNode->GetName() : wxString(
"(empty)" );
775 else if( cNodeName == wxT(
"SCREENGRID" ) )
781 wxString found = screenGridNode ? screenGridNode->GetName() : wxString(
"(empty)" );
792 userGrid.
Parse( cNode, aContext );
805 wxString cNodeName = aChildNode->GetName();
807 if( cNodeName == wxT(
"UNITS" ) )
811 else if( cNodeName == wxT(
"UNITSPRECISION" ) )
815 else if( cNodeName == wxT(
"INTERLINEGAP" ) )
819 else if( cNodeName == wxT(
"BARLINEGAP" ) )
823 else if( cNodeName == wxT(
"ALLOWBARTEXT" ) )
827 else if( cNodeName == wxT(
"ANGULARPRECISION" ) )
831 else if( cNodeName == wxT(
"DESIGNORIGIN" ) )
835 else if( cNodeName == wxT(
"DESIGNAREA" ) )
838 DesignArea = std::make_pair( pts[0], pts[1] );
840 else if( cNodeName == wxT(
"DESIGNREF" ) )
844 else if( cNodeName == wxT(
"DESIGNLIMIT" ) )
848 else if( cNodeName == wxT(
"PINNOOFFSET" ) )
852 else if( cNodeName == wxT(
"PINNOANGLE" ) )
867 wxASSERT( aNode->GetName() == wxT(
"SETTINGS" ) );
871 for( ; cNode; cNode = cNode->
GetNext() )
873 wxString cNodeName = cNode->GetName();
886 static const std::map<TEXT_FIELD_NAME, wxString> txtTokens =
910 wxString remainingStr = aTextString;
913 while( remainingStr.size() > 0 )
916 size_t startpos = remainingStr.Find( wxT(
"<@" ) );
918 if(
static_cast<int>( startpos ) == wxNOT_FOUND )
921 returnStr += remainingStr;
926 returnStr += remainingStr.SubString( 0, startpos - 1 );
928 if( ( startpos + 2 ) >= remainingStr.size() )
931 remainingStr = remainingStr.Mid( startpos + 2 );
936 for( std::pair<TEXT_FIELD_NAME, wxString> txtF : txtTokens )
938 if( remainingStr.StartsWith( txtF.second ) )
940 foundField = txtF.first;
948 returnStr += wxT(
"<@" );
953 size_t endpos = remainingStr.Find( wxT(
"@>" ) );
955 if(
static_cast<int>( endpos ) == wxNOT_FOUND )
959 returnStr += wxT(
"<@" ) + remainingStr;
963 size_t valueStart = txtTokens.at( foundField ).size();
964 wxString fieldValue = remainingStr.SubString( valueStart, endpos - 1 );
970 wxASSERT_MSG( fieldValue.at( 0 ) ==
'"',
"Expected '\"' as the first character" );
972 size_t splitPos = fieldValue.find_first_of(
'"', 1 );
973 address = fieldValue.SubString( 1, splitPos - 1 );
978 wxASSERT_MSG( remainingStr.EndsWith( wxT(
"@>" ) ),
979 "Expected '@>' at the end of a hyperlink" );
981 fieldValue = remainingStr.SubString( valueStart + splitPos + 1,
982 remainingStr.Length() - 3 );
984 remainingStr = wxEmptyString;
988 fieldValue = fieldValue.Mid( splitPos + 1 );
1029 returnStr += fieldValue;
1034 wxFileName fn( address );
1035 wxString fieldFmt = wxT(
"FROM_FILE_%s_%s" );
1036 wxString fieldName = wxString::Format( fieldFmt, fn.GetName(), fn.GetExt() );
1045 fieldName = wxString::Format( fieldFmt, fn.GetName(), fn.GetExt() )
1046 + wxString::Format( wxT(
"_%d" ), version++ );
1050 returnStr += wxT(
"${" ) + fieldName + wxT(
"}" );
1062 wxFAIL_MSG(
"We should have already covered this scenario above" );
1067 if( ( endpos + 2 ) >= remainingStr.size() )
1070 remainingStr = remainingStr.Mid( endpos + 2 );
1079 wxASSERT( aNode->GetName() == wxT(
"ALIGN" ) );
1083 if( alignmentStr == wxT(
"BOTTOMCENTER" ) )
1085 else if( alignmentStr == wxT(
"BOTTOMLEFT" ) )
1087 else if( alignmentStr == wxT(
"BOTTOMRIGHT" ) )
1089 else if( alignmentStr == wxT(
"CENTERCENTER" ) )
1091 else if( alignmentStr == wxT(
"CENTERLEFT" ) )
1093 else if( alignmentStr == wxT(
"CENTERRIGHT" ) )
1095 else if( alignmentStr == wxT(
"TOPCENTER" ) )
1097 else if( alignmentStr == wxT(
"TOPLEFT" ) )
1099 else if( alignmentStr == wxT(
"TOPRIGHT" ) )
1111 wxASSERT( aNode->GetName() == wxT(
"JUSTIFICATION" ) );
1115 if( justificationStr == wxT(
"LEFT" ) )
1117 else if( justificationStr == wxT(
"RIGHT" ) )
1119 else if( justificationStr == wxT(
"CENTER" ) )
1130 wxASSERT( aNode->GetName() == wxT(
"READABILITY" ) );
1134 if( readabilityStr == wxT(
"BOTTOM_TO_TOP" ) )
1136 else if( readabilityStr == wxT(
"TOP_TO_BOTTOM" ) )
1156 wxString cNodeName = aChildNode->GetName();
1158 if( cNodeName == wxT(
"PT" ) )
1159 Position.Parse( aChildNode, aContext );
1160 else if( cNodeName == wxT(
"ORIENT" ) )
1162 else if( cNodeName == wxT(
"MIRROR" ) )
1164 else if( cNodeName == wxT(
"FIX" ) )
1166 else if( cNodeName == wxT(
"ALIGN" ) )
1168 else if( cNodeName == wxT(
"JUSTIFICATION" ) )
1179 wxASSERT( aNode->GetName() == wxT(
"ATTRLOC" ) );
1186 for( ; cNode; cNode = cNode->
GetNext() )
1201 wxASSERT( aNode->GetName() == wxT(
"COLUMNORDER" ) );
1212 wxASSERT( aNode->GetName() == wxT(
"COLUMNWIDTH" ) );
1223 wxASSERT( aNode->GetName() == wxT(
"ATTRNAME" ) );
1229 wxString
location = wxString::Format(
"ATTRNAME -> %s",
Name );
1231 for( ; cNode; cNode = cNode->
GetNext() )
1233 wxString cNodeName = cNode->GetName();
1235 if( cNodeName == wxT(
"ATTROWNER" ) )
1239 if( attOwnerVal == wxT(
"ALL_ITEMS" ) )
1241 else if( attOwnerVal == wxT(
"AREA" ) )
1243 else if( attOwnerVal == wxT(
"BOARD" ) )
1245 else if( attOwnerVal == wxT(
"COMPONENT" ) )
1247 else if( attOwnerVal == wxT(
"CONNECTION" ) )
1249 else if( attOwnerVal == wxT(
"COPPER" ) )
1251 else if( attOwnerVal == wxT(
"DOCSYMBOL" ) )
1253 else if( attOwnerVal == wxT(
"FIGURE" ) )
1255 else if( attOwnerVal == wxT(
"NET" ) )
1257 else if( attOwnerVal == wxT(
"NETCLASS" ) )
1259 else if( attOwnerVal == wxT(
"PART" ) )
1261 else if( attOwnerVal == wxT(
"PART_DEFINITION" ) )
1263 else if( attOwnerVal == wxT(
"PIN" ) )
1265 else if( attOwnerVal == wxT(
"SIGNALREF" ) )
1267 else if( attOwnerVal == wxT(
"SYMBOL" ) )
1269 else if( attOwnerVal == wxT(
"SYMDEF" ) )
1271 else if( attOwnerVal == wxT(
"TEMPLATE" ) )
1273 else if( attOwnerVal == wxT(
"TESTPOINT" ) )
1278 else if( cNodeName == wxT(
"ATTRUSAGE" ) )
1282 if( attUsageVal == wxT(
"BOTH" ) )
1284 else if( attUsageVal == wxT(
"COMPONENT" ) )
1286 else if( attUsageVal == wxT(
"PART_DEFINITION" ) )
1288 else if( attUsageVal == wxT(
"PART_LIBRARY" ) )
1290 else if( attUsageVal == wxT(
"SYMBOL" ) )
1295 else if( cNodeName == wxT(
"NOTRANSFER" ) )
1299 else if( cNodeName == wxT(
"COLUMNORDER" ) )
1302 cOrder.
Parse( cNode, aContext );
1305 else if( cNodeName == wxT(
"COLUMNWIDTH" ) )
1308 cWidth.
Parse( cNode, aContext );
1311 else if( cNodeName == wxT(
"COLUMNINVISIBLE" ) )
1325 wxASSERT( aNode->GetName() == wxT(
"ATTR" ) );
1332 for( ; cNode; cNode = cNode->
GetNext() )
1334 if( cNode->GetName() == wxT(
"READONLY" ) )
1338 else if( cNode->GetName() == wxT(
"ATTRLOC" ) )
1353 wxASSERT( aNode->GetName() == wxT(
"TEXTLOC" ) );
1356 bool attributeIDisSet =
false;
1358 if( attributeStr == wxT(
"PART_NAME" ) )
1361 attributeIDisSet =
true;
1363 else if( attributeStr == wxT(
"COMP_NAME" ) )
1366 attributeIDisSet =
true;
1368 else if( attributeStr == wxT(
"COMP_NAME2" ) )
1371 attributeIDisSet =
true;
1373 else if( attributeStr == wxT(
"SYMBOL_NAME" ) )
1376 attributeIDisSet =
true;
1378 else if( attributeStr == wxT(
"LINK_ORIGIN" ) )
1381 attributeIDisSet =
true;
1383 else if( attributeStr == wxT(
"SIGNALNAME_ORIGIN" ) )
1386 attributeIDisSet =
true;
1388 else if( attributeStr == wxT(
"ATTRREF" ) )
1391 attributeIDisSet =
false;
1404 for( ; cNode; cNode = cNode->
GetNext() )
1406 wxString cNodeName = cNode->GetName();
1412 else if( !attributeIDisSet && cNodeName == wxT(
"ATTRREF" ) )
1415 attributeIDisSet =
true;
1417 else if( cNodeName == wxT(
"ORIENT" ) )
1421 else if( cNodeName == wxT(
"MIRROR" ) )
1425 else if( cNodeName == wxT(
"FIX" ) )
1429 else if( cNodeName == wxT(
"ALIGN" ) )
1433 else if( cNodeName == wxT(
"JUSTIFICATION" ) )
1450 wxASSERT( aNode->GetName() == wxT(
"NETCLASS" ) );
1456 wxString
location = wxString::Format(
"NETCLASS -> %s",
Name );
1458 for( ; cNode; cNode = cNode->
GetNext() )
1460 wxString cNodeName = cNode->GetName();
1462 if( cNodeName == wxT(
"ATTR" ) )
1465 attribute_val.
Parse( cNode, aContext );
1478 wxASSERT( aNode->GetName() == wxT(
"SPCCLASSNAME" ) );
1487 wxString
nodeName = aChildNode->GetName();
1489 if(
nodeName == wxT(
"LINECODE" ) )
1492 linecode.
Parse( aChildNode, aContext );
1493 LineCodes.insert( std::make_pair( linecode.
ID, linecode ) );
1495 else if(
nodeName == wxT(
"HATCHCODE" ) )
1498 hatchcode.
Parse( aChildNode, aContext );
1499 HatchCodes.insert( std::make_pair( hatchcode.
ID, hatchcode ) );
1501 else if(
nodeName == wxT(
"TEXTCODE" ) )
1504 textcode.
Parse( aChildNode, aContext );
1505 TextCodes.insert( std::make_pair( textcode.
ID, textcode ) );
1507 else if(
nodeName == wxT(
"ROUTECODE" ) )
1510 routecode.
Parse( aChildNode, aContext );
1511 RouteCodes.insert( std::make_pair( routecode.
ID, routecode ) );
1513 else if(
nodeName == wxT(
"ATTRNAME" ) )
1516 attrname.
Parse( aChildNode, aContext );
1519 else if(
nodeName == wxT(
"NETCLASS" ) )
1522 netclass.
Parse( aChildNode, aContext );
1523 NetClasses.insert( std::make_pair( netclass.
ID, netclass ) );
1525 else if(
nodeName == wxT(
"SPCCLASSNAME" ) )
1528 spcclassname.
Parse( aChildNode, aContext );
1542 wxASSERT( aNode->GetName() == wxT(
"SWAPRULE" ) );
1547 if( swapRuleStr == wxT(
"NO_SWAP" ) )
1549 else if( swapRuleStr == wxT(
"USE_SWAP_LAYER" ) )
1560 wxASSERT( aNode->GetName() == wxT(
"REUSEBLOCK" ) );
1568 for( ; cNode; cNode = cNode->
GetNext() )
1570 wxString cNodeName = cNode->GetName();
1572 if( cNodeName == wxT(
"MIRROR" ) )
1574 else if( cNodeName == wxT(
"ORIENT" ) )
1590 wxASSERT( aNode->GetName() == wxT(
"REUSEBLOCKREF" ) );
1601 wxASSERT( aNode->GetName() == wxT(
"GROUP" ) );
1608 for( ; cNode; cNode = cNode->
GetNext() )
1610 wxString cNodeName = cNode->GetName();
1612 if( cNodeName == wxT(
"FIX" ) )
1614 else if( cNodeName == wxT(
"TRANSFER" ) )
1616 else if( cNodeName == wxT(
"GROUPREF" ) )
1618 else if( cNodeName == wxT(
"REUSEBLOCKREF" ) )
1628 wxASSERT( aNode->GetName() == wxT(
"FIGURE" ) );
1635 bool shapeIsInitialised =
false;
1636 wxString
location = wxString::Format(
"Figure %s",
ID );
1641 for( ; cNode; cNode = cNode->
GetNext() )
1643 wxString cNodeName = cNode->GetName();
1645 if( !shapeIsInitialised &&
Shape.IsShape( cNode ) )
1647 Shape.Parse( cNode, aContext );
1648 shapeIsInitialised =
true;
1650 else if( cNodeName == wxT(
"SWAPRULE" ) )
1654 else if( cNodeName == wxT(
"FIX" ) )
1658 else if( cNodeName == wxT(
"GROUPREF" ) )
1663 else if( cNodeName == wxT(
"REUSEBLOCKREF" ) )
1667 else if( cNodeName == wxT(
"ATTR" ) )
1670 attr.
Parse( cNode, aContext );
1683 Parse( aNode, aContext,
true );
1690 wxASSERT( aNode->GetName() == wxT(
"TEXT" ) );
1706 for( ; cNode; cNode = cNode->
GetNext() )
1708 wxString cNodeName = cNode->GetName();
1710 if( cNodeName == wxT(
"PT" ) )
1712 else if( cNodeName == wxT(
"ORIENT" ) )
1714 else if( cNodeName == wxT(
"MIRROR" ) )
1716 else if( cNodeName == wxT(
"FIX" ) )
1718 else if( cNodeName == wxT(
"SWAPRULE" ) )
1720 else if( cNodeName == wxT(
"ALIGN" ) )
1722 else if( cNodeName == wxT(
"JUSTIFICATION" ) )
1724 else if( cNodeName == wxT(
"GROUPREF" ) )
1726 else if( cNodeName == wxT(
"REUSEBLOCKREF" ) )
1742 wxASSERT( aNode->GetName() == wxT(
"SYMDEF" ) );
1752 wxString cNodeName = aChildNode->GetName();
1754 if( cNodeName == wxT(
"PT" ) )
1756 Origin.Parse( aChildNode, aContext );
1758 else if( cNodeName == wxT(
"STUB" ) )
1762 else if( cNodeName == wxT(
"VERSION" ) )
1766 else if( cNodeName == wxT(
"FIGURE" ) )
1769 figure.
Parse( aChildNode, aContext );
1770 Figures.insert( std::make_pair( figure.
ID, figure ) );
1772 else if( cNodeName == wxT(
"TEXT" ) )
1775 txt.
Parse( aChildNode, aContext );
1776 Texts.insert( std::make_pair( txt.
ID, txt ) );
1778 else if( cNodeName == wxT(
"TEXTLOC" ) )
1781 textloc.
Parse( aChildNode, aContext );
1784 else if( cNodeName == wxT(
"ATTR" ) )
1787 attrVal.
Parse( aChildNode, aContext );
1801 wxASSERT( aNode->GetName() == wxT(
"GATEDEFINITION" ) );
1814 wxASSERT( aNode->GetName() == wxT(
"PINTYPE" ) );
1818 std::map<wxString, CADSTAR_PIN_TYPE> pinTypeMap = {
1829 if( pinTypeMap.find( pinTypeStr ) == pinTypeMap.end() )
1835 return pinTypeMap[pinTypeStr];
1841 wxASSERT( aNode->GetName() == wxT(
"PARTDEFINITIONPIN" ) );
1847 for( ; cNode; cNode = cNode->
GetNext() )
1849 wxString cNodeName = cNode->GetName();
1851 if( cNodeName == wxT(
"PINNAME" ) )
1855 else if( cNodeName == wxT(
"PINLABEL" ) )
1859 else if( cNodeName == wxT(
"PINSIGNAL" ) )
1863 else if( cNodeName == wxT(
"PINTERM" ) )
1868 else if( cNodeName == wxT(
"PINTYPE" ) )
1872 else if( cNodeName == wxT(
"PINLOAD" ) )
1876 else if( cNodeName == wxT(
"PINPOSITION" ) )
1880 else if( cNodeName == wxT(
"PINIDENTIFIER" ) )
1894 wxASSERT( aNode->GetName() == wxT(
"PARTPIN" ) );
1900 for( ; cNode; cNode = cNode->
GetNext() )
1902 wxString cNodeName = cNode->GetName();
1904 if( cNodeName == wxT(
"PINNAME" ) )
1906 else if( cNodeName == wxT(
"PINTYPE" ) )
1908 else if( cNodeName == wxT(
"PINIDENTIFIER" ) )
1919 wxASSERT( aNode->GetName() == wxT(
"PINEQUIVALENCE" ) );
1921 wxXmlAttribute* xmlAttribute = aNode->GetAttributes();
1923 for( ; xmlAttribute; xmlAttribute = xmlAttribute->GetNext() )
1930 if( !xmlAttribute->GetValue().ToLong( &pinId ) )
1943 wxASSERT( aNode->GetName() == wxT(
"SWAPGATE" ) );
1945 wxXmlAttribute* xmlAttribute = aNode->GetAttributes();
1947 for( ; xmlAttribute; xmlAttribute = xmlAttribute->GetNext() )
1954 if( !xmlAttribute->GetValue().ToLong( &pinId ) )
1967 wxASSERT( aNode->GetName() == wxT(
"SWAPGROUP" ) );
1973 for( ; cNode; cNode = cNode->
GetNext() )
1975 wxString cNodeName = cNode->GetName();
1977 if( cNodeName == wxT(
"EXTERNAL" ) )
1981 else if( cNodeName == wxT(
"SWAPGATE" ) )
1984 swapGate.
Parse( cNode, aContext );
1997 wxASSERT( aNode->GetName() == wxT(
"PARTDEFINITION" ) );
2003 for( ; cNode; cNode = cNode->
GetNext() )
2005 wxString cNodeName = cNode->GetName();
2007 if( cNodeName == wxT(
"HIDEPINNAMES" ) )
2011 else if( cNodeName == wxT(
"MAXPIN" ) )
2015 else if( cNodeName == wxT(
"GATEDEFINITION" ) )
2018 gate.
Parse( cNode, aContext );
2021 else if( cNodeName == wxT(
"PARTDEFINITIONPIN" ) )
2024 pin.Parse( cNode, aContext );
2025 Pins.insert( std::make_pair(
pin.ID,
pin ) );
2027 else if( cNodeName == wxT(
"ATTR" ) )
2030 attr.
Parse( cNode, aContext );
2033 else if( cNodeName == wxT(
"PINEQUIVALENCE" ) )
2036 pinEq.
Parse( cNode, aContext );
2039 else if( cNodeName == wxT(
"SWAPGROUP" ) )
2042 swapGroup.
Parse( cNode, aContext );
2055 wxASSERT( aNode->GetName() == wxT(
"PART" ) );
2062 for( ; cNode; cNode = cNode->
GetNext() )
2064 wxString cNodeName = cNode->GetName();
2066 if( cNodeName == wxT(
"VERSION" ) )
2070 else if( cNodeName == wxT(
"HIDEPINNAMES" ) )
2074 else if( cNodeName == wxT(
"PARTDEFINITION" ) )
2078 else if( cNodeName == wxT(
"PARTPIN" ) )
2081 pin.Parse( cNode, aContext );
2084 else if( cNodeName == wxT(
"ATTR" ) )
2087 attr.
Parse( cNode, aContext );
2100 wxASSERT( aNode->GetName() == wxT(
"PARTS" ) );
2104 for( ; cNode; cNode = cNode->
GetNext() )
2106 wxString cNodeName = cNode->GetName();
2108 if( cNodeName == wxT(
"PART" ) )
2111 part.
Parse( cNode, aContext );
2127 wxASSERT( aNode->GetName() == wxT(
"JPT" ) );
2137 wxString cNodeName = aChildNode->GetName();
2139 if( cNodeName == wxT(
"PT" ) )
2140 Location.Parse( aChildNode, aContext );
2141 else if( cNodeName == wxT(
"FIX" ) )
2143 else if( cNodeName == wxT(
"GROUPREF" ) )
2145 else if( cNodeName == wxT(
"REUSEBLOCKREF" ) )
2159 for( ; cNode; cNode = cNode->
GetNext() )
2172 wxASSERT( aNode->GetName() == wxT(
"CONN" ) );
2183 wxString cNodeName = aChildNode->GetName();
2185 if( cNodeName == wxT(
"FIX" ) )
2189 else if( cNodeName == wxT(
"HIDDEN" ) )
2193 else if( cNodeName == wxT(
"GROUPREF" ) )
2197 else if( cNodeName == wxT(
"REUSEBLOCKREF" ) )
2201 else if( cNodeName == wxT(
"ATTR" ) )
2204 attrVal.
Parse( aChildNode, aContext );
2218 wxASSERT( aNode->GetName() == wxT(
"NET" ) );
2226 wxString cNodeName = aChildNode->GetName();
2228 if( cNodeName == wxT(
"NETCODE" ) )
2232 else if( cNodeName == wxT(
"SIGNAME" ) )
2236 else if( cNodeName == wxT(
"SIGNUM" ) )
2240 else if( cNodeName == wxT(
"HIGHLIT" ) )
2244 else if( cNodeName == wxT(
"JPT" ) )
2247 jpt.
Parse( aChildNode, aContext );
2248 Junctions.insert( std::make_pair( jpt.
ID, jpt ) );
2250 else if( cNodeName == wxT(
"NETCLASSREF" ) )
2254 else if( cNodeName == wxT(
"SPACINGCLASS" ) )
2258 else if( cNodeName == wxT(
"ATTR" ) )
2261 attrVal.
Parse( aChildNode, aContext );
2275 wxASSERT( aNode->GetName() == wxT(
"DOCSYMBOL" ) );
2282 bool originParsed =
false;
2284 for( ; cNode; cNode = cNode->
GetNext() )
2286 wxString cNodeName = cNode->GetName();
2288 if( !originParsed && cNodeName == wxT(
"PT" ) )
2290 Origin.Parse( cNode, aContext );
2291 originParsed =
true;
2293 else if( cNodeName == wxT(
"GROUPREF" ) )
2297 else if( cNodeName == wxT(
"REUSEBLOCKREF" ) )
2301 else if( cNodeName == wxT(
"FIX" ) )
2305 else if( cNodeName == wxT(
"MIRROR" ) )
2309 else if( cNodeName == wxT(
"READABILITY" ) )
2313 else if( cNodeName == wxT(
"ORIENT" ) )
2317 else if( cNodeName == wxT(
"ATTR" ) )
2320 attr.
Parse( cNode, aContext );
2323 else if( cNodeName == wxT(
"SCALE" ) )
2341 wxASSERT( aNode->GetName() == wxT(
"DFLTSETTINGS" ) );
2347 for( ; cNode; cNode = cNode->
GetNext() )
2349 wxString cNodeName = cNode->GetName();
2351 if( cNodeName == wxT(
"INVISIBLE" ) )
2365 wxASSERT( aNode->GetName() == wxT(
"ATTRCOL" ) );
2372 for( ; cNode; cNode = cNode->
GetNext() )
2374 wxString cNodeName = cNode->GetName();
2376 if( cNodeName == wxT(
"INVISIBLE" ) )
2380 else if( cNodeName == wxT(
"NOTPICKABLE" ) )
2394 wxASSERT( aNode->GetName() == wxT(
"ATTRCOLORS" ) );
2398 for( ; cNode; cNode = cNode->
GetNext() )
2400 wxString cNodeName = cNode->GetName();
2402 if( cNodeName == wxT(
"DFLTSETTINGS" ) )
2406 else if( cNodeName == wxT(
"ATTRCOL" ) )
2409 attrcol.
Parse( cNode, aContext );
2412 else if( cNodeName == wxT(
"INVISIBLE" ) )
2426 wxASSERT( aNode->GetName() == wxT(
"PARTNAMECOL" ) );
2432 for( ; cNode; cNode = cNode->
GetNext() )
2434 wxString cNodeName = cNode->GetName();
2436 if( cNodeName == wxT(
"INVISIBLE" ) )
2440 else if( cNodeName == wxT(
"NOTPICKABLE" ) )
2454 static const wxString c_numAttributes = wxT(
"numAttributes" );
2457 long numAttributes = 0;
2459 if( aNode->GetAttribute( c_numAttributes, &
result ) )
2461 numAttributes = wxAtol(
result );
2462 aNode->DeleteAttribute( c_numAttributes );
2466#if wxUSE_UNICODE_WCHAR
2467 std::wstring numAttrStr = std::to_wstring( numAttributes );
2469 std::string numAttrStr = std::to_string( numAttributes );
2474 wxString paramName = wxT(
"attr" );
2475 paramName << numAttrStr;
2482 const wxString& aFileTypeIdentifier,
2485 KEYWORD emptyKeywords[1] = {};
2486 XNODE* rootNode =
nullptr;
2487 XNODE* cNode =
nullptr;
2488 XNODE* iNode =
nullptr;
2490 bool cadstarFileCheckDone =
false;
2492 wxCSConv win1252( wxT(
"windows-1252" ) );
2493 wxMBConv* conv = &win1252;
2497 FILE* fp = wxFopen( aFileName, wxT(
"rt" ) );
2502 fseek( fp, 0
L, SEEK_END );
2503 long fileSize = ftell( fp );
2506 DSNLEXER lexer( emptyKeywords, 0,
nullptr, fp, aFileName );
2508 auto currentProgress =
2511 return static_cast<double>( ftell( fp ) ) / fileSize;
2514 double previousReportedProgress = -1.0;
2518 if( aProgressReporter && ( currentProgress() - previousReportedProgress ) > 0.01 )
2528 previousReportedProgress = currentProgress();
2542 THROW_IO_ERROR(
_(
"The selected file is not valid or might be corrupt!" ) );
2548 str = wxString( lexer.
CurText(), *conv );
2549 cNode =
new XNODE( wxXML_ELEMENT_NODE, str );
2558 iNode->AddChild( cNode );
2560 else if( !cadstarFileCheckDone )
2562 if( cNode->GetName() != aFileTypeIdentifier )
2565 THROW_IO_ERROR(
_(
"The selected file is not valid or might be corrupt!" ) );
2568 cadstarFileCheckDone =
true;
2575 str = wxString( lexer.
CurText(), *conv );
2583 THROW_IO_ERROR(
_(
"The selected file is not valid or might be corrupt!" ) );
2588 if( iNode !=
nullptr )
2591 THROW_IO_ERROR(
_(
"The selected file is not valid or might be corrupt!" ) );
2602 THROW_IO_ERROR(
_(
"The selected file is not valid or might be corrupt!" ) );
2611 return aAttribute->GetName() != wxT(
"numAttributes" );
2618#if wxUSE_UNICODE_WCHAR
2619 std::wstring idStr = std::to_wstring( aID );
2621 std::string idStr = std::to_string( aID );
2624 wxString attrName = wxS(
"attr" );
2629 if( !aNode->GetAttribute( attrName, &retVal ) )
2634 return wxEmptyString;
2667 if( aNode && aNode->
GetNext() )
2675 if( aNode->
GetChildren()->GetName() == wxT(
"E" ) )
2685 std::vector<POINT> retVal;
2689 for( ; cNode; cNode = cNode->
GetNext() )
2691 if( cNode->GetName() == wxT(
"PT" ) )
2697 pt.
Parse( cNode, aContext );
2704 retVal.push_back( pt );
2706 else if( aTestAllChildNodes )
2712 if( aExpectedNumPoints !=
UNDEFINED_VALUE && retVal.size() !=
static_cast<size_t>( aExpectedNumPoints ) )
2714 THROW_IO_ERRORF(
_(
"Unexpected number of points in '%s'. Found %d but expected %d." ),
2717 aExpectedNumPoints );
2727 std::vector<VERTEX> retVal;
2731 for( ; cNode; cNode = cNode->
GetNext() )
2739 vertex.
Parse( cNode, aContext );
2746 retVal.push_back( vertex );
2748 else if( aTestAllChildNodes )
2761 std::vector<CUTOUT> retVal;
2765 for( ; cNode; cNode = cNode->
GetNext() )
2767 if( cNode->GetName() == wxT(
"CUTOUT" ) )
2773 cutout.
Parse( cNode, aContext );
2780 retVal.push_back( cutout );
2782 else if( aTestAllChildNodes )
2797 for( ; childNodes; childNodes = childNodes->
GetNext() )
2805 XNODE* aRootNode, std::vector<wxString> aSubNodeChildrenToCount )
2810 for( ; level1Node; level1Node = level1Node->
GetNext() )
2812 for( wxString childNodeName : aSubNodeChildrenToCount )
2814 if( level1Node->GetName() == childNodeName )
2827 wxString escapedText = aCadstarString;
2829 escapedText.Replace( wxT(
"'" ), wxT(
"~" ) );
2837 if( !aKiCadTextItem->
GetText().IsEmpty() )
2844 int numExtraLines =
text.Replace(
"\n",
"\n" );
2845 numExtraLines -=
text.at(
text.size() - 1 ) ==
'\n';
2846 positionOffset.
x *= numExtraLines;
2847 positionOffset.
y *= numExtraLines;
2849 aKiCadTextItem->
Offset( positionOffset );
2855 const wxString& aAlternateName )
2857 if( aAlternateName.IsEmpty() )
CADSTAR_PIN_POSITION
Positioning of pin names can be in one of four quadrants.
@ 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
#define THROW_IO_ERRORF(msg,...)
#define THROW_IO_CANCELLED()
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)
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.
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 subnode="NETCLASSREF".
SPACING_CLASS_ID SpacingClassID
The net might not have a spacing class, in which case it will be wxEmptyString subnode="SPACINGCLASS"...
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
Can be empty.
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.
TERMINAL_ID TerminalPin
(subnode="PINTERM", param1)
wxString Identifier
This should match a pad identifier in the component footprint.
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.
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, defaults to equal height (1:1 aspect r...
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