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" ) )
132 Timestamp.Parse( cNode, aContext );
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->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" ) )
231 wxASSERT( aNode->GetName() == wxT(
"HATCH" ) );
238 if( !cNode || cNode->GetName() != wxT(
"ORIENT" ) )
247 wxASSERT( aNode->GetName() == wxT(
"HATCHCODE" ) );
255 for( ; cNode; cNode = cNode->
GetNext() )
257 if( cNode->GetName() != wxT(
"HATCH" ) )
261 hatch.
Parse( cNode, aContext );
262 Hatches.push_back( hatch );
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 );
375 RouteReassigns.push_back( routereassign );
387 return Base * std::pow( 10.0, Exponent );
393 wxASSERT( aNode->GetName() == wxT(
"E" ) );
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" ) )
441 wxASSERT( IsVertex( aNode ) );
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 double aAccuracy )
const
489 VECTOR2I endPoint = aCadstarToKicadPointCallback( End );
493 aChainToAppendTo->
Append( endPoint );
497 wxCHECK_MSG( aChainToAppendTo->
PointCount() > 0, ,
498 "Can't append an arc to vertex to an empty chain" );
504 centerPoint = ( startPoint / 2 ) + ( endPoint / 2 );
506 centerPoint = aCadstarToKicadPointCallback(
Center );
512 VECTOR2I transform = aCadstarToKicadPointCallback( { 500, 500 } )
513 - aCadstarToKicadPointCallback( { 0, 0 } );
515 if( ( transform.
x > 0 && transform.
y < 0 ) || ( transform.
x < 0 && transform.
y > 0 ) )
516 clockwise = !clockwise;
521 aChainToAppendTo->
Append( arc, aAccuracy );
527 wxASSERT( aNode->GetName() == wxT(
"CUTOUT" ) );
535 wxString aNodeName = aNode->GetName();
537 if( aNodeName == wxT(
"OPENSHAPE" ) || aNodeName == wxT(
"OUTLINE" )
538 || aNodeName == wxT(
"SOLID" ) || aNodeName == wxT(
"HATCHED" ) )
551 wxASSERT( IsShape( aNode ) );
553 wxString aNodeName = aNode->GetName();
555 if( aNodeName == wxT(
"OPENSHAPE" ) )
560 HatchCodeID = wxEmptyString;
562 else if( aNodeName == wxT(
"OUTLINE" ) )
567 HatchCodeID = wxEmptyString;
569 else if( aNodeName == wxT(
"SOLID" ) )
574 HatchCodeID = wxEmptyString;
576 else if( aNodeName == wxT(
"HATCHED" ) )
585 wxASSERT_MSG(
true, wxT(
"Unknown SHAPE type" ) );
590 const std::function<
VECTOR2I(
const VECTOR2I& )> aCadstarToKicadPointCallback,
591 double aAccuracy )
const
595 if( Vertices.size() == 0 )
598 for(
const auto& vertex : Vertices )
599 vertex.AppendToChain( &outline, aCadstarToKicadPointCallback, aAccuracy );
606 Vertices.at( 0 ).AppendToChain( &outline, aCadstarToKicadPointCallback, aAccuracy );
614 const std::function<
VECTOR2I(
const VECTOR2I& )> aCadstarToKicadPointCallback,
615 double aAccuracy )
const
621 polyset.
AddOutline( OutlineAsChain( aCadstarToKicadPointCallback, aAccuracy ) );
623 for(
const auto& cutout : Cutouts )
627 if( cutout.Vertices.size() == 0 )
630 for(
const auto& cutoutVertex : cutout.Vertices )
631 cutoutVertex.AppendToChain( &hole, aCadstarToKicadPointCallback, aAccuracy );
636 cutout.Vertices.at( 0 ).AppendToChain( &hole, aCadstarToKicadPointCallback, aAccuracy );
647 wxASSERT( aNode->GetName() == wxT(
"UNITS" ) );
651 if( unit == wxT(
"CENTIMETER" ) )
653 else if( unit == wxT(
"INCH" ) )
655 else if( unit == wxT(
"METER" ) )
657 else if( unit == wxT(
"MICROMETRE" ) )
659 else if( unit == wxT(
"MM" ) )
661 else if( unit == wxT(
"THOU" ) )
663 else if( unit == wxT(
"DESIGN" ) )
674 wxASSERT( aNode->GetName() == wxT(
"ANGUNITS" ) );
678 if( angUnitStr == wxT(
"DEGREES" ) )
680 else if( angUnitStr == wxT(
"RADIANS" ) )
691 wxString aNodeName = aNode->GetName();
693 if( aNodeName == wxT(
"FRACTIONALGRID" ) || aNodeName == wxT(
"STEPGRID" ) )
702 wxASSERT( IsGrid( aNode ) );
704 wxString aNodeName = aNode->GetName();
706 if( aNodeName == wxT(
"FRACTIONALGRID" ) )
708 else if( aNodeName == wxT(
"STEPGRID" ) )
711 wxASSERT_MSG(
true, wxT(
"Unknown Grid Type" ) );
721 wxASSERT( aNode->GetName() == wxT(
"GRIDS" ) );
725 for( ; cNode; cNode = cNode->
GetNext() )
727 wxString cNodeName = cNode->GetName();
729 if( cNodeName == wxT(
"WORKINGGRID" ) )
736 workingGridNode->GetName(), wxT(
"GRIDS -> WORKINGGRID" ) );
740 WorkingGrid.Parse( workingGridNode, aContext );
743 else if( cNodeName == wxT(
"SCREENGRID" ) )
750 screenGridNode->GetName(), wxT(
"GRIDS -> SCREENGRID" ) );
754 ScreenGrid.Parse( screenGridNode, aContext );
760 userGrid.
Parse( cNode, aContext );
761 UserGrids.push_back( userGrid );
769 wxString cNodeName = aChildNode->GetName();
771 if( cNodeName == wxT(
"UNITS" ) )
775 else if( cNodeName == wxT(
"UNITSPRECISION" ) )
779 else if( cNodeName == wxT(
"INTERLINEGAP" ) )
783 else if( cNodeName == wxT(
"BARLINEGAP" ) )
787 else if( cNodeName == wxT(
"ALLOWBARTEXT" ) )
789 AllowBarredText =
true;
791 else if( cNodeName == wxT(
"ANGULARPRECISION" ) )
795 else if( cNodeName == wxT(
"DESIGNORIGIN" ) )
797 DesignOrigin.Parse( aChildNode->
GetChildren(), aContext );
799 else if( cNodeName == wxT(
"DESIGNAREA" ) )
802 DesignArea = std::make_pair( pts[0], pts[1] );
804 else if( cNodeName == wxT(
"DESIGNREF" ) )
806 DesignOrigin.Parse( aChildNode->
GetChildren(), aContext );
808 else if( cNodeName == wxT(
"DESIGNLIMIT" ) )
810 DesignLimit.Parse( aChildNode->
GetChildren(), aContext );
823 wxASSERT( aNode->GetName() == wxT(
"SETTINGS" ) );
827 for( ; cNode; cNode = cNode->
GetNext() )
829 wxString cNodeName = cNode->GetName();
831 if( ParseSubNode( cNode, aContext ) )
842 static const std::map<TEXT_FIELD_NAME, wxString> txtTokens =
866 wxString remainingStr = aTextString;
869 while( remainingStr.size() > 0 )
872 size_t startpos = remainingStr.Find( wxT(
"<@" ) );
874 if(
static_cast<int>( startpos ) == wxNOT_FOUND )
877 returnStr += remainingStr;
882 returnStr += remainingStr.SubString( 0, startpos - 1 );
884 if( ( startpos + 2 ) >= remainingStr.size() )
887 remainingStr = remainingStr.Mid( startpos + 2 );
892 for( std::pair<TEXT_FIELD_NAME, wxString> txtF : txtTokens )
894 if( remainingStr.StartsWith( txtF.second ) )
896 foundField = txtF.first;
904 returnStr += wxT(
"<@" );
909 size_t endpos = remainingStr.Find( wxT(
"@>" ) );
911 if(
static_cast<int>( endpos ) == wxNOT_FOUND )
915 returnStr += wxT(
"<@" ) + remainingStr;
919 size_t valueStart = txtTokens.at( foundField ).size();
920 wxString fieldValue = remainingStr.SubString( valueStart, endpos - 1 );
926 wxASSERT_MSG( fieldValue.at( 0 ) ==
'"',
"Expected '\"' as the first character" );
928 size_t splitPos = fieldValue.find_first_of(
'"', 1 );
929 address = fieldValue.SubString( 1, splitPos - 1 );
934 wxASSERT_MSG( remainingStr.EndsWith( wxT(
"@>" ) ),
935 "Expected '@>' at the end of a hyperlink" );
937 fieldValue = remainingStr.SubString( valueStart + splitPos + 1,
938 remainingStr.Length() - 3 );
940 remainingStr = wxEmptyString;
944 fieldValue = fieldValue.Mid( splitPos + 1 );
985 returnStr += fieldValue;
990 wxFileName fn( address );
991 wxString fieldFmt = wxT(
"FROM_FILE_%s_%s" );
992 wxString fieldName =
wxString::Format( fieldFmt, fn.GetName(), fn.GetExt() );
1006 returnStr += wxT(
"${" ) + fieldName + wxT(
"}" );
1018 wxFAIL_MSG(
"We should have already covered this scenario above" );
1023 if( ( endpos + 2 ) >= remainingStr.size() )
1026 remainingStr = remainingStr.Mid( endpos + 2 );
1035 wxASSERT( aNode->GetName() == wxT(
"ALIGN" ) );
1039 if( alignmentStr == wxT(
"BOTTOMCENTER" ) )
1041 else if( alignmentStr == wxT(
"BOTTOMLEFT" ) )
1043 else if( alignmentStr == wxT(
"BOTTOMRIGHT" ) )
1045 else if( alignmentStr == wxT(
"CENTERCENTER" ) )
1047 else if( alignmentStr == wxT(
"CENTERLEFT" ) )
1049 else if( alignmentStr == wxT(
"CENTERRIGHT" ) )
1051 else if( alignmentStr == wxT(
"TOPCENTER" ) )
1053 else if( alignmentStr == wxT(
"TOPLEFT" ) )
1055 else if( alignmentStr == wxT(
"TOPRIGHT" ) )
1067 wxASSERT( aNode->GetName() == wxT(
"JUSTIFICATION" ) );
1071 if( justificationStr == wxT(
"LEFT" ) )
1073 else if( justificationStr == wxT(
"RIGHT" ) )
1075 else if( justificationStr == wxT(
"CENTER" ) )
1086 wxASSERT( aNode->GetName() == wxT(
"READABILITY" ) );
1090 if( readabilityStr == wxT(
"BOTTOM_TO_TOP" ) )
1092 else if( readabilityStr == wxT(
"TOP_TO_BOTTOM" ) )
1112 wxString cNodeName = aChildNode->GetName();
1114 if( cNodeName == wxT(
"PT" ) )
1115 Position.Parse( aChildNode, aContext );
1116 else if( cNodeName == wxT(
"ORIENT" ) )
1118 else if( cNodeName == wxT(
"MIRROR" ) )
1120 else if( cNodeName == wxT(
"FIX" ) )
1122 else if( cNodeName == wxT(
"ALIGN" ) )
1124 else if( cNodeName == wxT(
"JUSTIFICATION" ) )
1135 wxASSERT( aNode->GetName() == wxT(
"ATTRLOC" ) );
1137 ParseIdentifiers( aNode, aContext );
1142 for( ; cNode; cNode = cNode->
GetNext() )
1144 if( ParseSubNode( cNode, aContext ) )
1150 if( !Position.IsFullySpecified() )
1157 wxASSERT( aNode->GetName() == wxT(
"COLUMNORDER" ) );
1168 wxASSERT( aNode->GetName() == wxT(
"COLUMNWIDTH" ) );
1179 wxASSERT( aNode->GetName() == wxT(
"ATTRNAME" ) );
1187 for( ; cNode; cNode = cNode->
GetNext() )
1189 wxString cNodeName = cNode->GetName();
1191 if( cNodeName == wxT(
"ATTROWNER" ) )
1195 if( attOwnerVal == wxT(
"ALL_ITEMS" ) )
1197 else if( attOwnerVal == wxT(
"AREA" ) )
1199 else if( attOwnerVal == wxT(
"BOARD" ) )
1201 else if( attOwnerVal == wxT(
"COMPONENT" ) )
1203 else if( attOwnerVal == wxT(
"CONNECTION" ) )
1205 else if( attOwnerVal == wxT(
"COPPER" ) )
1207 else if( attOwnerVal == wxT(
"DOCSYMBOL" ) )
1209 else if( attOwnerVal == wxT(
"FIGURE" ) )
1211 else if( attOwnerVal == wxT(
"NET" ) )
1213 else if( attOwnerVal == wxT(
"NETCLASS" ) )
1215 else if( attOwnerVal == wxT(
"PART" ) )
1217 else if( attOwnerVal == wxT(
"PART_DEFINITION" ) )
1219 else if( attOwnerVal == wxT(
"PIN" ) )
1221 else if( attOwnerVal == wxT(
"SIGNALREF" ) )
1223 else if( attOwnerVal == wxT(
"SYMBOL" ) )
1225 else if( attOwnerVal == wxT(
"SYMDEF" ) )
1227 else if( attOwnerVal == wxT(
"TEMPLATE" ) )
1229 else if( attOwnerVal == wxT(
"TESTPOINT" ) )
1234 else if( cNodeName == wxT(
"ATTRUSAGE" ) )
1238 if( attUsageVal == wxT(
"BOTH" ) )
1240 else if( attUsageVal == wxT(
"COMPONENT" ) )
1242 else if( attUsageVal == wxT(
"PART_DEFINITION" ) )
1244 else if( attUsageVal == wxT(
"PART_LIBRARY" ) )
1246 else if( attUsageVal == wxT(
"SYMBOL" ) )
1251 else if( cNodeName == wxT(
"NOTRANSFER" ) )
1255 else if( cNodeName == wxT(
"COLUMNORDER" ) )
1258 cOrder.
Parse( cNode, aContext );
1259 ColumnOrders.push_back( cOrder );
1261 else if( cNodeName == wxT(
"COLUMNWIDTH" ) )
1264 cWidth.
Parse( cNode, aContext );
1265 ColumnWidths.push_back( cWidth );
1267 else if( cNodeName == wxT(
"COLUMNINVISIBLE" ) )
1269 ColumnInvisible =
true;
1281 wxASSERT( aNode->GetName() == wxT(
"ATTR" ) );
1288 for( ; cNode; cNode = cNode->
GetNext() )
1290 if( cNode->GetName() == wxT(
"READONLY" ) )
1294 else if( cNode->GetName() == wxT(
"ATTRLOC" ) )
1296 AttributeLocation.Parse( cNode, aContext );
1309 wxASSERT( aNode->GetName() == wxT(
"TEXTLOC" ) );
1312 bool attributeIDisSet =
false;
1314 if( attributeStr == wxT(
"PART_NAME" ) )
1317 attributeIDisSet =
true;
1319 else if( attributeStr == wxT(
"COMP_NAME" ) )
1322 attributeIDisSet =
true;
1324 else if( attributeStr == wxT(
"COMP_NAME2" ) )
1327 attributeIDisSet =
true;
1329 else if( attributeStr == wxT(
"SYMBOL_NAME" ) )
1332 attributeIDisSet =
true;
1334 else if( attributeStr == wxT(
"LINK_ORIGIN" ) )
1337 attributeIDisSet =
true;
1339 else if( attributeStr == wxT(
"SIGNALNAME_ORIGIN" ) )
1342 attributeIDisSet =
true;
1344 else if( attributeStr == wxT(
"ATTRREF" ) )
1347 attributeIDisSet =
false;
1360 for( ; cNode; cNode = cNode->
GetNext() )
1362 wxString cNodeName = cNode->GetName();
1364 if( ParseSubNode( cNode, aContext ) )
1368 else if( !attributeIDisSet && cNodeName == wxT(
"ATTRREF" ) )
1371 attributeIDisSet =
true;
1373 else if( cNodeName == wxT(
"ORIENT" ) )
1377 else if( cNodeName == wxT(
"MIRROR" ) )
1381 else if( cNodeName == wxT(
"FIX" ) )
1385 else if( cNodeName == wxT(
"ALIGN" ) )
1389 else if( cNodeName == wxT(
"JUSTIFICATION" ) )
1399 if( !Position.IsFullySpecified() )
1406 wxASSERT( aNode->GetName() == wxT(
"NETCLASS" ) );
1414 for( ; cNode; cNode = cNode->
GetNext() )
1416 wxString cNodeName = cNode->GetName();
1418 if( cNodeName == wxT(
"ATTR" ) )
1421 attribute_val.
Parse( cNode, aContext );
1422 Attributes.push_back( attribute_val );
1434 wxASSERT( aNode->GetName() == wxT(
"SPCCLASSNAME" ) );
1443 wxString nodeName = aChildNode->GetName();
1445 if( nodeName == wxT(
"LINECODE" ) )
1448 linecode.
Parse( aChildNode, aContext );
1449 LineCodes.insert( std::make_pair( linecode.
ID, linecode ) );
1451 else if( nodeName == wxT(
"HATCHCODE" ) )
1454 hatchcode.
Parse( aChildNode, aContext );
1455 HatchCodes.insert( std::make_pair( hatchcode.
ID, hatchcode ) );
1457 else if( nodeName == wxT(
"TEXTCODE" ) )
1460 textcode.
Parse( aChildNode, aContext );
1461 TextCodes.insert( std::make_pair( textcode.
ID, textcode ) );
1463 else if( nodeName == wxT(
"ROUTECODE" ) )
1466 routecode.
Parse( aChildNode, aContext );
1467 RouteCodes.insert( std::make_pair( routecode.
ID, routecode ) );
1469 else if( nodeName == wxT(
"ATTRNAME" ) )
1472 attrname.
Parse( aChildNode, aContext );
1473 AttributeNames.insert( std::make_pair( attrname.
ID, attrname ) );
1475 else if( nodeName == wxT(
"NETCLASS" ) )
1478 netclass.
Parse( aChildNode, aContext );
1479 NetClasses.insert( std::make_pair( netclass.
ID, netclass ) );
1481 else if( nodeName == wxT(
"SPCCLASSNAME" ) )
1484 spcclassname.
Parse( aChildNode, aContext );
1485 SpacingClassNames.insert( std::make_pair( spcclassname.
ID, spcclassname ) );
1498 wxASSERT( aNode->GetName() == wxT(
"SWAPRULE" ) );
1503 if( swapRuleStr == wxT(
"NO_SWAP" ) )
1505 else if( swapRuleStr == wxT(
"USE_SWAP_LAYER" ) )
1516 wxASSERT( aNode->GetName() == wxT(
"REUSEBLOCK" ) );
1524 for( ; cNode; cNode = cNode->
GetNext() )
1526 wxString cNodeName = cNode->GetName();
1528 if( cNodeName == wxT(
"MIRROR" ) )
1530 else if( cNodeName == wxT(
"ORIENT" ) )
1540 return ReuseBlockID == wxEmptyString && ItemReference == wxEmptyString;
1546 wxASSERT( aNode->GetName() == wxT(
"REUSEBLOCKREF" ) );
1557 wxASSERT( aNode->GetName() == wxT(
"GROUP" ) );
1564 for( ; cNode; cNode = cNode->
GetNext() )
1566 wxString cNodeName = cNode->GetName();
1568 if( cNodeName == wxT(
"FIX" ) )
1570 else if( cNodeName == wxT(
"TRANSFER" ) )
1572 else if( cNodeName == wxT(
"GROUPREF" ) )
1574 else if( cNodeName == wxT(
"REUSEBLOCKREF" ) )
1575 ReuseBlockRef.Parse( cNode, aContext );
1584 wxASSERT( aNode->GetName() == wxT(
"FIGURE" ) );
1591 bool shapeIsInitialised =
false;
1597 for( ; cNode; cNode = cNode->
GetNext() )
1599 wxString cNodeName = cNode->GetName();
1601 if( !shapeIsInitialised && Shape.IsShape( cNode ) )
1603 Shape.Parse( cNode, aContext );
1604 shapeIsInitialised =
true;
1606 else if( cNodeName == wxT(
"SWAPRULE" ) )
1610 else if( cNodeName == wxT(
"FIX" ) )
1614 else if( cNodeName == wxT(
"GROUPREF" ) )
1619 else if( cNodeName == wxT(
"REUSEBLOCKREF" ) )
1621 ReuseBlockRef.Parse( cNode, aContext );
1623 else if( cNodeName == wxT(
"ATTR" ) )
1626 attr.
Parse( cNode, aContext );
1627 AttributeValues.insert( std::make_pair( attr.
AttributeID, attr ) );
1639 Parse( aNode, aContext,
true );
1646 wxASSERT( aNode->GetName() == wxT(
"TEXT" ) );
1662 for( ; cNode; cNode = cNode->
GetNext() )
1664 wxString cNodeName = cNode->GetName();
1666 if( cNodeName == wxT(
"PT" ) )
1667 Position.Parse( cNode, aContext );
1668 else if( cNodeName == wxT(
"ORIENT" ) )
1670 else if( cNodeName == wxT(
"MIRROR" ) )
1672 else if( cNodeName == wxT(
"FIX" ) )
1674 else if( cNodeName == wxT(
"SWAPRULE" ) )
1676 else if( cNodeName == wxT(
"ALIGN" ) )
1678 else if( cNodeName == wxT(
"JUSTIFICATION" ) )
1680 else if( cNodeName == wxT(
"GROUPREF" ) )
1682 else if( cNodeName == wxT(
"REUSEBLOCKREF" ) )
1683 ReuseBlockRef.Parse( cNode, aContext );
1692 wxASSERT( aNode->GetName() == wxT(
"SYMDEF" ) );
1702 wxString cNodeName = aChildNode->GetName();
1704 if( cNodeName == wxT(
"PT" ) )
1706 Origin.Parse( aChildNode, aContext );
1708 else if( cNodeName == wxT(
"STUB" ) )
1712 else if( cNodeName == wxT(
"VERSION" ) )
1716 else if( cNodeName == wxT(
"FIGURE" ) )
1719 figure.
Parse( aChildNode, aContext );
1720 Figures.insert( std::make_pair( figure.
ID, figure ) );
1722 else if( cNodeName == wxT(
"TEXT" ) )
1725 txt.
Parse( aChildNode, aContext );
1726 Texts.insert( std::make_pair( txt.
ID, txt ) );
1728 else if( cNodeName == wxT(
"TEXTLOC" ) )
1731 textloc.
Parse( aChildNode, aContext );
1732 TextLocations.insert( std::make_pair( textloc.
AttributeID, textloc ) );
1734 else if( cNodeName == wxT(
"ATTR" ) )
1737 attrVal.
Parse( aChildNode, aContext );
1738 AttributeValues.insert( std::make_pair( attrVal.
AttributeID, attrVal ) );
1751 wxASSERT( aNode->GetName() == wxT(
"GATEDEFINITION" ) );
1764 wxASSERT( aNode->GetName() == wxT(
"PINTYPE" ) );
1768 std::map<wxString, PIN_TYPE> pinTypeMap = { { wxT(
"INPUT" ), PIN_TYPE::INPUT },
1769 { wxT(
"OUTPUT_OR" ), PIN_TYPE::OUTPUT_OR },
1770 { wxT(
"OUTPUT_NOT_OR" ), PIN_TYPE::OUTPUT_NOT_OR },
1771 { wxT(
"OUTPUT_NOT_NORM_OR" ), PIN_TYPE::OUTPUT_NOT_NORM_OR },
1772 { wxT(
"POWER" ), PIN_TYPE::POWER }, { wxT(
"GROUND" ), PIN_TYPE::GROUND },
1773 { wxT(
"TRISTATE_BIDIR" ), PIN_TYPE::TRISTATE_BIDIR },
1774 { wxT(
"TRISTATE_INPUT" ), PIN_TYPE::TRISTATE_INPUT },
1775 { wxT(
"TRISTATE_DRIVER" ), PIN_TYPE::TRISTATE_DRIVER } };
1777 if( pinTypeMap.find( pinTypeStr ) == pinTypeMap.end() )
1780 return pinTypeMap[pinTypeStr];
1786 wxASSERT( aNode->GetName() == wxT(
"PARTDEFINITIONPIN" ) );
1792 for( ; cNode; cNode = cNode->
GetNext() )
1794 wxString cNodeName = cNode->GetName();
1796 if( cNodeName == wxT(
"PINNAME" ) )
1800 else if( cNodeName == wxT(
"PINLABEL" ) )
1804 else if( cNodeName == wxT(
"PINSIGNAL" ) )
1808 else if( cNodeName == wxT(
"PINTERM" ) )
1813 else if( cNodeName == wxT(
"PINTYPE" ) )
1815 Type = GetPinType( cNode );
1817 else if( cNodeName == wxT(
"PINLOAD" ) )
1821 else if( cNodeName == wxT(
"PINPOSITION" ) )
1825 else if( cNodeName == wxT(
"PINIDENTIFIER" ) )
1839 wxASSERT( aNode->GetName() == wxT(
"PARTPIN" ) );
1845 for( ; cNode; cNode = cNode->
GetNext() )
1847 wxString cNodeName = cNode->GetName();
1849 if( cNodeName == wxT(
"PINNAME" ) )
1851 else if( cNodeName == wxT(
"PINTYPE" ) )
1852 Type = GetPinType( cNode );
1853 else if( cNodeName == wxT(
"PINIDENTIFIER" ) )
1864 wxASSERT( aNode->GetName() == wxT(
"PINEQUIVALENCE" ) );
1866 wxXmlAttribute* xmlAttribute = aNode->GetAttributes();
1868 for( ; xmlAttribute; xmlAttribute = xmlAttribute->GetNext() )
1875 if( !xmlAttribute->GetValue().ToLong( &pinId ) )
1888 wxASSERT( aNode->GetName() == wxT(
"SWAPGATE" ) );
1890 wxXmlAttribute* xmlAttribute = aNode->GetAttributes();
1892 for( ; xmlAttribute; xmlAttribute = xmlAttribute->GetNext() )
1899 if( !xmlAttribute->GetValue().ToLong( &pinId ) )
1912 wxASSERT( aNode->GetName() == wxT(
"SWAPGROUP" ) );
1918 for( ; cNode; cNode = cNode->
GetNext() )
1920 wxString cNodeName = cNode->GetName();
1922 if( cNodeName == wxT(
"EXTERNAL" ) )
1926 else if( cNodeName == wxT(
"SWAPGATE" ) )
1929 swapGate.
Parse( cNode, aContext );
1930 SwapGates.push_back( swapGate );
1942 wxASSERT( aNode->GetName() == wxT(
"PARTDEFINITION" ) );
1948 for( ; cNode; cNode = cNode->
GetNext() )
1950 wxString cNodeName = cNode->GetName();
1952 if( cNodeName == wxT(
"HIDEPINNAMES" ) )
1954 HidePinNames =
true;
1956 else if( cNodeName == wxT(
"MAXPIN" ) )
1960 else if( cNodeName == wxT(
"GATEDEFINITION" ) )
1963 gate.
Parse( cNode, aContext );
1964 GateSymbols.insert( std::make_pair( gate.
ID, gate ) );
1966 else if( cNodeName == wxT(
"PARTDEFINITIONPIN" ) )
1969 pin.Parse( cNode, aContext );
1970 Pins.insert( std::make_pair(
pin.ID,
pin ) );
1972 else if( cNodeName == wxT(
"ATTR" ) )
1975 attr.
Parse( cNode, aContext );
1976 AttributeValues.insert( std::make_pair( attr.
AttributeID, attr ) );
1978 else if( cNodeName == wxT(
"PINEQUIVALENCE" ) )
1981 pinEq.
Parse( cNode, aContext );
1982 PinEquivalences.push_back( pinEq );
1984 else if( cNodeName == wxT(
"SWAPGROUP" ) )
1987 swapGroup.
Parse( cNode, aContext );
1988 SwapGroups.push_back( swapGroup );
2000 wxASSERT( aNode->GetName() == wxT(
"PART" ) );
2007 for( ; cNode; cNode = cNode->
GetNext() )
2009 wxString cNodeName = cNode->GetName();
2011 if( cNodeName == wxT(
"VERSION" ) )
2015 else if( cNodeName == wxT(
"HIDEPINNAMES" ) )
2017 HidePinNames =
true;
2019 else if( cNodeName == wxT(
"PARTDEFINITION" ) )
2021 Definition.Parse( cNode, aContext );
2023 else if( cNodeName == wxT(
"PARTPIN" ) )
2026 pin.Parse( cNode, aContext );
2027 PartPins.insert( std::make_pair(
pin.ID,
pin ) );
2029 else if( cNodeName == wxT(
"ATTR" ) )
2032 attr.
Parse( cNode, aContext );
2033 AttributeValues.insert( std::make_pair( attr.
AttributeID, attr ) );
2045 wxASSERT( aNode->GetName() == wxT(
"PARTS" ) );
2049 for( ; cNode; cNode = cNode->
GetNext() )
2051 wxString cNodeName = cNode->GetName();
2053 if( cNodeName == wxT(
"PART" ) )
2056 part.
Parse( cNode, aContext );
2057 PartDefinitions.insert( std::make_pair( part.
ID, part ) );
2072 wxASSERT( aNode->GetName() == wxT(
"JPT" ) );
2082 wxString cNodeName = aChildNode->GetName();
2084 if( cNodeName == wxT(
"PT" ) )
2085 Location.Parse( aChildNode, aContext );
2086 else if( cNodeName == wxT(
"FIX" ) )
2088 else if( cNodeName == wxT(
"GROUPREF" ) )
2090 else if( cNodeName == wxT(
"REUSEBLOCKREF" ) )
2091 ReuseBlockRef.Parse( aChildNode, aContext );
2101 ParseIdentifiers( aNode, aContext );
2104 for( ; cNode; cNode = cNode->
GetNext() )
2106 if( ParseSubNode( cNode, aContext ) )
2117 wxASSERT( aNode->GetName() == wxT(
"CONN" ) );
2128 wxString cNodeName = aChildNode->GetName();
2130 if( cNodeName == wxT(
"FIX" ) )
2134 else if( cNodeName == wxT(
"HIDDEN" ) )
2138 else if( cNodeName == wxT(
"GROUPREF" ) )
2142 else if( cNodeName == wxT(
"REUSEBLOCKREF" ) )
2144 ReuseBlockRef.Parse( aChildNode, aContext );
2146 else if( cNodeName == wxT(
"ATTR" ) )
2149 attrVal.
Parse( aChildNode, aContext );
2150 AttributeValues.insert( std::make_pair( attrVal.
AttributeID, attrVal ) );
2163 wxASSERT( aNode->GetName() == wxT(
"NET" ) );
2171 wxString cNodeName = aChildNode->GetName();
2173 if( cNodeName == wxT(
"NETCODE" ) )
2177 else if( cNodeName == wxT(
"SIGNAME" ) )
2181 else if( cNodeName == wxT(
"SIGNUM" ) )
2185 else if( cNodeName == wxT(
"HIGHLIT" ) )
2189 else if( cNodeName == wxT(
"JPT" ) )
2192 jpt.
Parse( aChildNode, aContext );
2193 Junctions.insert( std::make_pair( jpt.
ID, jpt ) );
2195 else if( cNodeName == wxT(
"NETCLASSREF" ) )
2199 else if( cNodeName == wxT(
"SPACINGCLASS" ) )
2203 else if( cNodeName == wxT(
"ATTR" ) )
2206 attrVal.
Parse( aChildNode, aContext );
2207 AttributeValues.insert( std::make_pair( attrVal.
AttributeID, attrVal ) );
2220 wxASSERT( aNode->GetName() == wxT(
"DOCSYMBOL" ) );
2227 bool originParsed =
false;
2229 for( ; cNode; cNode = cNode->
GetNext() )
2231 wxString cNodeName = cNode->GetName();
2233 if( !originParsed && cNodeName == wxT(
"PT" ) )
2235 Origin.Parse( cNode, aContext );
2236 originParsed =
true;
2238 else if( cNodeName == wxT(
"GROUPREF" ) )
2242 else if( cNodeName == wxT(
"REUSEBLOCKREF" ) )
2244 ReuseBlockRef.Parse( cNode, aContext );
2246 else if( cNodeName == wxT(
"FIX" ) )
2250 else if( cNodeName == wxT(
"MIRROR" ) )
2254 else if( cNodeName == wxT(
"READABILITY" ) )
2258 else if( cNodeName == wxT(
"ORIENT" ) )
2262 else if( cNodeName == wxT(
"ATTR" ) )
2265 attr.
Parse( cNode, aContext );
2266 AttributeValues.insert( std::make_pair( attr.
AttributeID, attr ) );
2268 else if( cNodeName == wxT(
"SCALE" ) )
2286 wxASSERT( aNode->GetName() == wxT(
"DFLTSETTINGS" ) );
2292 for( ; cNode; cNode = cNode->
GetNext() )
2294 wxString cNodeName = cNode->GetName();
2296 if( cNodeName == wxT(
"INVISIBLE" ) )
2310 wxASSERT( aNode->GetName() == wxT(
"ATTRCOL" ) );
2317 for( ; cNode; cNode = cNode->
GetNext() )
2319 wxString cNodeName = cNode->GetName();
2321 if( cNodeName == wxT(
"INVISIBLE" ) )
2325 else if( cNodeName == wxT(
"NOTPICKABLE" ) )
2339 wxASSERT( aNode->GetName() == wxT(
"ATTRCOLORS" ) );
2343 for( ; cNode; cNode = cNode->
GetNext() )
2345 wxString cNodeName = cNode->GetName();
2347 if( cNodeName == wxT(
"DFLTSETTINGS" ) )
2349 DefaultSettings.Parse( cNode, aContext );
2351 else if( cNodeName == wxT(
"ATTRCOL" ) )
2354 attrcol.
Parse( cNode, aContext );
2355 AttributeColors.insert( { attrcol.
AttributeID, attrcol } );
2357 else if( cNodeName == wxT(
"INVISIBLE" ) )
2371 wxASSERT( aNode->GetName() == wxT(
"PARTNAMECOL" ) );
2377 for( ; cNode; cNode = cNode->
GetNext() )
2379 wxString cNodeName = cNode->GetName();
2381 if( cNodeName == wxT(
"INVISIBLE" ) )
2385 else if( cNodeName == wxT(
"NOTPICKABLE" ) )
2400 int numAttributes = 0;
2402 if( aNode->GetAttribute( wxT(
"numAttributes" ), &result ) )
2404 numAttributes = wxAtoi( result );
2405 aNode->DeleteAttribute( wxT(
"numAttributes" ) );
2409 aNode->AddAttribute( wxT(
"numAttributes" ),
wxString::Format( wxT(
"%i" ), numAttributes ) );
2411 wxString paramName = wxT(
"attr" );
2412 paramName << numAttributes;
2414 aNode->AddAttribute( paramName, aValue );
2421 KEYWORD emptyKeywords[1] = {};
2422 XNODE * iNode =
nullptr, *cNode =
nullptr;
2424 bool cadstarFileCheckDone =
false;
2426 wxCSConv win1252( wxT(
"windows-1252" ) );
2427 wxMBConv* conv = &win1252;
2431 FILE* fp = wxFopen( aFileName, wxT(
"rt" ) );
2436 fseek( fp, 0L, SEEK_END );
2437 long fileSize = ftell( fp );
2440 DSNLEXER lexer( emptyKeywords, 0,
nullptr, fp, aFileName );
2442 auto currentProgress = [&]() ->
double
2444 return static_cast<double>( ftell( fp ) ) / fileSize;
2447 double previousReportedProgress = -1.0;
2451 if( aProgressReporter && ( currentProgress() - previousReportedProgress ) > 0.01 )
2457 previousReportedProgress = currentProgress();
2470 THROW_IO_ERROR(
_(
"The selected file is not valid or might be corrupt!" ) );
2476 str = wxString( lexer.
CurText(), *conv );
2477 cNode =
new XNODE( wxXML_ELEMENT_NODE, str );
2483 iNode->AddChild( cNode );
2485 else if( !cadstarFileCheckDone )
2487 if( cNode->GetName() != aFileTypeIdentifier )
2488 THROW_IO_ERROR(
_(
"The selected file is not valid or might be corrupt!" ) );
2490 cadstarFileCheckDone =
true;
2497 str = wxString( lexer.
CurText(), *conv );
2504 THROW_IO_ERROR(
_(
"The selected file is not valid or might be corrupt!" ) );
2509 if( iNode !=
nullptr )
2510 THROW_IO_ERROR(
_(
"The selected file is not valid or might be corrupt!" ) );
2516 THROW_IO_ERROR(
_(
"The selected file is not valid or might be corrupt!" ) );
2524 return aAttribute->GetName() != wxT(
"numAttributes" );
2531 wxString attrName, retVal;
2535 if( !aNode->GetAttribute( attrName, &retVal ) )
2540 return wxEmptyString;
2574 if( aNode && aNode->
GetNext() )
2582 if( aNode->
GetChildren()->GetName() == wxT(
"E" ) )
2592 std::vector<POINT> retVal;
2596 for( ; cNode; cNode = cNode->
GetNext() )
2598 if( cNode->GetName() == wxT(
"PT" ) )
2602 pt.
Parse( cNode, aContext );
2603 retVal.push_back( pt );
2605 else if( aTestAllChildNodes )
2612 && retVal.size() !=
static_cast<size_t>( aExpectedNumPoints ) )
2615 _(
"Unexpected number of points in '%s'. Found %d but expected %d." ),
2616 aNode->GetName(), retVal.size(), aExpectedNumPoints ) );
2626 std::vector<VERTEX> retVal;
2630 for( ; cNode; cNode = cNode->
GetNext() )
2636 vertex.
Parse( cNode, aContext );
2637 retVal.push_back( vertex );
2639 else if( aTestAllChildNodes )
2652 std::vector<CUTOUT> retVal;
2656 for( ; cNode; cNode = cNode->
GetNext() )
2658 if( cNode->GetName() == wxT(
"CUTOUT" ) )
2662 cutout.
Parse( cNode, aContext );
2663 retVal.push_back( cutout );
2665 else if( aTestAllChildNodes )
2680 for( ; childNodes; childNodes = childNodes->
GetNext() )
2692 for( ; level1Node; level1Node = level1Node->
GetNext() )
2694 for( wxString childNodeName : aSubNodeChildrenToCount )
2696 if( level1Node->GetName() == childNodeName )
2709 wxString escapedText = aCadstarString;
2711 escapedText.Replace( wxT(
"'" ), wxT(
"~" ) );
2719 if( !aKiCadTextItem->
GetText().IsEmpty() )
2730 positionOffset.
y = -positionOffset.
y;
2735 int numExtraLines =
text.Replace(
"\n",
"\n" );
2736 numExtraLines -=
text.at(
text.size() - 1 ) ==
'\n';
2737 positionOffset.
x *= numExtraLines;
2738 positionOffset.
y *= numExtraLines;
2740 aKiCadTextItem->
Offset( positionOffset );
KICAD_PLUGIN_EXPORT SCENEGRAPH * Load(char const *aFileName)
reads a model file and creates a generic display structure
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 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)
Corrects 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 cancelled.
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 base class for most all the KiCad significant classes used in schematics and boards.
KICAD_T Type() const
Returns the type of object.
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.
int GetInterline() const
Return the distance between two lines of text.
void Offset(const VECTOR2I &aOffset)
A progress reporter interface for use in multi-threaded environments.
virtual bool KeepRefreshing(bool aWait=false)=0
Update the UI (if any).
virtual void AdvanceProgress()=0
Increment the progress bar length (inside the current virtual zone).
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.
Represent a set of closed polygons.
int AddOutline(const SHAPE_LINE_CHAIN &aOutline)
Adds a new hole to the given outline (default: last) and returns its index.
int AddHole(const SHAPE_LINE_CHAIN &aHole, int aOutline=-1)
Return the area of this poly set.
Hold an XML or S-expression element.
XNODE * GetParent() const
XNODE * GetChildren() const
#define THROW_IO_ERROR(msg)
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 ...
PARSE_RESULT Parse(const std::string &aString, NOTATION aNotation=NOTATION::SI, SIM_VALUE::TYPE aValueType=SIM_VALUE::TYPE_FLOAT)
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Output a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
wxString ConvertToNewOverbarNotation(const wxString &aOldStr)
Convert the old ~...~ overbar notation to the new ~{...} one.
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
void ParseIdentifiers(XNODE *aNode, PARSER_CONTEXT *aContext)
virtual void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
bool ParseSubNode(XNODE *aChildNode, PARSER_CONTEXT *aContext)
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
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...
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
bool ParseSubNode(XNODE *aChildNode, PARSER_CONTEXT *aContext)
Represents a cutout in a closed shape (e.g.
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
Represents a floating value in E notation.
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
static bool IsGrid(XNODE *aNode)
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
void ParseIdentifiers(XNODE *aNode, PARSER_CONTEXT *aContext)
bool ParseSubNode(XNODE *aChildNode, PARSER_CONTEXT *aContext)
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".
bool ParseSubNode(XNODE *aChildNode, PARSER_CONTEXT *aContext)
void ParseIdentifiers(XNODE *aNode, PARSER_CONTEXT *aContext)
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
< "GATEDEFINITION" node name
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
GATE_ID ID
Usually "A", "B", "C", etc.
< "PINEQUIVALENCE" Node name
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
< "PARTDEFINITIONPIN" node name
POSITION
Positioning of pin names can be in one of four quadrants.
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
< "SWAPGATE" Node name (represents an "Element")
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
static PIN_TYPE GetPinType(XNODE *aNode)
Represents a point in x,y coordinates.
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
bool IsEmpty()
Determines if this is empty (i.e. no design reuse associated)
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
virtual void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
bool ParseSubNode(XNODE *aChildNode, PARSER_CONTEXT *aContext)
SHAPE_POLY_SET ConvertToPolySet(const std::function< VECTOR2I(const VECTOR2I &)> aCadstarToKicadPointCallback, double aAccuracy) const
SHAPE_LINE_CHAIN OutlineAsChain(const std::function< VECTOR2I(const VECTOR2I &)> aCadstarToKicadPointCallback, double aAccuracy) const
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
static bool IsShape(XNODE *aNode)
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
bool ParseSubNode(XNODE *aChildNode, PARSER_CONTEXT *aContext)
void ParseIdentifiers(XNODE *aNode, PARSER_CONTEXT *aContext)
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
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
< Nodename = "VARIANT" or "VMASTER" (master variant
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
Represents a vertex in a shape.
static bool IsVertex(XNODE *aNode)
void AppendToChain(SHAPE_LINE_CHAIN *aChainToAppendTo, const std::function< VECTOR2I(const VECTOR2I &)> aCadstarToKicadPointCallback, double aAccuracy) const
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
Hold a keyword string and its unique integer token.
void RotatePoint(int *pX, int *pY, const EDA_ANGLE &aAngle)