KiCad PCB EDA Suite
Loading...
Searching...
No Matches
cadstar_pcb_archive_parser.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright (C) 2020 Roberto Fernandez Bautista <[email protected]>
5 * Copyright (C) 2020-2023 KiCad Developers, see AUTHORS.txt for contributors.
6 *
7 * This program is free software: you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation, either version 3 of the License, or (at your
10 * option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20
26#include <base_units.h>
28#include <macros.h>
29#include <progress_reporter.h>
30#include <wx/translation.h>
31
32
34{
36 m_progressReporter->BeginPhase( 0 ); // Read file
37
38 m_rootNode = LoadArchiveFile( Filename, wxT( "CADSTARPCB" ), m_progressReporter );
39
41 {
42 m_progressReporter->BeginPhase( 1 ); // Parse File
43
44 std::vector<wxString> subNodeChildrenToCount = { wxT( "LIBRARY" ), wxT( "PARTS" ),
45 wxT( "LAYOUT" ) };
46
47 long numOfSteps = GetNumberOfStepsForReporting( m_rootNode, subNodeChildrenToCount );
49 }
50
52
53 XNODE* cNode = m_rootNode->GetChildren();
54
55 if( !cNode )
56 THROW_MISSING_NODE_IO_ERROR( wxT( "HEADER" ), wxT( "CADSTARPCB" ) );
57
58 for( ; cNode; cNode = cNode->GetNext() )
59 {
60 if( cNode->GetName() == wxT( "HEADER" ) )
61 {
62 Header.Parse( cNode, &m_context );
63
64 switch( Header.Resolution )
65 {
68 break;
69
70 default:
71 wxASSERT_MSG( true, wxT( "Unknown File Resolution" ) );
72 break;
73 }
74
75 if( aLibrary && Header.Format.Type != wxT( "LIBRARY" ) )
76 {
77 THROW_IO_ERROR( wxT( "The selected file is not a valid CADSTAR library file." ) );
78 }
79 else if( !aLibrary && Header.Format.Type != wxT( "LAYOUT" ) )
80 {
81 if( Header.Format.Type == wxT( "LIBRARY" ) )
82 {
84 wxT( "The selected file is a CADSTAR library file (as opposed "
85 "to a layout file). You can import this library by adding it "
86 "to the library table." ) );
87 }
88 else
89 {
90 THROW_IO_ERROR( wxT( "The selected file is an unknown CADSTAR format so "
91 "cannot be imported into KiCad." ) );
92 }
93 }
94 }
95 else if( cNode->GetName() == wxT( "ASSIGNMENTS" ) )
96 {
97 Assignments.Parse( cNode, &m_context );
98 }
99 else if( cNode->GetName() == wxT( "LIBRARY" ) )
100 {
101 Library.Parse( cNode, &m_context );
102 }
103 else if( cNode->GetName() == wxT( "DEFAULTS" ) )
104 {
105 // No design information here (no need to parse)
106 // Only contains CADSTAR configuration data such as default shapes, text and units
107 // In future some of this could be converted to KiCad but limited value
108 }
109 else if( cNode->GetName() == wxT( "PARTS" ) )
110 {
111 Parts.Parse( cNode, &m_context );
112 }
113 else if( cNode->GetName() == wxT( "LAYOUT" ) )
114 {
115 Layout.Parse( cNode, &m_context );
116 }
117 else if( cNode->GetName() == wxT( "DISPLAY" ) )
118 {
119 // No design information here (no need to parse)
120 // Contains CADSTAR Display settings such as layer/element colours and visibility.
121 // In the future these settings could be converted to KiCad
122 }
123 else
124 {
125 THROW_UNKNOWN_NODE_IO_ERROR( cNode->GetName(), wxT( "[root]" ) );
126 }
127
128 checkPoint();
129 }
130
131 delete m_rootNode;
132 m_rootNode = nullptr;
133}
134
135
137{
138 wxASSERT( aNode->GetName() == wxT( "ASSIGNMENTS" ) );
139
140 XNODE* cNode = aNode->GetChildren();
141
142 if( !cNode )
143 THROW_MISSING_NODE_IO_ERROR( wxT( "TECHNOLOGY" ), wxT( "ASSIGNMENTS" ) );
144
145 for( ; cNode; cNode = cNode->GetNext() )
146 {
147 if( cNode->GetName() == wxT( "LAYERDEFS" ) )
148 Layerdefs.Parse( cNode, aContext );
149 else if( cNode->GetName() == wxT( "CODEDEFS" ) )
150 Codedefs.Parse( cNode, aContext );
151 else if( cNode->GetName() == wxT( "TECHNOLOGY" ) )
152 Technology.Parse( cNode, aContext );
153 else if( cNode->GetName() == wxT( "GRIDS" ) )
154 Grids.Parse( cNode, aContext );
155 else if( cNode->GetName() == wxT( "NETCLASSEDITATTRIBSETTINGS" ) )
157 else if( cNode->GetName() == wxT( "SPCCLASSEDITATTRIBSETTINGS" ) )
159 else
160 THROW_UNKNOWN_NODE_IO_ERROR( cNode->GetName(), aNode->GetName() );
161 }
162}
163
164
166{
167 wxASSERT( aNode->GetName() == wxT( "LAYERDEFS" ) );
168
169 wxXmlAttribute* xmlAttribute = nullptr;
170
171 XNODE* cNode = aNode->GetChildren();
172
173 if( !cNode )
174 THROW_MISSING_PARAMETER_IO_ERROR( wxT( "LAYERSTACK" ), wxT( "LAYERDEFS" ) );
175
176 for( ; cNode; cNode = cNode->GetNext() )
177 {
178 wxString nodeName = cNode->GetName();
179
180 if( nodeName == wxT( "LAYERSTACK" ) )
181 {
182 xmlAttribute = cNode->GetAttributes();
183
184 for( ; xmlAttribute; xmlAttribute = xmlAttribute->GetNext() )
185 {
186 if( !IsValidAttribute( xmlAttribute ) )
187 continue;
188 else
189 LayerStack.push_back( (LAYER_ID) xmlAttribute->GetValue() );
190 }
191
192 CheckNoChildNodes( cNode );
193 }
194 else if( nodeName == wxT( "MATERIAL" ) )
195 {
196 MATERIAL material;
197 material.Parse( cNode, aContext );
198 Materials.insert( std::make_pair( material.ID, material ) );
199 }
200 else if( nodeName == wxT( "LAYER" ) )
201 {
202 LAYER layer;
203 layer.Parse( cNode, aContext );
204 Layers.insert( std::make_pair( layer.ID, layer ) );
205 }
206 else if( nodeName == wxT( "SWAPPAIR" ) )
207 {
208 LAYER_ID layerId = (LAYER_ID) GetXmlAttributeIDString( cNode, 0 );
209 LAYER_ID swapLayerId = (LAYER_ID) GetXmlAttributeIDString( cNode, 1 );
210
211 Layers[layerId].SwapLayerID = swapLayerId;
212 }
213 else
214 {
215 THROW_UNKNOWN_NODE_IO_ERROR( nodeName, aNode->GetName() );
216 }
217 }
218}
219
220
222{
223 wxASSERT( aNode->GetName() == wxT( "RULESET" ) );
224
225 ID = GetXmlAttributeIDString( aNode, 0 );
226 Name = GetXmlAttributeIDString( aNode, 1 );
227
228 XNODE* cNode = aNode->GetChildren();
229
230 for( ; cNode; cNode = cNode->GetNext() )
231 {
232 wxString nodeName = cNode->GetName();
233
234 if( nodeName == wxT( "ROUCODEREF" ) )
235 {
236 AreaRouteCodeID = GetXmlAttributeIDString( cNode, 0 );
237 }
238 else if( nodeName == wxT( "VIACODEREF" ) )
239 {
240 AreaViaCodeID = GetXmlAttributeIDString( cNode, 0 );
241 }
242 else if( nodeName == wxT( "SPACINGCODE" ) )
243 {
244 SPACINGCODE spacingcode;
245 spacingcode.Parse( cNode, aContext );
246 SpacingCodes.insert( std::make_pair( spacingcode.ID, spacingcode ) );
247 }
248 else
249 {
250 THROW_UNKNOWN_NODE_IO_ERROR( nodeName, aNode->GetName() );
251 }
252 }
253}
254
255
257{
258 wxASSERT( aNode->GetName() == wxT( "CODEDEFS" ) );
259
260 XNODE* cNode = aNode->GetChildren();
261
262 for( ; cNode; cNode = cNode->GetNext() )
263 {
264 wxString nodeName = cNode->GetName();
265
266 if( ParseSubNode( cNode, aContext ) ) // in CADSTAR_ARCHIVE_PARSER::CODEDEFS
267 {
268 }
269 else if( nodeName == wxT( "COPPERCODE" ) )
270 {
271 COPPERCODE coppercode;
272 coppercode.Parse( cNode, aContext );
273 CopperCodes.insert( std::make_pair( coppercode.ID, coppercode ) );
274 }
275 else if( nodeName == wxT( "SPACINGCODE" ) )
276 {
277 SPACINGCODE spacingcode;
278 spacingcode.Parse( cNode, aContext );
279 SpacingCodes.insert( std::make_pair( spacingcode.ID, spacingcode ) );
280 }
281 else if( nodeName == wxT( "RULESET" ) )
282 {
283 RULESET ruleset;
284 ruleset.Parse( cNode, aContext );
285 Rulesets.insert( std::make_pair( ruleset.ID, ruleset ) );
286 }
287 else if( nodeName == wxT( "PADCODE" ) )
288 {
289 PADCODE padcode;
290 padcode.Parse( cNode, aContext );
291 PadCodes.insert( std::make_pair( padcode.ID, padcode ) );
292 }
293 else if( nodeName == wxT( "VIACODE" ) )
294 {
295 VIACODE viacode;
296 viacode.Parse( cNode, aContext );
297 ViaCodes.insert( std::make_pair( viacode.ID, viacode ) );
298 }
299 else if( nodeName == wxT( "LAYERPAIR" ) )
300 {
301 LAYERPAIR layerpair;
302 layerpair.Parse( cNode, aContext );
303 LayerPairs.insert( std::make_pair( layerpair.ID, layerpair ) );
304 }
305 else if( nodeName == wxT( "SPCCLASSSPACE" ) )
306 {
307 SPCCLASSSPACE spcclassspace;
308 spcclassspace.Parse( cNode, aContext );
309 SpacingClasses.push_back( spcclassspace );
310 }
311 else
312 {
313 THROW_UNKNOWN_NODE_IO_ERROR( nodeName, aNode->GetName() );
314 }
315 }
316}
317
318
320{
321 wxASSERT( aNode->GetName() == wxT( "MATERIAL" ) );
322
323 ID = GetXmlAttributeIDString( aNode, 0 );
324 Name = GetXmlAttributeIDString( aNode, 1 );
325
326 wxString sType = GetXmlAttributeIDString( aNode, 2 );
327
328 if( sType == wxT( "CONSTRUCTION" ) )
329 {
331 }
332 else if( sType == wxT( "ELECTRICAL" ) )
333 {
335 }
336 else if( sType == wxT( "NONELEC" ) )
337 {
339 }
340 else
341 {
342 THROW_UNKNOWN_PARAMETER_IO_ERROR( sType, wxString::Format( wxT( "MATERIAL %s" ), Name ) );
343 }
344
345 XNODE* iNode = aNode->GetChildren();
346
347 if( !iNode )
348 {
349 THROW_MISSING_PARAMETER_IO_ERROR( wxT( "RESISTIVITY" ),
350 wxString::Format( wxT( "MATERIAL %s" ), Name ) );
351 }
352
353 for( ; iNode; iNode = iNode->GetNext() )
354 {
355 wxString nodeName = iNode->GetName();
356
357 if( nodeName == wxT( "RELPERMIT" ) )
358 {
359 ParseChildEValue( iNode, aContext, Permittivity );
360 }
361 else if( nodeName == wxT( "LOSSTANGENT" ) )
362 {
363 ParseChildEValue( iNode, aContext, LossTangent );
364 }
365 else if( nodeName == wxT( "RESISTIVITY" ) )
366 {
367 ParseChildEValue( iNode, aContext, Resistivity );
368 }
369 else
370 {
371 THROW_UNKNOWN_NODE_IO_ERROR( nodeName, wxString::Format( wxT( "MATERIAL %s" ), Name ) );
372 }
373 }
374}
375
376
378{
379 wxASSERT( aNode->GetName() == wxT( "LAYER" ) );
380
381 ID = GetXmlAttributeIDString( aNode, 0 );
382 Name = GetXmlAttributeIDString( aNode, 1 );
383
384 XNODE* cNode = aNode->GetChildren();
385 auto processLayerMaterialDetails = [&]() {
386 XNODE* tempNode = cNode->GetChildren();
387 for( ; tempNode; tempNode = tempNode->GetNext() )
388 {
389 wxString tempNodeName = tempNode->GetName();
390
391 if( tempNodeName == wxT( "MAKE" ) || tempNodeName == wxT( "LAYERHEIGHT" ) )
392 {
393 if( tempNodeName == wxT( "LAYERHEIGHT" ) )
394 {
395 Thickness = GetXmlAttributeIDLong( tempNode, 0 );
396 }
397 else
398 {
399 MaterialId = GetXmlAttributeIDString( tempNode, 0 );
400 Thickness = GetXmlAttributeIDLong( tempNode, 1 );
401 }
402
403 XNODE* childOfTempNode = tempNode->GetChildren();
404
405 if( childOfTempNode )
406 {
407 if( childOfTempNode->GetName() == wxT( "EMBEDS" ) )
408 {
409 wxString embedsValue = GetXmlAttributeIDString( childOfTempNode, 0 );
410
411 if( embedsValue == wxT( "UPWARDS" ) )
412 {
413 Embedding = EMBEDDING::ABOVE;
414 }
415 else if( embedsValue == wxT( "DOWNWARDS" ) )
416 {
417 Embedding = EMBEDDING::BELOW;
418 }
419 else
420 {
422 wxString::Format( wxT( "LAYER %s -> EMBEDS" ),
423 Name ) );
424 }
425 }
426 else
427 {
428 THROW_UNKNOWN_NODE_IO_ERROR( childOfTempNode->GetName(),
429 wxString::Format( wxT( "LAYER %s->MAKE" ),
430 Name ) );
431 }
432 }
433 }
434 else if( tempNodeName == wxT( "BIAS" ) )
435 {
436 wxString bias = GetXmlAttributeIDString( tempNode, 0 );
437
438 if( bias == wxT( "X_BIASED" ) )
439 {
440 RoutingBias = ROUTING_BIAS::X;
441 }
442 else if( bias == wxT( "Y_BIASED" ) )
443 {
444 RoutingBias = ROUTING_BIAS::Y;
445 }
446 else if( bias == wxT( "ANTITRACK" ) )
447 {
448 RoutingBias = ROUTING_BIAS::ANTI_ROUTE;
449 }
450 else if( bias == wxT( "OBSTACLE" ) )
451 {
452 RoutingBias = ROUTING_BIAS::OBSTACLE;
453 }
454 else if( bias == wxT( "UNBIASED" ) )
455 {
456 RoutingBias = ROUTING_BIAS::UNBIASED;
457 }
458 else
459 {
461 wxString::Format( wxT( "LAYER %s -> BIAS" ),
462 Name ) );
463 }
464 }
465 else
466 {
467 THROW_UNKNOWN_NODE_IO_ERROR( tempNodeName, wxString::Format( wxT( "LAYER %s" ),
468 Name ) );
469 }
470 }
471 };
472
473 for( ; cNode; cNode = cNode->GetNext() )
474 {
475 wxString cNodeName = cNode->GetName();
476
477 if( cNodeName == wxT( "ALLDOC" ) )
478 {
479 Type = LAYER_TYPE::ALLDOC;
480 }
481 else if( cNodeName == wxT( "ALLELEC" ) )
482 {
483 Type = LAYER_TYPE::ALLELEC;
484 }
485 else if( cNodeName == wxT( "ALLLAYER" ) )
486 {
488 }
489 else if( cNodeName == wxT( "ASSCOMPCOPP" ) )
490 {
492 }
493 else if( cNodeName == wxT( "JUMPERLAYER" ) )
494 {
496 }
497 else if( cNodeName == wxT( "NOLAYER" ) )
498 {
499 Type = LAYER_TYPE::NOLAYER;
500 }
501 else if( cNodeName == wxT( "POWER" ) )
502 {
503 Type = LAYER_TYPE::POWER;
504 PhysicalLayer = GetXmlAttributeIDLong( cNode, 0 );
505 processLayerMaterialDetails();
506 }
507 else if( cNodeName == wxT( "DOC" ) )
508 {
509 Type = LAYER_TYPE::DOC;
510 }
511 else if( cNodeName == wxT( "CONSTRUCTION" ) )
512 {
514 processLayerMaterialDetails();
515 }
516 else if( cNodeName == wxT( "ELEC" ) )
517 {
518 Type = LAYER_TYPE::ELEC;
519 PhysicalLayer = GetXmlAttributeIDLong( cNode, 0 );
520 processLayerMaterialDetails();
521 }
522 else if( cNodeName == wxT( "NONELEC" ) )
523 {
524 Type = LAYER_TYPE::NONELEC;
525 PhysicalLayer = GetXmlAttributeIDLong( cNode, 0 );
526 processLayerMaterialDetails();
527 }
528 else if( cNodeName == wxT( "DESCRIPTION" ) )
529 {
530 Description = GetXmlAttributeIDString( cNode, 0 );
531 }
532 else if( cNodeName == wxT( "REFPLANE" ) )
533 {
534 ReferencePlane = true;
535 }
536 else if( cNodeName == wxT( "VLAYER" ) )
537 {
538 VariantLayer = true;
539 }
540 else if( cNodeName == wxT( "LASUBTYP" ) )
541 {
542 //Process subtype
543 wxString sSubType = GetXmlAttributeIDString( cNode, 0 );
544
545 if( sSubType == wxT( "LAYERSUBTYPE_ASSEMBLY" ) )
546 {
548 }
549 else if( sSubType == wxT( "LAYERSUBTYPE_PASTE" ) )
550 {
551 this->SubType = LAYER_SUBTYPE::LAYERSUBTYPE_PASTE;
552 }
553 else if( sSubType == wxT( "LAYERSUBTYPE_PLACEMENT" ) )
554 {
556 }
557 else if( sSubType == wxT( "LAYERSUBTYPE_SILKSCREEN" ) )
558 {
560 }
561 else if( sSubType == wxT( "LAYERSUBTYPE_SOLDERRESIST" ) )
562 {
564 }
565 else if( sSubType == wxT( "LAYERSUBTYPE_CLEARANCE" ) )
566 {
568 }
569 else if( sSubType == wxT( "LAYERSUBTYPE_ROUT" ) )
570 {
571 this->SubType = LAYER_SUBTYPE::LAYERSUBTYPE_ROUT;
572 }
573 else
574 {
575 THROW_UNKNOWN_PARAMETER_IO_ERROR( sSubType, wxString::Format( wxT( "LAYER %s %s" ),
576 Name, cNodeName ) );
577 }
578 }
579 else
580 {
581 THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, wxString::Format( wxT( "LAYER %s" ), Name ) );
582 }
583 }
584}
585
586
588{
589 wxASSERT( aNode->GetName() == wxT( "COPREASSIGN" ) );
590
591 LayerID = GetXmlAttributeIDString( aNode, 0 );
592
593 CopperWidth = GetXmlAttributeIDLong( aNode, 1 );
594}
595
596
598{
599 wxASSERT( aNode->GetName() == wxT( "COPPERCODE" ) );
600
601 ID = GetXmlAttributeIDString( aNode, 0 );
602 Name = GetXmlAttributeIDString( aNode, 1 );
603
604 CopperWidth = GetXmlAttributeIDLong( aNode, 2 );
605
606 XNODE* cNode = aNode->GetChildren();
607
608 for( ; cNode; cNode = cNode->GetNext() )
609 {
610 if( cNode->GetName() == wxT( "COPREASSIGN" ) )
611 {
613 reassign.Parse( cNode, aContext );
614 Reassigns.push_back( reassign );
615 }
616 else
617 {
618 THROW_UNKNOWN_NODE_IO_ERROR( cNode->GetName(), aNode->GetName() );
619 }
620 }
621}
622
623
625 PARSER_CONTEXT* aContext )
626{
627 wxASSERT( aNode->GetName() == wxT( "SPACEREASSIGN" ) );
628
629 LayerID = GetXmlAttributeIDString( aNode, 0 );
630 Spacing = GetXmlAttributeIDLong( aNode, 1 );
631
632 CheckNoChildNodes( aNode );
633}
634
635
637{
638 wxASSERT( aNode->GetName() == wxT( "SPACINGCODE" ) );
639
640 ID = GetXmlAttributeIDString( aNode, 0 );
641 Spacing = GetXmlAttributeIDLong( aNode, 1 );
642
643 XNODE* cNode = aNode->GetChildren();
644
645 for( ; cNode; cNode = cNode->GetNext() )
646 {
647 wxString cNodeName = cNode->GetName();
648
649 if( cNodeName == wxT( "SPACEREASSIGN" ) )
650 {
651 REASSIGN reassign;
652 reassign.Parse( cNode, aContext );
653 Reassigns.push_back( reassign );
654 }
655 else
656 {
657 THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, aNode->GetName() );
658 }
659 }
660}
661
662
664{
665 wxString aNodeName = aNode->GetName();
666
667 if( aNodeName == wxT( "ANNULUS" ) || aNodeName == wxT( "BULLET" ) || aNodeName == wxT( "ROUND" )
668 || aNodeName == wxT( "DIAMOND" ) || aNodeName == wxT( "FINGER" )
669 || aNodeName == wxT( "OCTAGON" ) || aNodeName == wxT( "RECTANGLE" )
670 || aNodeName == wxT( "ROUNDED" ) || aNodeName == wxT( "SQUARE" ) )
671 {
672 return true;
673 }
674 else
675 {
676 return false;
677 }
678}
679
680
682{
683 wxASSERT( IsPadShape( aNode ) );
684
685 wxString aNodeName = aNode->GetName();
686
687 if( aNodeName == wxT( "ANNULUS" ) )
688 ShapeType = PAD_SHAPE_TYPE::ANNULUS;
689 else if( aNodeName == wxT( "BULLET" ) )
690 ShapeType = PAD_SHAPE_TYPE::BULLET;
691 else if( aNodeName == wxT( "ROUND" ) )
692 ShapeType = PAD_SHAPE_TYPE::CIRCLE;
693 else if( aNodeName == wxT( "DIAMOND" ) )
694 ShapeType = PAD_SHAPE_TYPE::DIAMOND;
695 else if( aNodeName == wxT( "FINGER" ) )
696 ShapeType = PAD_SHAPE_TYPE::FINGER;
697 else if( aNodeName == wxT( "OCTAGON" ) )
698 ShapeType = PAD_SHAPE_TYPE::OCTAGON;
699 else if( aNodeName == wxT( "RECTANGLE" ) )
700 ShapeType = PAD_SHAPE_TYPE::RECTANGLE;
701 else if( aNodeName == wxT( "ROUNDED" ) )
703 else if( aNodeName == wxT( "SQUARE" ) )
704 ShapeType = PAD_SHAPE_TYPE::SQUARE;
705 else
706 wxASSERT( true );
707
708 switch( ShapeType )
709 {
711 Size = GetXmlAttributeIDLong( aNode, 0 );
712 InternalFeature = GetXmlAttributeIDLong( aNode, 1 );
713 break;
714
716 InternalFeature = GetXmlAttributeIDLong( aNode, 3 );
718
722 RightLength = GetXmlAttributeIDLong( aNode, 2 );
723 LeftLength = GetXmlAttributeIDLong( aNode, 1 );
725
729
730 if( aNode->GetChildren() )
731 {
732 if( aNode->GetChildren()->GetName() == wxT( "ORIENT" ) )
733 {
734 OrientAngle = GetXmlAttributeIDLong( aNode->GetChildren(), 0 );
735 }
736 else
737 {
738 THROW_UNKNOWN_NODE_IO_ERROR( aNode->GetChildren()->GetName(), aNode->GetName() );
739 }
740
741 CheckNoNextNodes( aNode->GetChildren() );
742 }
744
746 Size = GetXmlAttributeIDLong( aNode, 0 );
747 break;
748 }
749}
750
751
753{
754 wxASSERT( aNode->GetName() == wxT( "PADREASSIGN" ) );
755
756 LayerID = GetXmlAttributeIDString( aNode, 0 );
757
759 Shape.Parse( aNode->GetChildren(), aContext );
760 else
761 THROW_UNKNOWN_NODE_IO_ERROR( aNode->GetChildren()->GetName(), aNode->GetName() );
762
763 CheckNoNextNodes( aNode->GetChildren() );
764}
765
766
768{
769 wxASSERT( aNode->GetName() == wxT( "PADCODE" ) );
770
771 ID = GetXmlAttributeIDString( aNode, 0 );
772 Name = GetXmlAttributeIDString( aNode, 1 );
773
774 XNODE* cNode = aNode->GetChildren();
775 wxString location = wxString::Format( wxT( "PADCODE -> %s" ), Name );
776
777 for( ; cNode; cNode = cNode->GetNext() )
778 {
779 wxString cNodeName = cNode->GetName();
780
781 if( CADSTAR_PAD_SHAPE::IsPadShape( cNode ) )
782 {
783 Shape.Parse( cNode, aContext );
784 }
785 else if( cNodeName == wxT( "CLEARANCE" ) )
786 {
787 ReliefClearance = GetXmlAttributeIDLong( cNode, 0 );
788 }
789 else if( cNodeName == wxT( "RELIEFWIDTH" ) )
790 {
791 ReliefWidth = GetXmlAttributeIDLong( cNode, 0 );
792 }
793 else if( cNodeName == wxT( "DRILL" ) )
794 {
795 DrillDiameter = GetXmlAttributeIDLong( cNode, 0 );
796 XNODE* subNode = cNode->GetChildren();
797
798 for( ; subNode; subNode = subNode->GetNext() )
799 {
800 wxString subNodeName = subNode->GetName();
801
802 if( subNodeName == wxT( "NONPLATED" ) )
803 Plated = false;
804 else if( subNodeName == wxT( "OVERSIZE" ) )
805 DrillOversize = GetXmlAttributeIDLong( subNode, 0 );
806 else
807 THROW_UNKNOWN_NODE_IO_ERROR( subNode->GetName(), location );
808 }
809 }
810 else if( cNodeName == wxT( "DRILLLENGTH" ) )
811 {
812 SlotLength = GetXmlAttributeIDLong( cNode, 0 );
813 }
814 else if( cNodeName == wxT( "DRILLORIENTATION" ) )
815 {
816 SlotOrientation = GetXmlAttributeIDLong( cNode, 0 );
817 }
818 else if( cNodeName == wxT( "DRILLXOFFSET" ) )
819 {
820 DrillXoffset = GetXmlAttributeIDLong( cNode, 0 );
821 }
822 else if( cNodeName == wxT( "DRILLYOFFSET" ) )
823 {
824 DrillYoffset = GetXmlAttributeIDLong( cNode, 0 );
825 }
826 else if( cNodeName == wxT( "PADREASSIGN" ) )
827 {
828 PADREASSIGN reassign;
829 reassign.Parse( cNode, aContext );
830 Reassigns.insert( std::make_pair( reassign.LayerID, reassign.Shape ) );
831 }
832 else
833 {
834 THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, location );
835 }
836 }
837}
838
839
841{
842 wxASSERT( aNode->GetName() == wxT( "VIAREASSIGN" ) );
843
844 LayerID = GetXmlAttributeIDString( aNode, 0 );
845
847 Shape.Parse( aNode->GetChildren(), aContext );
848 else
849 THROW_UNKNOWN_NODE_IO_ERROR( aNode->GetChildren()->GetName(), aNode->GetName() );
850
851 CheckNoNextNodes( aNode->GetChildren() );
852}
853
854
856{
857 wxASSERT( aNode->GetName() == wxT( "VIACODE" ) );
858
859 ID = GetXmlAttributeIDString( aNode, 0 );
860 Name = GetXmlAttributeIDString( aNode, 1 );
861
862 XNODE* cNode = aNode->GetChildren();
863 wxString location = wxString::Format( wxT( "VIACODE -> %s" ), Name );
864
865 for( ; cNode; cNode = cNode->GetNext() )
866 {
867 wxString cNodeName = cNode->GetName();
868
869 if( CADSTAR_PAD_SHAPE::IsPadShape( cNode ) )
870 {
871 Shape.Parse( cNode, aContext );
872 }
873 else if( cNodeName == wxT( "CLEARANCE" ) )
874 {
875 ReliefClearance = GetXmlAttributeIDLong( cNode, 0 );
876 }
877 else if( cNodeName == wxT( "RELIEFWIDTH" ) )
878 {
879 ReliefWidth = GetXmlAttributeIDLong( cNode, 0 );
880 }
881 else if( cNodeName == wxT( "DRILL" ) )
882 {
883 DrillDiameter = GetXmlAttributeIDLong( cNode, 0 );
884 XNODE* subNode = cNode->GetChildren();
885
886 for( ; subNode; subNode = subNode->GetNext() )
887 {
888 wxString subNodeName = subNode->GetName();
889
890 if( subNodeName == wxT( "OVERSIZE" ) )
891 DrillOversize = GetXmlAttributeIDLong( subNode, 0 );
892 else
893 THROW_UNKNOWN_NODE_IO_ERROR( subNode->GetName(), location );
894 }
895 }
896 else if( cNodeName == wxT( "VIAREASSIGN" ) )
897 {
898 VIAREASSIGN reassign;
899 reassign.Parse( cNode, aContext );
900 Reassigns.insert( std::make_pair( reassign.LayerID, reassign.Shape ) );
901 }
902 else
903 {
904 THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, location );
905 }
906 }
907}
908
909
911{
912 wxASSERT( aNode->GetName() == wxT( "LAYERPAIR" ) );
913
914 ID = GetXmlAttributeIDString( aNode, 0 );
915 Name = GetXmlAttributeIDString( aNode, 1 );
916
917 PhysicalLayerStart = GetXmlAttributeIDLong( aNode, 2 );
918 PhysicalLayerEnd = GetXmlAttributeIDLong( aNode, 3 );
919
920 wxString location = wxString::Format( wxT( "LAYERPAIR -> %s" ), Name );
921
922 if( aNode->GetChildren() )
923 {
924 if( aNode->GetChildren()->GetName() == wxT( "VIACODEREF" ) )
925 {
926 ViacodeID = GetXmlAttributeIDString( aNode->GetChildren(), 0 );
927 }
928 else
929 {
930 THROW_UNKNOWN_NODE_IO_ERROR( aNode->GetChildren()->GetName(), location );
931 }
932
933 CheckNoNextNodes( aNode->GetChildren() );
934 }
935}
936
937
939{
940 wxASSERT( aNode->GetName() == wxT( "SPCCLASSSPACE" ) );
941
942 SpacingClassID1 = GetXmlAttributeIDString( aNode, 0 );
943 SpacingClassID2 = GetXmlAttributeIDString( aNode, 1 );
944 LayerID = GetXmlAttributeIDString( aNode, 2 );
945 Spacing = GetXmlAttributeIDLong( aNode, 3 );
946}
947
948
950{
951 wxASSERT( aNode->GetName() == wxT( "TECHNOLOGY" ) );
952
953 XNODE* cNode = aNode->GetChildren();
954
955 for( ; cNode; cNode = cNode->GetNext() )
956 {
957 wxString cNodeName = cNode->GetName();
958
959 if( ParseSubNode( cNode, aContext ) ) //CADSTAR_ARCHIVE_PARSER::SETTINGS
960 {
961 }
962 else if( cNodeName == wxT( "MINROUTEWIDTH" ) )
963 {
964 MinRouteWidth = GetXmlAttributeIDLong( cNode, 0 );
965 }
966 else if( cNodeName == wxT( "MINNECKED" ) )
967 {
968 MinNeckedLength = GetXmlAttributeIDLong( cNode, 0 );
969 }
970 else if( cNodeName == wxT( "MINUNNECKED" ) )
971 {
972 MinUnneckedLength = GetXmlAttributeIDLong( cNode, 0 );
973 }
974 else if( cNodeName == wxT( "MINMITER" ) )
975 {
976 MinMitre = GetXmlAttributeIDLong( cNode, 0 );
977 }
978 else if( cNodeName == wxT( "MAXMITER" ) )
979 {
980 MaxMitre = GetXmlAttributeIDLong( cNode, 0 );
981 }
982 else if( cNodeName == wxT( "MAXPHYSLAYER" ) )
983 {
984 MaxPhysicalLayer = GetXmlAttributeIDLong( cNode, 0 );
985 }
986 else if( cNodeName == wxT( "TRACKGRID" ) )
987 {
988 TrackGrid = GetXmlAttributeIDLong( cNode, 0 );
989 }
990 else if( cNodeName == wxT( "VIAGRID" ) )
991 {
992 ViaGrid = GetXmlAttributeIDLong( cNode, 0 );
993 }
994 else if( cNodeName == wxT( "BACKOFFJCTS" ) )
995 {
996 BackOffJunctions = true;
997 }
998 else if( cNodeName == wxT( "BCKOFFWIDCHANGE" ) )
999 {
1000 BackOffWidthChange = true;
1001 }
1002 else
1003 {
1004 THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, wxT( "TECHNOLOGY" ) );
1005 }
1006 }
1007}
1008
1009
1011 const wxString& aPadSideString )
1012{
1013 if( aPadSideString == wxT( "THRU" ) )
1015 else if( aPadSideString == wxT( "BOTTOM" ) )
1016 return PAD_SIDE::MAXIMUM;
1017 else if( aPadSideString == wxT( "TOP" ) )
1018 return PAD_SIDE::MINIMUM;
1019 else
1020 return PAD_SIDE::THROUGH_HOLE; // Assume through hole as default
1021}
1022
1023
1025{
1026 wxASSERT( aNode->GetName() == wxT( "COMPCOPPER" ) );
1027
1028 CopperCodeID = GetXmlAttributeIDString( aNode, 0 );
1029 LayerID = GetXmlAttributeIDString( aNode, 1 );
1030
1031 XNODE* cNode = aNode->GetChildren();
1032 bool shapeIsInitialised = false; // Stop more than one Shape Object
1033 wxString location = wxT( "COMPCOPPER" );
1034
1035 if( !cNode )
1036 THROW_MISSING_NODE_IO_ERROR( wxT( "Shape" ), location );
1037
1038 for( ; cNode; cNode = cNode->GetNext() )
1039 {
1040 wxString cNodeName = cNode->GetName();
1041
1042 if( !shapeIsInitialised && Shape.IsShape( cNode ) )
1043 {
1044 Shape.Parse( cNode, aContext );
1045 shapeIsInitialised = true;
1046 }
1047 else if( cNodeName == wxT( "SWAPRULE" ) )
1048 {
1049 SwapRule = ParseSwapRule( cNode );
1050 }
1051 else if( cNodeName == wxT( "ASSOCPIN" ) )
1052 {
1053 wxXmlAttribute* xmlAttribute = cNode->GetAttributes();
1054
1055 for( ; xmlAttribute; xmlAttribute = xmlAttribute->GetNext() )
1056 {
1057 if( !IsValidAttribute( xmlAttribute ) )
1058 continue;
1059
1060 long padId;
1061
1062 if( !xmlAttribute->GetValue().ToLong( &padId ) )
1063 THROW_PARSING_IO_ERROR( wxT( "ASSOCPIN" ), location );
1064
1065 AssociatedPadIDs.push_back( (PAD_ID) padId );
1066 }
1067
1068 CheckNoChildNodes( cNode );
1069 }
1070 else
1071 {
1072 THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, location );
1073 }
1074 }
1075}
1076
1077
1079{
1080 wxASSERT( aNode->GetName() == wxT( "COMPAREA" ) );
1081
1082 ID = GetXmlAttributeIDString( aNode, 0 );
1083 LineCodeID = GetXmlAttributeIDString( aNode, 1 );
1084 LayerID = GetXmlAttributeIDString( aNode, 3 );
1085
1086 XNODE* cNode = aNode->GetChildren();
1087 bool shapeIsInitialised = false; // Stop more than one Shape Object
1088 wxString location = wxString::Format( wxT( "COMPAREA %s" ), ID );
1089
1090 if( !cNode )
1091 THROW_MISSING_NODE_IO_ERROR( wxT( "Shape" ), location );
1092
1093 for( ; cNode; cNode = cNode->GetNext() )
1094 {
1095 wxString cNodeName = cNode->GetName();
1096
1097 if( !shapeIsInitialised && SHAPE::IsShape( cNode ) )
1098 {
1099 Shape.Parse( cNode, aContext );
1100 shapeIsInitialised = true;
1101 }
1102 else if( cNodeName == wxT( "SWAPRULE" ) )
1103 {
1104 SwapRule = ParseSwapRule( cNode );
1105 }
1106 else if( cNodeName == wxT( "USAGE" ) )
1107 {
1108 wxXmlAttribute* xmlAttribute = cNode->GetAttributes();
1109
1110 for( ; xmlAttribute; xmlAttribute = xmlAttribute->GetNext() )
1111 {
1112 if( !IsValidAttribute( xmlAttribute ) )
1113 continue;
1114
1115 if( xmlAttribute->GetValue() == wxT( "NO_TRACKS" ) )
1116 NoTracks = true;
1117 else if( xmlAttribute->GetValue() == wxT( "NO_VIAS" ) )
1118 NoVias = true;
1119 else
1120 THROW_UNKNOWN_PARAMETER_IO_ERROR( xmlAttribute->GetValue(), location );
1121 }
1122
1123 CheckNoChildNodes( cNode );
1124 }
1125 else
1126 {
1127 THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, location );
1128 }
1129 }
1130}
1131
1132
1134{
1135 wxASSERT( aNode->GetName() == wxT( "EXITS" ) );
1136
1137 wxXmlAttribute* xmlAttribute = aNode->GetAttributes();
1138
1139 for( ; xmlAttribute; xmlAttribute = xmlAttribute->GetNext() )
1140 {
1141 if( !IsValidAttribute( xmlAttribute ) )
1142 continue;
1143
1144 if( xmlAttribute->GetValue() == wxT( "FREE" ) )
1145 FreeAngle = true;
1146 else if( xmlAttribute->GetValue() == wxT( "N" ) )
1147 North = true;
1148 else if( xmlAttribute->GetValue() == wxT( "S" ) )
1149 South = true;
1150 else if( xmlAttribute->GetValue() == wxT( "E" ) )
1151 East = true;
1152 else if( xmlAttribute->GetValue() == wxT( "W" ) )
1153 West = true;
1154 else if( xmlAttribute->GetValue() == wxT( "NE" ) )
1155 NorthEast = true;
1156 else if( xmlAttribute->GetValue() == wxT( "NW" ) )
1157 NorthWest = true;
1158 else if( xmlAttribute->GetValue() == wxT( "SE" ) )
1159 SouthEast = true;
1160 else if( xmlAttribute->GetValue() == wxT( "SW" ) )
1161 SouthWest = true;
1162 else
1163 THROW_UNKNOWN_PARAMETER_IO_ERROR( xmlAttribute->GetValue(), wxT( "EXITS" ) );
1164 }
1165
1166 CheckNoChildNodes( aNode );
1167}
1168
1169
1171{
1172 wxASSERT( aNode->GetName() == wxT( "PAD" ) );
1173
1174 ID = GetXmlAttributeIDLong( aNode, 0 );
1175 PadCodeID = GetXmlAttributeIDString( aNode, 2 );
1176 Side = GetPadSide( GetXmlAttributeIDString( aNode, 3 ) );
1177
1178 XNODE* cNode = aNode->GetChildren();
1179 wxString location = wxString::Format( wxT( "PAD %ld" ), ID );
1180
1181 if( !cNode )
1182 THROW_MISSING_NODE_IO_ERROR( wxT( "PT" ), location );
1183
1184 for( ; cNode; cNode = cNode->GetNext() )
1185 {
1186 wxString cNodeName = cNode->GetName();
1187
1188 if( cNodeName == wxT( "ORIENT" ) )
1189 OrientAngle = GetXmlAttributeIDLong( cNode, 0 );
1190 else if( cNodeName == wxT( "FIRSTPAD" ) )
1191 FirstPad = true;
1192 else if( cNodeName == wxT( "EXITS" ) )
1193 Exits.Parse( cNode, aContext );
1194 else if( cNodeName == wxT( "PADIDENTIFIER" ) )
1195 Identifier = GetXmlAttributeIDString( cNode, 0 );
1196 else if( cNodeName == wxT( "PCBONLYPAD" ) )
1197 PCBonlyPad = true;
1198 else if( cNodeName == wxT( "PT" ) )
1199 Position.Parse( cNode, aContext );
1200 else
1201 THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, location );
1202 }
1203}
1204
1205
1207{
1208 wxASSERT( aNode->GetName() == wxT( "DIMARROW" ) );
1209 bool arrowStyleInitialised = false;
1210 bool upperAngleInitialised = false;
1211 bool lowerAngleInitialised = false;
1212
1213 ArrowLength = GetXmlAttributeIDLong( aNode, 3 );
1214
1215 XNODE* cNode = aNode->GetChildren();
1216
1217
1218 for( ; cNode; cNode = cNode->GetNext() )
1219 {
1220 wxString cNodeName = cNode->GetName();
1221
1222 if( cNodeName == wxT( "ARROWSTYLE" ) )
1223 {
1224 wxString arrowStyleStr = GetXmlAttributeIDString( cNode, 0 );
1225 arrowStyleInitialised = true;
1226
1227 if( arrowStyleStr == wxT( "DIMENSION_ARROWOPEN" ) )
1228 ArrowStyle = STYLE::OPEN;
1229 else if( arrowStyleStr == wxT( "DIMENSION_ARROWCLOSED" ) )
1230 ArrowStyle = STYLE::CLOSED;
1231 else if( arrowStyleStr == wxT( "DIMENSION_ARROWCLEAR" ) )
1232 ArrowStyle = STYLE::CLEAR;
1233 else if( arrowStyleStr == wxT( "DIMENSION_ARROWCLOSEDFILLED" ) )
1234 ArrowStyle = STYLE::CLOSED_FILLED;
1235 else
1236 THROW_UNKNOWN_PARAMETER_IO_ERROR( arrowStyleStr, cNodeName );
1237 }
1238 else if( cNodeName == wxT( "ARROWANGLEA" ) )
1239 {
1240 UpperAngle = GetXmlAttributeIDLong( cNode, 0 );
1241 upperAngleInitialised = true;
1242 }
1243 else if( cNodeName == wxT( "ARROWANGLEB" ) )
1244 {
1245 UpperAngle = GetXmlAttributeIDLong( cNode, 0 );
1246 lowerAngleInitialised = true;
1247 }
1248 else
1249 {
1250 THROW_UNKNOWN_PARAMETER_IO_ERROR( cNodeName, wxT( "DIMARROW" ) );
1251 }
1252 }
1253
1254 if( !arrowStyleInitialised )
1255 THROW_MISSING_PARAMETER_IO_ERROR( wxT( "ARROWSTYLE" ), wxT( "DIMARROW" ) );
1256
1257 if( !upperAngleInitialised )
1258 THROW_MISSING_PARAMETER_IO_ERROR( wxT( "ARROWANGLEA" ), wxT( "DIMARROW" ) );
1259
1260 if( !lowerAngleInitialised )
1261 THROW_MISSING_PARAMETER_IO_ERROR( wxT( "ARROWANGLEB" ), wxT( "DIMARROW" ) );
1262}
1263
1264
1266 PARSER_CONTEXT* aContext )
1267{
1268 wxASSERT( aNode->GetName() == wxT( "DIMTEXT" ) );
1269
1270 TextGap = GetXmlAttributeIDLong( aNode, 1 );
1271 TextOffset = GetXmlAttributeIDLong( aNode, 2 );
1272
1273 XNODE* cNode = aNode->GetChildren();
1274
1275 if( !cNode || cNode->GetName() != wxT( "TXTSTYLE" ) )
1276 THROW_UNKNOWN_NODE_IO_ERROR( cNode->GetName(), wxT( "DIMTEXT" ) );
1277
1278 wxString styleStr = GetXmlAttributeIDString( cNode, 0 );
1279
1280 if( styleStr == wxT( "DIMENSION_INTERNAL" ) )
1281 Style = STYLE::INSIDE;
1282 else if( styleStr == wxT( "DIMENSION_EXTERNAL" ) )
1283 Style = STYLE::OUTSIDE;
1284 else
1285 THROW_UNKNOWN_PARAMETER_IO_ERROR( styleStr, wxT( "TXTSTYLE" ) );
1286
1287 CheckNoNextNodes( cNode );
1288}
1289
1290
1292 PARSER_CONTEXT* aContext )
1293{
1294 wxASSERT( aNode->GetName() == wxT( "EXTLINE" ) );
1295
1296 LineCodeID = GetXmlAttributeIDString( aNode, 0 );
1297 Overshoot = GetXmlAttributeIDLong( aNode, 3 );
1298 Offset = GetXmlAttributeIDLong( aNode, 4 );
1299
1300 XNODE* cNode = aNode->GetChildren();
1301 int noOfPoints = 0;
1302
1303 for( ; cNode; cNode = cNode->GetNext() )
1304 {
1305 wxString cNodeName = cNode->GetName();
1306
1307 if( noOfPoints < 2 && cNodeName == wxT( "PT" ) )
1308 {
1309 ++noOfPoints;
1310
1311 if( noOfPoints == 1 )
1312 Start.Parse( cNode, aContext );
1313 else
1314 End.Parse( cNode, aContext );
1315 }
1316 else if( cNodeName == wxT( "SUPPRESSFIRST" ) )
1317 {
1318 SuppressFirst = true;
1319 }
1320 else
1321 {
1322 THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, wxT( "EXTLINE" ) );
1323 }
1324 }
1325
1326 if( noOfPoints != 2 )
1327 THROW_MISSING_PARAMETER_IO_ERROR( wxT( "PT" ), wxT( "EXTLINE" ) );
1328}
1329
1330
1332{
1333 if( aNode->GetName() == wxT( "LEADERLINE" ) || aNode->GetName() == wxT( "LINEARLINE" )
1334 || aNode->GetName() == wxT( "ANGULARLINE" ) )
1335 {
1336 return true;
1337 }
1338 else
1339 {
1340 return false;
1341 }
1342}
1343
1344
1346{
1347 wxASSERT( IsLine( aNode ) );
1348
1349 if( aNode->GetName() == wxT( "LINEARLINE" ) )
1350 Type = TYPE::LINEARLINE;
1351 else if( aNode->GetName() == wxT( "LEADERLINE" ) )
1352 Type = TYPE::LEADERLINE;
1353 else if( aNode->GetName() == wxT( "ANGULARLINE" ) )
1354 Type = TYPE::ANGULARLINE;
1355 else
1356 wxASSERT_MSG( true, wxT( "Not a valid type. What happened to the node Name?" ) );
1357
1358 LineCodeID = GetXmlAttributeIDString( aNode, 0 );
1359
1360 if( Type == TYPE::LEADERLINE )
1361 {
1362 LeaderLineLength = GetXmlAttributeIDLong( aNode, 5 );
1363 LeaderLineExtensionLength = GetXmlAttributeIDLong( aNode, 6 );
1364 }
1365
1366 XNODE* cNode = aNode->GetChildren();
1367 int noOfPoints = 0;
1368 int requiredNoOfPoints = 2;
1369
1370 if( Type == TYPE::ANGULARLINE )
1371 requiredNoOfPoints = 3;
1372
1373 for( ; cNode; cNode = cNode->GetNext() )
1374 {
1375 wxString cNodeName = cNode->GetName();
1376
1377 if( cNodeName == wxT( "DIMLINETYPE" ) )
1378 {
1379 wxString styleStr = GetXmlAttributeIDString( cNode, 0 );
1380
1381 if( styleStr == wxT( "DIMENSION_INTERNAL" ) )
1382 Style = STYLE::INTERNAL;
1383 else if( styleStr == wxT( "DIMENSION_EXTERNAL" ) )
1384 Style = STYLE::EXTERNAL;
1385 else
1386 THROW_UNKNOWN_PARAMETER_IO_ERROR( styleStr, cNodeName );
1387 }
1388 else if( noOfPoints < requiredNoOfPoints && cNodeName == wxT( "PT" ) )
1389 {
1390 ++noOfPoints;
1391
1392 if( noOfPoints == 1 )
1393 Start.Parse( cNode, aContext );
1394 else if( noOfPoints == 2 )
1395 End.Parse( cNode, aContext );
1396 else
1397 Centre.Parse( cNode, aContext );
1398 }
1399 else if( Type == TYPE::LEADERLINE && cNodeName == wxT( "LEADERANG" ) )
1400 {
1401 LeaderAngle = GetXmlAttributeIDLong( cNode, 0 );
1402 }
1403 else
1404 {
1405 THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, aNode->GetName() );
1406 }
1407 }
1408
1409 if( noOfPoints != requiredNoOfPoints )
1410 THROW_MISSING_PARAMETER_IO_ERROR( wxT( "PT" ), aNode->GetName() );
1411}
1412
1413
1415{
1416 if( aNode->GetName() == wxT( "LINEARDIM" ) || aNode->GetName() == wxT( "LEADERDIM" )
1417 || aNode->GetName() == wxT( "ANGLEDIM" ) )
1418 {
1419 return true;
1420 }
1421 else
1422 {
1423 return false;
1424 }
1425}
1426
1427
1429{
1430 wxASSERT( IsDimension( aNode ) );
1431
1432 std::map<wxString, TYPE> typeMap = { { wxT( "LINEARDIM" ), TYPE::LINEARDIM },
1433 { wxT( "LEADERDIM" ), TYPE::LEADERDIM }, { wxT( "ANGLEDIM" ), TYPE::ANGLEDIM } };
1434
1435 //make sure aNode is valid TYPE
1436 wxASSERT_MSG( typeMap.find( aNode->GetName() ) != typeMap.end(),
1437 wxT( "Not a valid type. What happened to the node Name?" ) );
1438
1439 Type = typeMap[aNode->GetName()];
1440 LayerID = GetXmlAttributeIDString( aNode, 1 );
1441 wxString subTypeStr = GetXmlAttributeIDString( aNode, 2 );
1442
1443 std::map<wxString, SUBTYPE> subTypeMap = {
1444 { wxT( "DIMENSION_ORTHOGONAL" ), SUBTYPE::ORTHOGONAL },
1445 { wxT( "DIMENSION_DIRECT" ), SUBTYPE::DIRECT },
1446 { wxT( "DIMENSION_ANGLED" ), SUBTYPE::ANGLED },
1447 { wxT( "DIMENSION_DIAMETER" ), SUBTYPE::DIAMETER },
1448 { wxT( "DIMENSION_RADIUS" ), SUBTYPE::RADIUS },
1449 { wxT( "DIMENSION_ANGULAR" ), SUBTYPE::ANGULAR } };
1450
1451 if( subTypeMap.find( subTypeStr ) == subTypeMap.end() )
1452 THROW_UNKNOWN_PARAMETER_IO_ERROR( subTypeStr, aNode->GetName() );
1453
1454 Subtype = subTypeMap[subTypeStr];
1455 Precision = GetXmlAttributeIDLong( aNode, 3 );
1456
1457 XNODE* cNode = aNode->GetChildren();
1458
1459 bool idParsed = false;
1460 bool unitsParsed = false; //UNITS or ANGUNITS
1461 bool arrowParsed = false;
1462 bool textFormatParsed = false;
1463 bool extLineParsed = false;
1464 bool lineParsed = false;
1465 bool textParsed = false;
1466
1467 for( ; cNode; cNode = cNode->GetNext() )
1468 {
1469 wxString cNodeName = cNode->GetName();
1470
1471 if( !idParsed && cNodeName == wxT( "DIMREF" ) )
1472 {
1473 ID = GetXmlAttributeIDString( cNode, 0 );
1474 idParsed = true;
1475 }
1476 else if( !unitsParsed && cNodeName == wxT( "UNITS" ) )
1477 {
1478 LinearUnits = ParseUnits( cNode );
1479 unitsParsed = true;
1480 }
1481 else if( !unitsParsed && cNodeName == wxT( "ANGUNITS" ) )
1482 {
1483 AngularUnits = ParseAngunits( cNode );
1484 unitsParsed = true;
1485 }
1486 else if( !arrowParsed && cNodeName == wxT( "DIMARROW" ) )
1487 {
1488 Arrow.Parse( cNode, aContext );
1489 arrowParsed = true;
1490 }
1491 else if( !textFormatParsed && cNodeName == wxT( "DIMTEXT" ) )
1492 {
1493 TextParams.Parse( cNode, aContext );
1494 textFormatParsed = true;
1495 }
1496 else if( !extLineParsed && cNodeName == wxT( "EXTLINE" ) )
1497 {
1498 ExtensionLineParams.Parse( cNode, aContext );
1499 extLineParsed = true;
1500 }
1501 else if( !lineParsed && LINE::IsLine( cNode ) )
1502 {
1503 Line.Parse( cNode, aContext );
1504 lineParsed = true;
1505 }
1506 else if( !textParsed && cNodeName == wxT( "TEXT" ) )
1507 {
1508 // Do not parse the fields in dimension text (will be done when loading, if required)
1509 Text.Parse( cNode, aContext, false );
1510 textParsed = true;
1511 }
1512 else if( cNodeName == wxT( "FIX" ) )
1513 {
1514 Fixed = true;
1515 }
1516 else if( cNodeName == wxT( "GROUPREF" ) )
1517 {
1518 GroupID = GetXmlAttributeIDString( cNode, 0 );
1519 }
1520 else if( cNodeName == wxT( "REUSEBLOCKREF" ) )
1521 {
1522 ReuseBlockRef.Parse( cNode, aContext );
1523 }
1524 else
1525 {
1526 THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, aNode->GetName() );
1527 }
1528 }
1529}
1530
1531
1533{
1534 wxASSERT( aNode->GetName() == wxT( "SYMDEF" ) );
1535
1536 ParseIdentifiers( aNode, aContext );
1537
1538 wxString rest;
1539
1540 if( ReferenceName.StartsWith( wxT( "JUMPERNF" ), &rest ) )
1541 Type = SYMDEF_TYPE::JUMPER;
1542 else if( ReferenceName.StartsWith( wxT( "STARPOINTNF" ), &rest ) )
1544 else if( ReferenceName == wxT( "TESTPOINT" ) )
1546 else
1548
1549 XNODE* cNode = aNode->GetChildren();
1550
1551 for( ; cNode; cNode = cNode->GetNext() )
1552 {
1553 wxString cNodeName = cNode->GetName();
1554
1555 if( ParseSubNode( cNode, aContext ) )
1556 {
1557 continue;
1558 }
1559 else if( cNodeName == wxT( "SYMHEIGHT" ) )
1560 {
1561 SymHeight = GetXmlAttributeIDLong( cNode, 0 );
1562 }
1563 else if( cNodeName == wxT( "COMPCOPPER" ) )
1564 {
1565 COMPONENT_COPPER compcopper;
1566 compcopper.Parse( cNode, aContext );
1567 ComponentCoppers.push_back( compcopper );
1568 }
1569 else if( cNodeName == wxT( "COMPAREA" ) )
1570 {
1571 COMPONENT_AREA area;
1572 area.Parse( cNode, aContext );
1573 ComponentAreas.insert( std::make_pair( area.ID, area ) );
1574 }
1575 else if( cNodeName == wxT( "PAD" ) )
1576 {
1578 pad.Parse( cNode, aContext );
1579 ComponentPads.insert( std::make_pair( pad.ID, pad ) );
1580 }
1581 else if( cNodeName == wxT( "DIMENSIONS" ) )
1582 {
1583 XNODE* dimensionNode = cNode->GetChildren();
1584
1585 for( ; dimensionNode; dimensionNode = dimensionNode->GetNext() )
1586 {
1587 if( DIMENSION::IsDimension( dimensionNode ) )
1588 {
1589 DIMENSION dim;
1590 dim.Parse( dimensionNode, aContext );
1591 Dimensions.insert( std::make_pair( dim.ID, dim ) );
1592 }
1593 else
1594 {
1595 THROW_UNKNOWN_NODE_IO_ERROR( dimensionNode->GetName(), cNodeName );
1596 }
1597 }
1598 }
1599 else
1600 {
1601 THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, aNode->GetName() );
1602 }
1603 }
1604
1605 if( !Stub && ( Origin.x == UNDEFINED_VALUE || Origin.y == UNDEFINED_VALUE ) )
1606 THROW_MISSING_PARAMETER_IO_ERROR( wxT( "PT" ), aNode->GetName() );
1607}
1608
1609
1611{
1612 wxASSERT( aNode->GetName() == wxT( "LIBRARY" ) );
1613
1614 XNODE* cNode = aNode->GetChildren();
1615
1616 for( ; cNode; cNode = cNode->GetNext() )
1617 {
1618 wxString cNodeName = cNode->GetName();
1619
1620 if( cNodeName == wxT( "SYMDEF" ) )
1621 {
1622 SYMDEF_PCB symdef;
1623 symdef.Parse( cNode, aContext );
1624 ComponentDefinitions.insert( std::make_pair( symdef.ID, symdef ) );
1625 }
1626 else if( cNodeName == wxT( "HIERARCHY" ) )
1627 {
1628 // Ignore for now
1629 //
1630 // This node doesn't have any equivalent in KiCad so for now we ignore it. In
1631 // future, we could parse it in detail, to obtain the tree-structure of
1632 // footprints in a cadstar library
1633 }
1634 else
1635 {
1636 THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, aNode->GetName() );
1637 }
1638
1639 aContext->CheckPointCallback();
1640 }
1641}
1642
1643
1645{
1646 wxASSERT( aNode->GetName() == wxT( "BOARD" ) );
1647
1648 ID = GetXmlAttributeIDString( aNode, 0 );
1649 LineCodeID = GetXmlAttributeIDString( aNode, 1 );
1650
1651 XNODE* cNode = aNode->GetChildren();
1652 bool shapeIsInitialised = false; // Stop more than one Shape Object
1653 wxString location = wxString::Format( wxT( "BOARD %s" ), ID );
1654
1655 if( !cNode )
1656 THROW_MISSING_NODE_IO_ERROR( wxT( "Shape" ), location );
1657
1658 for( ; cNode; cNode = cNode->GetNext() )
1659 {
1660 wxString cNodeName = cNode->GetName();
1661
1662 if( !shapeIsInitialised && SHAPE::IsShape( cNode ) )
1663 {
1664 Shape.Parse( cNode, aContext );
1665 shapeIsInitialised = true;
1666 }
1667 else if( cNodeName == wxT( "ATTR" ) )
1668 {
1669 ATTRIBUTE_VALUE attr;
1670 attr.Parse( cNode, aContext );
1671 AttributeValues.insert( std::make_pair( attr.AttributeID, attr ) );
1672 }
1673 else if( cNodeName == wxT( "FIX" ) )
1674 {
1675 Fixed = true;
1676 }
1677 else if( cNodeName == wxT( "GROUPREF" ) )
1678 {
1679 GroupID = GetXmlAttributeIDString( cNode, 0 );
1680 }
1681 else if( cNodeName == wxT( "REUSEBLOCKREF" ) )
1682 {
1683 ReuseBlockRef.Parse( cNode, aContext );
1684 }
1685 else
1686 {
1687 THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, location );
1688 }
1689 }
1690}
1691
1692
1694{
1695 wxASSERT( aNode->GetName() == wxT( "AREA" ) );
1696
1697 ID = GetXmlAttributeIDString( aNode, 0 );
1698 LineCodeID = GetXmlAttributeIDString( aNode, 1 );
1699 Name = GetXmlAttributeIDString( aNode, 2 );
1700 LayerID = GetXmlAttributeIDString( aNode, 4 );
1701
1702 XNODE* cNode = aNode->GetChildren();
1703 bool shapeIsInitialised = false; // Stop more than one Shape Object
1704 wxString location = wxString::Format( wxT( "AREA %s" ), ID );
1705
1706 if( !cNode )
1707 THROW_MISSING_NODE_IO_ERROR( wxT( "Shape" ), location );
1708
1709 for( ; cNode; cNode = cNode->GetNext() )
1710 {
1711 wxString cNodeName = cNode->GetName();
1712
1713 if( !shapeIsInitialised && SHAPE::IsShape( cNode ) )
1714 {
1715 Shape.Parse( cNode, aContext );
1716 shapeIsInitialised = true;
1717 }
1718 else if( cNodeName == wxT( "FIX" ) )
1719 {
1720 Fixed = true;
1721 }
1722 else if( cNodeName == wxT( "USAGE" ) )
1723 {
1724 wxXmlAttribute* xmlAttribute = cNode->GetAttributes();
1725
1726 for( ; xmlAttribute; xmlAttribute = xmlAttribute->GetNext() )
1727 {
1728 if( !IsValidAttribute( xmlAttribute ) )
1729 continue;
1730
1731 if( xmlAttribute->GetValue() == wxT( "PLACEMENT" ) )
1732 Placement = true;
1733 else if( xmlAttribute->GetValue() == wxT( "ROUTING" ) )
1734 Routing = true;
1735 else if( xmlAttribute->GetValue() == wxT( "KEEPOUT" ) )
1736 Keepout = true;
1737 else if( xmlAttribute->GetValue() == wxT( "NO_TRACKS" ) )
1738 NoTracks = true;
1739 else if( xmlAttribute->GetValue() == wxT( "NO_VIAS" ) )
1740 NoVias = true;
1741 else
1742 THROW_UNKNOWN_PARAMETER_IO_ERROR( xmlAttribute->GetValue(), location );
1743 }
1744
1745 CheckNoChildNodes( cNode );
1746 }
1747 else if( cNodeName == wxT( "AREAHEIGHT" ) )
1748 {
1749 AreaHeight = GetXmlAttributeIDLong( cNode, 0 );
1750 }
1751 else if( cNodeName == wxT( "GROUPREF" ) )
1752 {
1753 GroupID = GetXmlAttributeIDString( cNode, 0 );
1754 }
1755 else if( cNodeName == wxT( "REUSEBLOCKREF" ) )
1756 {
1757 ReuseBlockRef.Parse( cNode, aContext );
1758 }
1759 else if( cNodeName == wxT( "ATTR" ) )
1760 {
1761 ATTRIBUTE_VALUE attr;
1762 attr.Parse( cNode, aContext );
1763 AttributeValues.insert( std::make_pair( attr.AttributeID, attr ) );
1764 }
1765 else
1766 {
1767 THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, location );
1768 }
1769 }
1770}
1771
1772
1774{
1775 wxASSERT( aNode->GetName() == wxT( "PINATTR" ) );
1776
1777 Pin = GetXmlAttributeIDLong( aNode, 0 );
1778
1779 XNODE* cNode = aNode->GetChildren();
1780
1781 for( ; cNode; cNode = cNode->GetNext() )
1782 {
1783 wxString cNodeName = cNode->GetName();
1784
1785 if( cNodeName == wxT( "ATTR" ) )
1786 {
1787 ATTRIBUTE_VALUE attrVal;
1788 attrVal.Parse( cNode, aContext );
1789 AttributeValues.insert( std::make_pair( attrVal.AttributeID, attrVal ) );
1790 }
1791 else if( cNodeName == wxT( "TESTLAND" ) )
1792 {
1793 TestlandSide = ParseTestlandSide( cNode );
1794 }
1795 else
1796 {
1797 THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, aNode->GetName() );
1798 }
1799 }
1800}
1801
1802
1804{
1805 wxASSERT( aNode->GetName() == wxT( "PADEXCEPTION" ) );
1806
1807 ID = GetXmlAttributeIDLong( aNode, 0 );
1808
1809 XNODE* cNode = aNode->GetChildren();
1810
1811 for( ; cNode; cNode = cNode->GetNext() )
1812 {
1813 wxString cNodeName = cNode->GetName();
1814
1815 if( cNodeName == wxT( "PADCODEREF" ) )
1816 {
1817 PadCode = GetXmlAttributeIDString( cNode, 0 );
1818 }
1819 else if( cNodeName == wxT( "EXITS" ) )
1820 {
1821 OverrideExits = true;
1822 Exits.Parse( cNode, aContext );
1823 }
1824 else if( cNodeName == wxT( "SIDE" ) )
1825 {
1826 OverrideSide = true;
1827 Side = GetPadSide( GetXmlAttributeIDString( cNode, 0 ) );
1828 }
1829 else if( cNodeName == wxT( "ORIENT" ) )
1830 {
1831 OverrideOrientation = true;
1832 OrientAngle = GetXmlAttributeIDLong( cNode, 0 );
1833 }
1834 else
1835 {
1836 THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, aNode->GetName() );
1837 }
1838 }
1839}
1840
1841
1843{
1844 wxASSERT( aNode->GetName() == wxT( "COMP" ) );
1845
1846 ID = GetXmlAttributeIDString( aNode, 0 );
1847 Name = GetXmlAttributeIDString( aNode, 1 );
1848 PartID = GetXmlAttributeIDString( aNode, 2 );
1849 SymdefID = GetXmlAttributeIDString( aNode, 3 );
1850
1851 XNODE* cNode = aNode->GetChildren();
1852 bool originParsed = false;
1853
1854 for( ; cNode; cNode = cNode->GetNext() )
1855 {
1856 wxString cNodeName = cNode->GetName();
1857
1858 if( !originParsed && cNodeName == wxT( "PT" ) )
1859 {
1860 Origin.Parse( cNode, aContext );
1861 originParsed = true;
1862 }
1863 else if( cNodeName == wxT( "GROUPREF" ) )
1864 {
1865 GroupID = GetXmlAttributeIDString( cNode, 0 );
1866 }
1867 else if( cNodeName == wxT( "REUSEBLOCKREF" ) )
1868 {
1869 ReuseBlockRef.Parse( cNode, aContext );
1870 }
1871 else if( cNodeName == wxT( "TESTPOINT" ) )
1872 {
1873 TestPoint = true;
1874 }
1875 else if( cNodeName == wxT( "FIX" ) )
1876 {
1877 Fixed = true;
1878 }
1879 else if( cNodeName == wxT( "MIRROR" ) )
1880 {
1881 Mirror = true;
1882 }
1883 else if( cNodeName == wxT( "READABILITY" ) )
1884 {
1885 Readability = ParseReadability( cNode );
1886 }
1887 else if( cNodeName == wxT( "ORIENT" ) )
1888 {
1889 OrientAngle = GetXmlAttributeIDLong( cNode, 0 );
1890 }
1891 else if( cNodeName == wxT( "VCOMPMASTER" ) )
1892 {
1893 VariantParentComponentID = GetXmlAttributeIDString( cNode, 0 );
1894 VariantID = GetXmlAttributeIDString( cNode, 1 );
1895 }
1896 else if( cNodeName == wxT( "TEXTLOC" ) )
1897 {
1898 TEXT_LOCATION textloc;
1899 textloc.Parse( cNode, aContext );
1900 TextLocations.insert( std::make_pair( textloc.AttributeID, textloc ) );
1901 }
1902 else if( cNodeName == wxT( "ATTR" ) )
1903 {
1904 ATTRIBUTE_VALUE attrVal;
1905 attrVal.Parse( cNode, aContext );
1906 AttributeValues.insert( std::make_pair( attrVal.AttributeID, attrVal ) );
1907 }
1908 else if( cNodeName == wxT( "PINATTR" ) )
1909 {
1910 PIN_ATTRIBUTE pinAttr;
1911 pinAttr.Parse( cNode, aContext );
1912 PinAttributes.insert( std::make_pair( pinAttr.Pin, pinAttr ) );
1913 }
1914 else if( cNodeName == wxT( "COMPPINLABEL" ) )
1915 {
1917 wxString pinLabel = GetXmlAttributeIDString( cNode, 1 );
1918 PinLabels.insert( std::make_pair( pinID, pinLabel ) );
1919 }
1920 else if( cNodeName == wxT( "PADEXCEPTION" ) )
1921 {
1922 PADEXCEPTION padExcept;
1923 padExcept.Parse( cNode, aContext );
1924 PadExceptions.insert( std::make_pair( padExcept.ID, padExcept ) );
1925 }
1926 else
1927 {
1928 THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, aNode->GetName() );
1929 }
1930 }
1931
1932 if( !originParsed )
1933 THROW_MISSING_PARAMETER_IO_ERROR( wxT( "PT" ), aNode->GetName() );
1934}
1935
1936
1938 XNODE* aNode )
1939{
1940 wxASSERT( aNode->GetName() == wxT( "TESTLAND" ) );
1941
1942 wxString side = GetXmlAttributeIDString( aNode, 0 );
1943
1944 if( side == wxT( "MIN_SIDE" ) )
1945 return TESTLAND_SIDE::MIN;
1946 else if( side == wxT( "MAX_SIDE" ) )
1947 return TESTLAND_SIDE::MAX;
1948 else if( side == wxT( "BOTH_SIDES" ) )
1949 return TESTLAND_SIDE::BOTH;
1950 else
1951 THROW_UNKNOWN_PARAMETER_IO_ERROR( side, aNode->GetName() );
1952
1953 return TESTLAND_SIDE::NONE;
1954}
1955
1956
1958{
1959 wxASSERT( aNode->GetName() == wxT( "TRUNK" ) );
1960
1961 ID = GetXmlAttributeIDString( aNode, 0 );
1962 Definition = GetXmlAttributeIDString( aNode, 1 );
1963}
1964
1965
1967{
1968 wxASSERT( aNode->GetName() == wxT( "PIN" ) );
1969
1970 ID = GetXmlAttributeIDString( aNode, 0 );
1971 ComponentID = GetXmlAttributeIDString( aNode, 1 );
1972 PadID = GetXmlAttributeIDLong( aNode, 2 );
1973 CheckNoChildNodes( aNode );
1974}
1975
1976
1978 PARSER_CONTEXT* aContext )
1979{
1980 ParseIdentifiers( aNode, aContext );
1981 XNODE* cNode = aNode->GetChildren();
1982
1983 for( ; cNode; cNode = cNode->GetNext() )
1984 {
1985 if( ParseSubNode( cNode, aContext ) )
1986 continue;
1987 else if( cNode->GetName() == wxT( "TRUNKREF" ) )
1988 TrunkID = GetXmlAttributeIDString( cNode, 0 );
1989 else
1990 THROW_UNKNOWN_NODE_IO_ERROR( cNode->GetName(), aNode->GetName() );
1991 }
1992}
1993
1994
1996{
1997 wxASSERT( aNode->GetName() == wxT( "VIA" ) );
1998
1999 ID = GetXmlAttributeIDString( aNode, 0 );
2000 ViaCodeID = GetXmlAttributeIDString( aNode, 1 );
2001 LayerPairID = GetXmlAttributeIDString( aNode, 2 );
2002
2003 XNODE* cNode = aNode->GetChildren();
2004
2005 for( ; cNode; cNode = cNode->GetNext() )
2006 {
2007 wxString cNodeName = cNode->GetName();
2008
2009 if( cNodeName == wxT( "PT" ) )
2010 Location.Parse( cNode, aContext );
2011 else if( cNodeName == wxT( "FIX" ) )
2012 Fixed = true;
2013 else if( cNodeName == wxT( "GROUPREF" ) )
2014 GroupID = GetXmlAttributeIDString( cNode, 0 );
2015 else if( cNodeName == wxT( "REUSEBLOCKREF" ) )
2016 ReuseBlockRef.Parse( cNode, aContext );
2017 else if( cNodeName == wxT( "TESTLAND" ) )
2018 TestlandSide = ParseTestlandSide( cNode );
2019 else if( cNode->GetName() == wxT( "TRUNKREF" ) )
2020 TrunkID = GetXmlAttributeIDString( cNode, 0 );
2021 else
2022 THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, aNode->GetName() );
2023 }
2024}
2025
2026
2028 PARSER_CONTEXT* aContext )
2029{
2030 wxASSERT( aNode->GetName() == wxT( "COPTERM" ) );
2031
2032 ID = GetXmlAttributeIDString( aNode, 0 );
2033 CopperID = GetXmlAttributeIDString( aNode, 1 );
2034 CopperTermNum = GetXmlAttributeIDLong( aNode, 2 );
2035}
2036
2037
2039 PARSER_CONTEXT* aContext )
2040{
2041 wxASSERT( aNode->GetName() == wxT( "ROUTEWIDTH" ) );
2042
2043 RouteWidth = GetXmlAttributeIDLong( aNode, 0 );
2044 XNODE* prevNode = aNode;
2045 XNODE* nextNode = aNode->GetNext();
2046
2047 for( ; nextNode; nextNode = nextNode->GetNext() )
2048 {
2049 if( nextNode->GetName() == wxT( "FIX" ) )
2050 {
2051 Fixed = true;
2052 }
2053 else if( nextNode->GetName() == wxT( "TDROPATSTART" ) )
2054 {
2055 TeardropAtStart = true;
2056 TeardropAtStartAngle = GetXmlAttributeIDLong( nextNode, 0 );
2057 }
2058 else if( nextNode->GetName() == wxT( "TDROPATEND" ) )
2059 {
2060 TeardropAtEnd = true;
2061 TeardropAtEndAngle = GetXmlAttributeIDLong( nextNode, 0 );
2062 }
2063 else if( VERTEX::IsVertex( nextNode ) )
2064 {
2065 Vertex.Parse( nextNode, aContext );
2066 }
2067 else if( nextNode->GetName() == wxT( "ROUTEWIDTH" ) )
2068 {
2069 return prevNode;
2070 }
2071 else
2072 {
2073 THROW_UNKNOWN_NODE_IO_ERROR( nextNode->GetName(), wxT( "ROUTE" ) );
2074 }
2075
2076 prevNode = nextNode;
2077 }
2078
2079 return prevNode;
2080}
2081
2082
2084{
2085 wxASSERT( aNode->GetName() == wxT( "ROUTE" ) );
2086
2087 LayerID = GetXmlAttributeIDString( aNode, 0 );
2088
2089 //Parse child nodes
2090 XNODE* cNode = aNode->GetChildren();
2091 bool startPointParsed = false;
2092
2093 for( ; cNode; cNode = cNode->GetNext() )
2094 {
2095 wxString cNodeName = cNode->GetName();
2096
2097 if( !startPointParsed && cNodeName == wxT( "PT" ) )
2098 {
2099 startPointParsed = true;
2100 StartPoint.Parse( cNode, aContext );
2101 }
2102 else if( cNodeName == wxT( "ROUTEWIDTH" ) )
2103 {
2104 ROUTE_VERTEX rtVert;
2105 cNode = rtVert.Parse( cNode, aContext );
2106 RouteVertices.push_back( rtVert );
2107
2108 assert( cNode != nullptr );
2109 }
2110 else
2111 {
2112 THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, wxT( "ROUTE" ) );
2113 }
2114 }
2115}
2116
2117
2119 PARSER_CONTEXT* aContext )
2120{
2121 ParseIdentifiers( aNode, aContext );
2122
2123 //Parse child nodes
2124 XNODE* cNode = aNode->GetChildren();
2125 bool routeParsed = false; //assume only one route per connection
2126
2127 for( ; cNode; cNode = cNode->GetNext() )
2128 {
2129 wxString cNodeName = cNode->GetName();
2130
2131 if( ParseSubNode( cNode, aContext ) )
2132 {
2133 continue;
2134 }
2135 else if( !Unrouted && !routeParsed && cNodeName == wxT( "ROUTE" ) )
2136 {
2137 Route.Parse( cNode, aContext );
2138 routeParsed = true;
2139 }
2140 else if( !routeParsed && cNodeName == wxT( "UNROUTE" ) )
2141 {
2142 Unrouted = true;
2143 UnrouteLayerID = GetXmlAttributeIDString( cNode, 0 );
2144 }
2145 else if( cNode->GetName() == wxT( "TRUNKREF" ) )
2146 {
2147 TrunkID = GetXmlAttributeIDString( cNode, 0 );
2148 }
2149 else
2150 {
2151 THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, wxT( "CONN" ) );
2152 }
2153 }
2154}
2155
2156
2158{
2159 ParseIdentifiers( aNode, aContext );
2160
2161 //Parse child nodes
2162 XNODE* cNode = aNode->GetChildren();
2163
2164 for( ; cNode; cNode = cNode->GetNext() )
2165 {
2166 wxString cNodeName = cNode->GetName();
2167
2168 if( cNodeName == wxT( "JPT" ) )
2169 {
2170 JUNCTION_PCB jpt;
2171 jpt.Parse( cNode, aContext );
2172 Junctions.insert( std::make_pair( jpt.ID, jpt ) );
2173 }
2174 else if( ParseSubNode( cNode, aContext ) )
2175 {
2176 continue;
2177 }
2178 else if( cNodeName == wxT( "PIN" ) )
2179 {
2180 PIN pin;
2181 pin.Parse( cNode, aContext );
2182 Pins.insert( std::make_pair( pin.ID, pin ) );
2183 }
2184 else if( cNodeName == wxT( "VIA" ) )
2185 {
2186 VIA via;
2187 via.Parse( cNode, aContext );
2188 Vias.insert( std::make_pair( via.ID, via ) );
2189 }
2190 else if( cNodeName == wxT( "COPTERM" ) )
2191 {
2192 COPPER_TERMINAL cterm;
2193 cterm.Parse( cNode, aContext );
2194 CopperTerminals.insert( std::make_pair( cterm.ID, cterm ) );
2195 }
2196 else if( cNodeName == wxT( "CONN" ) )
2197 {
2198 CONNECTION_PCB conn;
2199 conn.Parse( cNode, aContext );
2200 Connections.push_back( conn );
2201 }
2202 else
2203 {
2204 THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, wxT( "NET" ) );
2205 }
2206 }
2207}
2208
2209
2211{
2212 wxASSERT( aNode->GetName() == wxT( "POURING" ) );
2213
2214 CopperCodeID = GetXmlAttributeIDString( aNode, 0 );
2215 ReliefCopperCodeID = GetXmlAttributeIDString( aNode, 1 );
2216 ClearanceWidth = GetXmlAttributeIDLong( aNode, 2 );
2217 SliverWidth = GetXmlAttributeIDLong( aNode, 3 );
2218 AdditionalIsolation = GetXmlAttributeIDLong( aNode, 4 );
2219 ThermalReliefPadsAngle = GetXmlAttributeIDLong( aNode, 5 );
2220 ThermalReliefViasAngle = GetXmlAttributeIDLong( aNode, 6 );
2221
2222 wxString MinIsolCopStr = GetXmlAttributeIDString( aNode, 7 );
2223
2224 if( MinIsolCopStr == wxT( "NONE" ) )
2225 MinIsolatedCopper = UNDEFINED_VALUE;
2226 else
2227 MinIsolatedCopper = GetXmlAttributeIDLong( aNode, 7 );
2228
2229 wxString MinDisjCopStr = GetXmlAttributeIDString( aNode, 8 );
2230
2231 if( MinDisjCopStr == wxT( "NONE" ) )
2232 MinDisjointCopper = UNDEFINED_VALUE;
2233 else
2234 MinDisjointCopper = GetXmlAttributeIDLong( aNode, 8 );
2235
2236 XNODE* cNode = aNode->GetChildren();
2237
2238 for( ; cNode; cNode = cNode->GetNext() )
2239 {
2240 wxString cNodeName = cNode->GetName();
2241
2242 if( cNodeName == wxT( "NOPINRELIEF" ) )
2243 {
2244 ThermalReliefOnPads = false;
2245 }
2246 else if( cNodeName == wxT( "NOVIARELIEF" ) )
2247 {
2248 ThermalReliefOnVias = false;
2249 }
2250 else if( cNodeName == wxT( "IGNORETRN" ) )
2251 {
2252 AllowInNoRouting = true;
2253 }
2254 else if( cNodeName == wxT( "BOXPINS" ) )
2255 {
2256 BoxIsolatedPins = true;
2257 }
2258 else if( cNodeName == wxT( "REGENERATE" ) )
2259 {
2260 AutomaticRepour = true;
2261 }
2262 else if( cNodeName == wxT( "AUTOROUTETARGET" ) )
2263 {
2264 TargetForAutorouting = true;
2265 }
2266 else if( cNodeName == wxT( "THERMALCUTOUT" ) )
2267 {
2268 ReliefType = RELIEF_TYPE::CUTOUTS;
2269 }
2270 else if( cNodeName == wxT( "FILLED" ) )
2271 {
2272 FillType = COPPER_FILL_TYPE::FILLED;
2273 }
2274 else if( cNodeName == wxT( "HATCHCODEREF" ) )
2275 {
2276 FillType = COPPER_FILL_TYPE::HATCHED;
2277 HatchCodeID = GetXmlAttributeIDString( cNode, 0 );
2278 }
2279 else
2280 {
2281 THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, wxT( "POURING" ) );
2282 }
2283 }
2284}
2285
2286
2288{
2289 wxASSERT( aNode->GetName() == wxT( "TEMPLATE" ) );
2290
2291 ID = GetXmlAttributeIDString( aNode, 0 );
2292 LineCodeID = GetXmlAttributeIDString( aNode, 1 );
2293 Name = GetXmlAttributeIDString( aNode, 2 );
2294 NetID = GetXmlAttributeIDString( aNode, 3 );
2295 LayerID = GetXmlAttributeIDString( aNode, 4 );
2296
2297 XNODE* cNode = aNode->GetChildren();
2298 bool shapeParsed = false;
2299 bool pouringParsed = false;
2300
2301 for( ; cNode; cNode = cNode->GetNext() )
2302 {
2303 wxString cNodeName = cNode->GetName();
2304
2305 if( !shapeParsed && SHAPE::IsShape( cNode ) )
2306 {
2307 Shape.Parse( cNode, aContext );
2308 shapeParsed = true;
2309 }
2310 else if( !pouringParsed && cNodeName == wxT( "POURING" ) )
2311 {
2312 Pouring.Parse( cNode, aContext );
2313 pouringParsed = true;
2314 }
2315 else if( cNodeName == wxT( "FIX" ) )
2316 {
2317 Fixed = true;
2318 }
2319 else if( cNodeName == wxT( "GROUPREF" ) )
2320 {
2321 GroupID = GetXmlAttributeIDString( cNode, 0 );
2322 }
2323 else if( cNodeName == wxT( "REUSEBLOCKREF" ) )
2324 {
2325 ReuseBlockRef.Parse( cNode, aContext );
2326 }
2327 else if( cNodeName == wxT( "ATTR" ) )
2328 {
2329 ATTRIBUTE_VALUE attr;
2330 attr.Parse( cNode, aContext );
2331 AttributeValues.insert( std::make_pair( attr.AttributeID, attr ) );
2332 }
2333 else
2334 {
2335 THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, wxT( "TEMPLATE" ) );
2336 }
2337 }
2338}
2339
2340
2342 PARSER_CONTEXT* aContext )
2343{
2344 wxASSERT( aNode->GetName() == wxT( "TERM" ) );
2345
2346 ID = GetXmlAttributeIDLong( aNode, 0 );
2347
2348 XNODE* cNode = aNode->GetChildren();
2349 bool locationParsed = false;
2350
2351 for( ; cNode; cNode = cNode->GetNext() )
2352 {
2353 wxString cNodeName = cNode->GetName();
2354
2355 if( !locationParsed && cNodeName == wxT( "PT" ) )
2356 {
2357 Location.Parse( cNode, aContext );
2358 locationParsed = true;
2359 }
2360 else if( cNodeName == wxT( "FIX" ) )
2361 {
2362 Fixed = true;
2363 }
2364 else
2365 {
2366 THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, aNode->GetName() );
2367 }
2368 }
2369}
2370
2371
2373{
2374 wxASSERT( aNode->GetName() == wxT( "NETREF" ) );
2375
2376 NetID = GetXmlAttributeIDString( aNode, 0 );
2377
2378 XNODE* cNode = aNode->GetChildren();
2379
2380 for( ; cNode; cNode = cNode->GetNext() )
2381 {
2382 wxString cNodeName = cNode->GetName();
2383
2384 if( cNodeName == wxT( "TERM" ) )
2385 {
2386 COPPER_TERM term;
2387 term.Parse( cNode, aContext );
2388 CopperTerminals.insert( std::make_pair( term.ID, term ) );
2389 }
2390 else if( cNodeName == wxT( "FIX" ) )
2391 {
2392 Fixed = true;
2393 }
2394 else
2395 {
2396 THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, wxT( "NETREF" ) );
2397 }
2398 }
2399}
2400
2401
2403{
2404 wxASSERT( aNode->GetName() == wxT( "COPPER" ) );
2405
2406 ID = GetXmlAttributeIDString( aNode, 0 );
2407 CopperCodeID = GetXmlAttributeIDString( aNode, 1 );
2408 LayerID = GetXmlAttributeIDString( aNode, 2 );
2409
2410 XNODE* cNode = aNode->GetChildren();
2411 bool shapeParsed = false;
2412 bool netRefParsed = false;
2413
2414 for( ; cNode; cNode = cNode->GetNext() )
2415 {
2416 wxString cNodeName = cNode->GetName();
2417
2418 if( !shapeParsed && SHAPE::IsShape( cNode ) )
2419 {
2420 Shape.Parse( cNode, aContext );
2421 shapeParsed = true;
2422 }
2423 else if( !netRefParsed && cNodeName == wxT( "NETREF" ) )
2424 {
2425 NetRef.Parse( cNode, aContext );
2426 netRefParsed = true;
2427 }
2428 else if( cNodeName == wxT( "FIX" ) )
2429 {
2430 Fixed = true;
2431 }
2432 else if( cNodeName == wxT( "GROUPREF" ) )
2433 {
2434 GroupID = GetXmlAttributeIDString( cNode, 0 );
2435 }
2436 else if( cNodeName == wxT( "REUSEBLOCKREF" ) )
2437 {
2438 ReuseBlockRef.Parse( cNode, aContext );
2439 }
2440 else if( cNodeName == wxT( "POURED" ) )
2441 {
2442 PouredTemplateID = GetXmlAttributeIDString( cNode, 0 );
2443 }
2444 else if( cNodeName == wxT( "ATTR" ) )
2445 {
2446 ATTRIBUTE_VALUE attr;
2447 attr.Parse( cNode, aContext );
2448 AttributeValues.insert( std::make_pair( attr.AttributeID, attr ) );
2449 }
2450 else
2451 {
2452 THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, wxT( "TEMPLATE" ) );
2453 }
2454 }
2455}
2456
2457
2459{
2460 wxASSERT( aNode->GetName() == wxT( "DRILLTABLE" ) );
2461
2462 ID = GetXmlAttributeIDString( aNode, 0 );
2463 LayerID = GetXmlAttributeIDString( aNode, 1 );
2464
2465 XNODE* cNode = aNode->GetChildren();
2466 bool positionParsed = false;
2467
2468 for( ; cNode; cNode = cNode->GetNext() )
2469 {
2470 wxString cNodeName = cNode->GetName();
2471
2472 if( !positionParsed && cNodeName == wxT( "PT" ) )
2473 {
2474 Position.Parse( cNode, aContext );
2475 positionParsed = true;
2476 }
2477 else if( cNodeName == wxT( "ORIENT" ) )
2478 {
2479 OrientAngle = GetXmlAttributeIDLong( cNode, 0 );
2480 }
2481 else if( cNodeName == wxT( "MIRROR" ) )
2482 {
2483 Mirror = true;
2484 }
2485 else if( cNodeName == wxT( "FIX" ) )
2486 {
2487 Fixed = true;
2488 }
2489 else if( cNodeName == wxT( "READABILITY" ) )
2490 {
2491 Readability = ParseReadability( cNode );
2492 }
2493 else if( cNodeName == wxT( "GROUPREF" ) )
2494 {
2495 GroupID = GetXmlAttributeIDString( cNode, 0 );
2496 }
2497 else if( cNodeName == wxT( "REUSEBLOCKREF" ) )
2498 {
2499 ReuseBlockRef.Parse( cNode, aContext );
2500 }
2501 else
2502 {
2503 THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, aNode->GetName() );
2504 }
2505 }
2506}
2507
2508
2510{
2511 wxASSERT( aNode->GetName() == wxT( "LAYOUT" ) );
2512
2513 XNODE* cNode = aNode->GetChildren();
2514 bool netSynchParsed = false;
2515 bool dimensionsParsed = false;
2516
2517 for( ; cNode; cNode = cNode->GetNext() )
2518 {
2519 wxString cNodeName = cNode->GetName();
2520
2521 if( !netSynchParsed && cNodeName == wxT( "NETSYNCH" ) )
2522 {
2523 std::map<wxString, NETSYNCH> netSynchMap = { { wxT( "WARNING" ), NETSYNCH::WARNING },
2524 { wxT( "FULL" ), NETSYNCH::FULL } };
2525
2526 wxString nsString = GetXmlAttributeIDString( cNode, 0 );
2527
2528 if( netSynchMap.find( nsString ) == netSynchMap.end() )
2529 THROW_UNKNOWN_PARAMETER_IO_ERROR( nsString, aNode->GetName() );
2530
2531 NetSynch = netSynchMap[nsString];
2532 netSynchParsed = true;
2533 }
2534 else if( cNodeName == wxT( "GROUP" ) )
2535 {
2536 GROUP group;
2537 group.Parse( cNode, aContext );
2538 Groups.insert( std::make_pair( group.ID, group ) );
2539 }
2540 else if( cNodeName == wxT( "REUSEBLOCK" ) )
2541 {
2542 REUSEBLOCK reuseblock;
2543 reuseblock.Parse( cNode, aContext );
2544 ReuseBlocks.insert( std::make_pair( reuseblock.ID, reuseblock ) );
2545 }
2546 else if( cNodeName == wxT( "BOARD" ) )
2547 {
2548 CADSTAR_BOARD board;
2549 board.Parse( cNode, aContext );
2550 Boards.insert( std::make_pair( board.ID, board ) );
2551 }
2552 else if( cNodeName == wxT( "FIGURE" ) )
2553 {
2554 FIGURE figure;
2555 figure.Parse( cNode, aContext );
2556 Figures.insert( std::make_pair( figure.ID, figure ) );
2557 }
2558 else if( cNodeName == wxT( "AREA" ) )
2559 {
2560 AREA area;
2561 area.Parse( cNode, aContext );
2562 Areas.insert( std::make_pair( area.ID, area ) );
2563 }
2564 else if( cNodeName == wxT( "COMP" ) )
2565 {
2566 COMPONENT comp;
2567 comp.Parse( cNode, aContext );
2568 Components.insert( std::make_pair( comp.ID, comp ) );
2569 }
2570 else if( cNodeName == wxT( "TRUNK" ) )
2571 {
2572 TRUNK trunk;
2573 trunk.Parse( cNode, aContext );
2574 Trunks.insert( std::make_pair( trunk.ID, trunk ) );
2575 }
2576 else if( cNodeName == wxT( "NET" ) )
2577 {
2578 NET_PCB net;
2579 net.Parse( cNode, aContext );
2580 Nets.insert( std::make_pair( net.ID, net ) );
2581 }
2582 else if( cNodeName == wxT( "TEMPLATE" ) )
2583 {
2584 TEMPLATE temp;
2585 temp.Parse( cNode, aContext );
2586 Templates.insert( std::make_pair( temp.ID, temp ) );
2587 }
2588 else if( cNodeName == wxT( "COPPER" ) )
2589 {
2590 COPPER copper;
2591 copper.Parse( cNode, aContext );
2592 Coppers.insert( std::make_pair( copper.ID, copper ) );
2593 }
2594 else if( cNodeName == wxT( "TEXT" ) )
2595 {
2596 TEXT txt;
2597 txt.Parse( cNode, aContext );
2598 Texts.insert( std::make_pair( txt.ID, txt ) );
2599 }
2600 else if( cNodeName == wxT( "DOCSYMBOL" ) )
2601 {
2602 DOCUMENTATION_SYMBOL docsym;
2603 docsym.Parse( cNode, aContext );
2604 DocumentationSymbols.insert( std::make_pair( docsym.ID, docsym ) );
2605 }
2606 else if( !dimensionsParsed && cNodeName == wxT( "DIMENSIONS" ) )
2607 {
2608 XNODE* dimensionNode = cNode->GetChildren();
2609
2610 for( ; dimensionNode; dimensionNode = dimensionNode->GetNext() )
2611 {
2612 if( DIMENSION::IsDimension( dimensionNode ) )
2613 {
2614 DIMENSION dim;
2615 dim.Parse( dimensionNode, aContext );
2616 Dimensions.insert( std::make_pair( dim.ID, dim ) );
2617 }
2618 else
2619 {
2620 THROW_UNKNOWN_NODE_IO_ERROR( dimensionNode->GetName(), cNodeName );
2621 }
2622 }
2623
2624 dimensionsParsed = true;
2625 }
2626 else if( cNodeName == wxT( "DRILLTABLE" ) )
2627 {
2628 DRILL_TABLE drilltable;
2629 drilltable.Parse( cNode, aContext );
2630 DrillTables.insert( std::make_pair( drilltable.ID, drilltable ) );
2631 }
2632 else if( cNodeName == wxT( "VHIERARCHY" ) )
2633 {
2634 VariantHierarchy.Parse( cNode, aContext );
2635 }
2636 else if( cNodeName == wxT( "ERRORMARK" ) )
2637 {
2638 //ignore (this is a DRC error marker in cadstar)
2639 continue;
2640 }
2641 else
2642 {
2643 THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, aNode->GetName() );
2644 }
2645
2646 aContext->CheckPointCallback();
2647 }
2648}
constexpr double PCB_IU_PER_MM
Definition: base_units.h:70
#define THROW_MISSING_NODE_IO_ERROR(nodename, location)
#define THROW_UNKNOWN_NODE_IO_ERROR(nodename, location)
#define THROW_UNKNOWN_PARAMETER_IO_ERROR(param, location)
#define THROW_MISSING_PARAMETER_IO_ERROR(param, location)
#define THROW_PARSING_IO_ERROR(param, location)
static UNITS ParseUnits(XNODE *aNode)
static SWAP_RULE ParseSwapRule(XNODE *aNode)
static const long UNDEFINED_VALUE
static void CheckNoNextNodes(XNODE *aNode)
static XNODE * LoadArchiveFile(const wxString &aFileName, const wxString &aFileTypeIdentifier, PROGRESS_REPORTER *aProgressReporter=nullptr)
Reads a CADSTAR Archive file (S-parameter format)
wxString LAYER_ID
ID of a Sheet (if schematic) or board Layer (if PCB)
static ANGUNITS ParseAngunits(XNODE *aNode)
long PART_DEFINITION_PIN_ID
Pin identifier in the part definition.
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 void CheckNoChildNodes(XNODE *aNode)
static long GetXmlAttributeIDLong(XNODE *aNode, unsigned int aID, bool aIsRequired=true)
static void ParseChildEValue(XNODE *aNode, PARSER_CONTEXT *aContext, EVALUE &aValueToParse)
static long GetNumberOfStepsForReporting(XNODE *aRootNode, std::vector< wxString > aSubNodeChildrenToCount)
PROGRESS_REPORTER * m_progressReporter
static TESTLAND_SIDE ParseTestlandSide(XNODE *aNode)
@ STARPOINT
From CADSTAR Help: "Starpoints are special symbols/components that can be used to electrically connec...
@ JUMPER
From CADSTAR Help: "Jumpers are components used primarily for the purpose of routing.
@ COMPONENT
Standard PCB Component definition.
@ TESTPOINT
From CADSTAR Help: "A testpoint is an area of copper connected to a net.
@ UNBIASED
Keyword "UNBIASED" (default)
long PAD_ID
Pad identifier (pin) in the PCB.
void Parse(bool aLibrary=false)
Parses the file.
int KiCadUnitMultiplier
Use this value to convert units in this CPA file to KiCad units.
@ ALLELEC
Inbuilt layer type (cannot be assigned to user layers)
@ ALLDOC
Inbuilt layer type (cannot be assigned to user layers)
@ NONELEC
This type has subtypes.
@ NOLAYER
Inbuilt layer type (cannot be assigned to user layers)
@ JUMPERLAYER
Inbuilt layer type (cannot be assigned to user layers)
@ ALLLAYER
Inbuilt layer type (cannot be assigned to user layers)
@ ASSCOMPCOPP
Inbuilt layer type (cannot be assigned to user layers)
@ MAX
The highest PHYSICAL_LAYER_ID currently defined (i.e. back / bottom side).
@ MIN
The lowest PHYSICAL_LAYER_ID currently defined (i.e. front / top side).
static PAD_SIDE GetPadSide(const wxString &aPadSideString)
PAD_SIDE
From CADSTAR Help: "This parameter indicates the physical layers on which the selected pad is placed.
@ MAXIMUM
The highest PHYSICAL_LAYER_ID currently defined (i.e.
@ MINIMUM
PHYSICAL_LAYER_ID 1 (i.e.
@ THROUGH_HOLE
All physical layers currently defined.
virtual void BeginPhase(int aPhase)=0
Initialize the aPhase virtual zone of the dialog progress bar.
virtual void SetMaxProgress(int aMaxProgress)=0
Fix the value that gives the 100 percent progress bar length (inside the current virtual zone).
Hold an XML or S-expression element.
Definition: xnode.h:43
XNODE * GetChildren() const
Definition: xnode.h:61
XNODE * GetNext() const
Definition: xnode.h:66
#define THROW_IO_ERROR(msg)
Definition: ki_exception.h:39
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 ...
Definition: macros.h:83
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
NETELEMENT_ID ID
First character is "J".
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
Corresponds to CADSTAR "origin".
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
From CADSTAR Help: "Area is for creating areas within which, and nowhere else, certain operations are...
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
From CADSTAR Help: "Area is for creating areas within which, and nowhere else, certain operations are...
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
A shape of copper in the component footprint.
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 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
Linear, leader (radius/diameter) or angular dimension.
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
DIMENSION_ID ID
Some ID (doesn't seem to be used) subnode="DIMREF".
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 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
< "PIN" nodename (represents a PAD in a PCB component)
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
< Two sibbling nodes: first node being "ROUTEWIDTH" and next node being a VERTEX (e....
XNODE * Parse(XNODE *aNode, 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
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 Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
SPACINGCODE_ID ID
Possible spacing rules:
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
Templates are CADSTAR's equivalent to a "filled zone".
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