KiCad PCB EDA Suite
Loading...
Searching...
No Matches
test_diptrace_sch_import_fixture.h
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 The KiCad Developers, see AUTHORS.txt for contributors.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <https://www.gnu.org/licenses/>.
18 */
19
20#ifndef TEST_DIPTRACE_SCH_IMPORT_FIXTURE_H
21#define TEST_DIPTRACE_SCH_IMPORT_FIXTURE_H
22
27
29
32
33#include <connection_graph.h>
34#include <eeschema_helpers.h>
35#include <sch_connection.h>
36#include <sch_label.h>
37#include <sch_line.h>
38#include <sch_pin.h>
39#include <sch_screen.h>
40#include <sch_shape.h>
41#include <sch_sheet_path.h>
42#include <sch_symbol.h>
43#include <schematic.h>
45
46#include <lib_symbol.h>
47
48#include <climits>
49
50#include <algorithm>
51#include <cmath>
52#include <cstdlib>
53#include <filesystem>
54#include <memory>
55#include <set>
56#include <sstream>
57#include <vector>
58
59#include <reporter.h>
60
61#include <wx/filefn.h>
62#include <wx/ffile.h>
63#include <wx/xml/xml.h>
64
65
69{
70public:
71 REPORTER& Report( const wxString& aText, SEVERITY aSeverity = RPT_SEVERITY_UNDEFINED ) override
72 {
73 m_messages.emplace_back( aSeverity, aText );
74 return *this;
75 }
76
77 bool HasMessage() const override { return !m_messages.empty(); }
78
79 int CountOfSeverity( int aSeverityMask ) const
80 {
81 int n = 0;
82
83 for( const auto& [sev, text] : m_messages )
84 {
85 if( sev & aSeverityMask )
86 n++;
87 }
88
89 return n;
90 }
91
92 std::string MessagesOfSeverity( int aSeverityMask ) const
93 {
94 std::ostringstream out;
95
96 for( const auto& [sev, text] : m_messages )
97 {
98 if( !( sev & aSeverityMask ) )
99 continue;
100
101 if( out.tellp() > 0 )
102 out << "; ";
103
104 out << text.ToStdString();
105 }
106
107 return out.str();
108 }
109
110 void Clear() override { m_messages.clear(); }
111
112 std::vector<std::pair<SEVERITY, wxString>> m_messages;
113};
114
115
117{
119 m_schematic( new SCHEMATIC( nullptr ) )
120 {
121 m_manager.LoadProject( "" );
122 m_schematic->SetProject( &m_manager.Prj() );
123 m_schematic->CurrentSheet().clear();
124 m_schematic->CurrentSheet().push_back( &m_schematic->Root() );
125 }
126
128 std::unique_ptr<SCHEMATIC> m_schematic;
132
133 std::string GetTestDataDir() { return KI_TEST::GetEeschemaTestDataDir() + "plugins/diptrace/"; }
134
136 {
137 const char* examplesEnv = std::getenv( "DIPTRACE_VIEWER_EXAMPLES_DIR" );
138
139 return examplesEnv && *examplesEnv ? examplesEnv : "/home/seth/Downloads/DipTrace Viewer/Examples";
140 }
141
143 {
144 std::set<SCH_SCREEN*> seenScreens;
145 int count = 0;
146
147 for( const SCH_SHEET_PATH& sheetPath : m_schematic->BuildUnorderedSheetList() )
148 {
149 SCH_SCREEN* screen = sheetPath.LastScreen();
150
151 if( !screen || !seenScreens.insert( screen ).second )
152 continue;
153
154 for( SCH_ITEM* item : screen->Items() )
155 {
156 if( item->Type() == aType )
157 count++;
158 }
159 }
160
161 return count;
162 }
163
165 {
166 std::set<SCH_SCREEN*> seenScreens;
167
168 for( const SCH_SHEET_PATH& sheetPath : m_schematic->BuildUnorderedSheetList() )
169 {
170 SCH_SCREEN* screen = sheetPath.LastScreen();
171
172 if( !screen || !seenScreens.insert( screen ).second )
173 continue;
174 }
175
176 return static_cast<int>( seenScreens.size() );
177 }
178
179 // Symbol references are resolved per sheet path through instance data, so iterate the
180 // hierarchy and match each symbol's path-resolved reference rather than its raw field text.
181 int MaxPinCountForRefdes( const wxString& aRefdes )
182 {
183 int maxPins = -1;
184
185 for( const SCH_SHEET_PATH& sheetPath : m_schematic->BuildUnorderedSheetList() )
186 {
187 SCH_SCREEN* screen = sheetPath.LastScreen();
188
189 if( !screen )
190 continue;
191
192 for( SCH_ITEM* item : screen->Items().OfType( SCH_SYMBOL_T ) )
193 {
194 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
195
196 if( symbol->GetRef( &sheetPath, false ) == aRefdes )
197 maxPins = std::max( maxPins, static_cast<int>( symbol->GetPins().size() ) );
198 }
199 }
200
201 return maxPins;
202 }
203
204 wxString GetFootprintForRefdes( const wxString& aRefdes )
205 {
206 for( const SCH_SHEET_PATH& sheetPath : m_schematic->BuildUnorderedSheetList() )
207 {
208 SCH_SCREEN* screen = sheetPath.LastScreen();
209
210 if( !screen )
211 continue;
212
213 for( SCH_ITEM* item : screen->Items().OfType( SCH_SYMBOL_T ) )
214 {
215 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
216
217 if( symbol->GetRef( &sheetPath, false ) == aRefdes )
218 {
219 SCH_FIELD* fpField = symbol->GetField( FIELD_T::FOOTPRINT );
220 return fpField ? fpField->GetText() : wxString();
221 }
222 }
223 }
224
225 return wxString();
226 }
227
229 wxString GetSheetNameForRefdes( const wxString& aRefdes )
230 {
231 for( const SCH_SHEET_PATH& sheetPath : m_schematic->BuildUnorderedSheetList() )
232 {
233 SCH_SCREEN* screen = sheetPath.LastScreen();
234
235 if( !screen )
236 continue;
237
238 for( SCH_ITEM* item : screen->Items().OfType( SCH_SYMBOL_T ) )
239 {
240 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
241
242 if( symbol->GetRef( &sheetPath, false ) == aRefdes )
243 return sheetPath.Last() ? sheetPath.Last()->GetName() : wxString();
244 }
245 }
246
247 return wxString();
248 }
249
252 void PinOrientationCounts( const wxString& aRefdes, int& aLeft, int& aRight, int& aUp, int& aDown )
253 {
254 aLeft = aRight = aUp = aDown = 0;
255
256 for( const SCH_SHEET_PATH& sheetPath : m_schematic->BuildUnorderedSheetList() )
257 {
258 SCH_SCREEN* screen = sheetPath.LastScreen();
259
260 if( !screen )
261 continue;
262
263 for( SCH_ITEM* item : screen->Items().OfType( SCH_SYMBOL_T ) )
264 {
265 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
266
267 if( symbol->GetRef( &sheetPath, false ) != aRefdes || !symbol->GetLibSymbolRef() )
268 continue;
269
270 for( SCH_PIN* pin : symbol->GetLibSymbolRef()->GetPins() )
271 {
272 switch( pin->GetOrientation() )
273 {
274 case PIN_ORIENTATION::PIN_LEFT: aLeft++; break;
275 case PIN_ORIENTATION::PIN_RIGHT: aRight++; break;
276 case PIN_ORIENTATION::PIN_UP: aUp++; break;
277 case PIN_ORIENTATION::PIN_DOWN: aDown++; break;
278 default: break;
279 }
280 }
281
282 return;
283 }
284 }
285 }
286
290 bool HasLabelOnSheet( const wxString& aText, const wxString& aSheetName )
291 {
292 for( const SCH_SHEET_PATH& sheetPath : m_schematic->BuildUnorderedSheetList() )
293 {
294 if( !sheetPath.Last() || sheetPath.Last()->GetName() != aSheetName )
295 continue;
296
297 SCH_SCREEN* screen = sheetPath.LastScreen();
298
299 if( !screen )
300 continue;
301
302 for( SCH_ITEM* item : screen->Items().OfType( SCH_GLOBAL_LABEL_T ) )
303 {
304 SCH_LABEL_BASE* label = static_cast<SCH_LABEL_BASE*>( item );
305
306 if( label->GetText() == aText )
307 return true;
308 }
309 }
310
311 return false;
312 }
313
317 bool HasLabelStartingWithOnSheet( const wxString& aPrefix, const wxString& aSheetName )
318 {
319 for( const SCH_SHEET_PATH& sheetPath : m_schematic->BuildUnorderedSheetList() )
320 {
321 if( !sheetPath.Last() || sheetPath.Last()->GetName() != aSheetName )
322 continue;
323
324 SCH_SCREEN* screen = sheetPath.LastScreen();
325
326 if( !screen )
327 continue;
328
329 for( SCH_ITEM* item : screen->Items().OfType( SCH_GLOBAL_LABEL_T ) )
330 {
331 SCH_LABEL_BASE* label = static_cast<SCH_LABEL_BASE*>( item );
332
333 if( label->GetText().StartsWith( aPrefix ) )
334 return true;
335 }
336 }
337
338 return false;
339 }
340
342 int CountLinesOnSheet( const wxString& aSheetName )
343 {
344 int lines = 0;
345
346 for( const SCH_SHEET_PATH& sheetPath : m_schematic->BuildUnorderedSheetList() )
347 {
348 if( !sheetPath.Last() || sheetPath.Last()->GetName() != aSheetName )
349 continue;
350
351 SCH_SCREEN* screen = sheetPath.LastScreen();
352
353 if( !screen )
354 continue;
355
356 for( SCH_ITEM* item : screen->Items().OfType( SCH_LINE_T ) )
357 {
358 static_cast<void>( item );
359 lines++;
360 }
361 }
362
363 return lines;
364 }
365
369 int RefValueFieldSeparation( const wxString& aRefdes )
370 {
371 for( const SCH_SHEET_PATH& sheetPath : m_schematic->BuildUnorderedSheetList() )
372 {
373 SCH_SCREEN* screen = sheetPath.LastScreen();
374
375 if( !screen )
376 continue;
377
378 for( SCH_ITEM* item : screen->Items().OfType( SCH_SYMBOL_T ) )
379 {
380 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
381
382 if( symbol->GetRef( &sheetPath, false ) != aRefdes )
383 continue;
384
385 SCH_FIELD* refField = symbol->GetField( FIELD_T::REFERENCE );
386 SCH_FIELD* valField = symbol->GetField( FIELD_T::VALUE );
387
388 if( !refField || !valField )
389 return -1;
390
391 return ( refField->GetPosition() - valField->GetPosition() ).EuclideanNorm();
392 }
393 }
394
395 return -1;
396 }
397
400 wxString GetFieldValueForRefdes( const wxString& aRefdes, const wxString& aFieldName )
401 {
402 for( const SCH_SHEET_PATH& sheetPath : m_schematic->BuildUnorderedSheetList() )
403 {
404 SCH_SCREEN* screen = sheetPath.LastScreen();
405
406 if( !screen )
407 continue;
408
409 for( SCH_ITEM* item : screen->Items().OfType( SCH_SYMBOL_T ) )
410 {
411 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
412
413 if( symbol->GetRef( &sheetPath, false ) != aRefdes )
414 continue;
415
416 const SCH_FIELD* field = symbol->GetField( aFieldName );
417 return field ? field->GetText() : wxString();
418 }
419 }
420
421 return wxString();
422 }
423
426 double ValueFieldAngleDegrees( const wxString& aRefdes )
427 {
428 for( const SCH_SHEET_PATH& sheetPath : m_schematic->BuildUnorderedSheetList() )
429 {
430 SCH_SCREEN* screen = sheetPath.LastScreen();
431
432 if( !screen )
433 continue;
434
435 for( SCH_ITEM* item : screen->Items().OfType( SCH_SYMBOL_T ) )
436 {
437 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
438
439 if( symbol->GetRef( &sheetPath, false ) != aRefdes )
440 continue;
441
442 const SCH_FIELD* field = symbol->GetField( FIELD_T::VALUE );
443 return field ? field->GetTextAngle().AsDegrees() : -1;
444 }
445 }
446
447 return -1;
448 }
449
452 int ShowsPinNames( const wxString& aRefdes )
453 {
454 for( const SCH_SHEET_PATH& sheetPath : m_schematic->BuildUnorderedSheetList() )
455 {
456 SCH_SCREEN* screen = sheetPath.LastScreen();
457
458 if( !screen )
459 continue;
460
461 for( SCH_ITEM* item : screen->Items().OfType( SCH_SYMBOL_T ) )
462 {
463 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
464
465 if( symbol->GetRef( &sheetPath, false ) != aRefdes || !symbol->GetLibSymbolRef() )
466 continue;
467
468 return symbol->GetLibSymbolRef()->GetShowPinNames() ? 1 : 0;
469 }
470 }
471
472 return -1;
473 }
474
476 int CountSymbolShapes( const wxString& aRefdes, SHAPE_T aShapeType )
477 {
478 for( const SCH_SHEET_PATH& sheetPath : m_schematic->BuildUnorderedSheetList() )
479 {
480 SCH_SCREEN* screen = sheetPath.LastScreen();
481
482 if( !screen )
483 continue;
484
485 for( SCH_ITEM* item : screen->Items().OfType( SCH_SYMBOL_T ) )
486 {
487 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
488
489 if( symbol->GetRef( &sheetPath, false ) != aRefdes || !symbol->GetLibSymbolRef() )
490 continue;
491
492 int count = 0;
493
494 for( const SCH_ITEM& draw : symbol->GetLibSymbolRef()->GetDrawItems() )
495 {
496 if( draw.Type() == SCH_SHAPE_T && static_cast<const SCH_SHAPE&>( draw ).GetShape() == aShapeType )
497 {
498 count++;
499 }
500 }
501
502 return count;
503 }
504 }
505
506 return -1;
507 }
508
509 int CountSymbolsForRefdesOnSheet( const wxString& aRefdes, const wxString& aSheetName )
510 {
511 int count = 0;
512
513 for( const SCH_SHEET_PATH& sheetPath : m_schematic->BuildUnorderedSheetList() )
514 {
515 if( !sheetPath.Last() || sheetPath.Last()->GetName() != aSheetName )
516 continue;
517
518 SCH_SCREEN* screen = sheetPath.LastScreen();
519
520 if( !screen )
521 continue;
522
523 for( SCH_ITEM* item : screen->Items().OfType( SCH_SYMBOL_T ) )
524 {
525 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
526
527 if( symbol->GetRef( &sheetPath, false ) == aRefdes )
528 count++;
529 }
530 }
531
532 return count;
533 }
534
535 static int DipTraceMmToSchIU( double aMm ) { return static_cast<int>( std::lround( aMm * 10000.0 ) ); }
536
537 static VECTOR2I DipTraceXmlSheetPointToKiCad( double aXmm, double aYmm )
538 {
539 return VECTOR2I( DipTraceMmToSchIU( 210.0 + aXmm ), DipTraceMmToSchIU( 148.5 - aYmm ) );
540 }
541
542 int CountSheetGraphicLines( const wxString& aSheetName, const VECTOR2I& aStart, const VECTOR2I& aEnd, int aWidth )
543 {
544 int count = 0;
545
546 for( const SCH_SHEET_PATH& sheetPath : m_schematic->BuildUnorderedSheetList() )
547 {
548 if( !sheetPath.Last() || sheetPath.Last()->GetName() != aSheetName )
549 continue;
550
551 SCH_SCREEN* screen = sheetPath.LastScreen();
552
553 if( !screen )
554 continue;
555
556 for( SCH_ITEM* item : screen->Items().OfType( SCH_SHAPE_T ) )
557 {
558 SCH_SHAPE* shape = static_cast<SCH_SHAPE*>( item );
559
560 if( shape->GetShape() != SHAPE_T::POLY || shape->GetStroke().GetWidth() != aWidth )
561 continue;
562
563 const KIGFX::COLOR4D color = shape->GetStroke().GetColor();
564
565 if( color.r > 0.01 || color.g > 0.01 || color.b < 0.99 )
566 continue;
567
568 const SHAPE_POLY_SET& poly = shape->GetPolyShape();
569
570 if( poly.TotalVertices() != 2 )
571 continue;
572
573 VECTOR2I p0 = poly.CVertex( 0 );
574 VECTOR2I p1 = poly.CVertex( 1 );
575
576 if( ( p0 == aStart && p1 == aEnd ) || ( p0 == aEnd && p1 == aStart ) )
577 count++;
578 }
579 }
580
581 return count;
582 }
583
584 int CountFilledPolysForRefdes( const wxString& aRefdes )
585 {
586 for( const SCH_SHEET_PATH& sheetPath : m_schematic->BuildUnorderedSheetList() )
587 {
588 SCH_SCREEN* screen = sheetPath.LastScreen();
589
590 if( !screen )
591 continue;
592
593 for( SCH_ITEM* item : screen->Items().OfType( SCH_SYMBOL_T ) )
594 {
595 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
596
597 if( symbol->GetRef( &sheetPath, false ) != aRefdes || !symbol->GetLibSymbolRef() )
598 continue;
599
600 int count = 0;
601
602 for( const SCH_ITEM& draw : symbol->GetLibSymbolRef()->GetDrawItems() )
603 {
604 if( draw.Type() == SCH_SHAPE_T && static_cast<const SCH_SHAPE&>( draw ).GetShape() == SHAPE_T::POLY
605 && static_cast<const SCH_SHAPE&>( draw ).GetFillMode() != FILL_T::NO_FILL )
606 {
607 count++;
608 }
609 }
610
611 return count;
612 }
613 }
614
615 return -1;
616 }
617
618 int CountOpenPolysWithPointCountForRefdes( const wxString& aRefdes, int aPointCount )
619 {
620 for( const SCH_SHEET_PATH& sheetPath : m_schematic->BuildUnorderedSheetList() )
621 {
622 SCH_SCREEN* screen = sheetPath.LastScreen();
623
624 if( !screen )
625 continue;
626
627 for( SCH_ITEM* item : screen->Items().OfType( SCH_SYMBOL_T ) )
628 {
629 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
630
631 if( symbol->GetRef( &sheetPath, false ) != aRefdes || !symbol->GetLibSymbolRef() )
632 continue;
633
634 int count = 0;
635
636 for( const SCH_ITEM& draw : symbol->GetLibSymbolRef()->GetDrawItems() )
637 {
638 if( draw.Type() != SCH_SHAPE_T )
639 continue;
640
641 const SCH_SHAPE& shape = static_cast<const SCH_SHAPE&>( draw );
642
643 if( shape.GetShape() == SHAPE_T::POLY && shape.GetFillMode() == FILL_T::NO_FILL
644 && shape.GetPolyShape().TotalVertices() == aPointCount )
645 {
646 count++;
647 }
648 }
649
650 return count;
651 }
652 }
653
654 return -1;
655 }
656
658 std::vector<int> UnitsForRefdesOnSheet( const wxString& aRefdes, const wxString& aSheetName )
659 {
660 std::vector<int> units;
661
662 for( const SCH_SHEET_PATH& sheetPath : m_schematic->BuildUnorderedSheetList() )
663 {
664 if( !sheetPath.Last() || sheetPath.Last()->GetName() != aSheetName )
665 continue;
666
667 SCH_SCREEN* screen = sheetPath.LastScreen();
668
669 if( !screen )
670 continue;
671
672 for( SCH_ITEM* item : screen->Items().OfType( SCH_SYMBOL_T ) )
673 {
674 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
675
676 if( symbol->GetRef( &sheetPath, false ) == aRefdes )
677 units.push_back( symbol->GetUnit() );
678 }
679 }
680
681 std::sort( units.begin(), units.end() );
682 return units;
683 }
684
686 int UnitCountForRefdes( const wxString& aRefdes )
687 {
688 for( const SCH_SHEET_PATH& sheetPath : m_schematic->BuildUnorderedSheetList() )
689 {
690 SCH_SCREEN* screen = sheetPath.LastScreen();
691
692 if( !screen )
693 continue;
694
695 for( SCH_ITEM* item : screen->Items().OfType( SCH_SYMBOL_T ) )
696 {
697 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
698
699 if( symbol->GetRef( &sheetPath, false ) == aRefdes )
700 return symbol->GetUnitCount();
701 }
702 }
703
704 return -1;
705 }
706
708 int LibPinCountForRefdesUnitOnSheet( const wxString& aRefdes, const wxString& aSheetName, int aUnit )
709 {
710 for( const SCH_SHEET_PATH& sheetPath : m_schematic->BuildUnorderedSheetList() )
711 {
712 if( !sheetPath.Last() || sheetPath.Last()->GetName() != aSheetName )
713 continue;
714
715 SCH_SCREEN* screen = sheetPath.LastScreen();
716
717 if( !screen )
718 continue;
719
720 for( SCH_ITEM* item : screen->Items().OfType( SCH_SYMBOL_T ) )
721 {
722 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
723
724 if( symbol->GetRef( &sheetPath, false ) == aRefdes && symbol->GetUnit() == aUnit )
725 return static_cast<int>( symbol->GetLibPins().size() );
726 }
727 }
728
729 return -1;
730 }
731
733 std::set<wxString> LibPinNamesForRefdesUnitOnSheet( const wxString& aRefdes, const wxString& aSheetName, int aUnit )
734 {
735 for( const SCH_SHEET_PATH& sheetPath : m_schematic->BuildUnorderedSheetList() )
736 {
737 if( !sheetPath.Last() || sheetPath.Last()->GetName() != aSheetName )
738 continue;
739
740 SCH_SCREEN* screen = sheetPath.LastScreen();
741
742 if( !screen )
743 continue;
744
745 for( SCH_ITEM* item : screen->Items().OfType( SCH_SYMBOL_T ) )
746 {
747 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
748
749 if( symbol->GetRef( &sheetPath, false ) != aRefdes || symbol->GetUnit() != aUnit )
750 continue;
751
752 std::set<wxString> names;
753
754 for( SCH_PIN* pin : symbol->GetLibPins() )
755 names.insert( pin->GetName() );
756
757 return names;
758 }
759 }
760
761 return {};
762 }
763
765 int CountJunctionsOnSheet( const wxString& aSheetName )
766 {
767 int count = 0;
768
769 for( const SCH_SHEET_PATH& sheetPath : m_schematic->BuildUnorderedSheetList() )
770 {
771 if( !sheetPath.Last() || sheetPath.Last()->GetName() != aSheetName )
772 continue;
773
774 SCH_SCREEN* screen = sheetPath.LastScreen();
775
776 if( !screen )
777 continue;
778
779 for( SCH_ITEM* item : screen->Items().OfType( SCH_JUNCTION_T ) )
780 {
781 static_cast<void>( item );
782 count++;
783 }
784 }
785
786 return count;
787 }
788
791 VECTOR2I FieldPosForRefdes( const wxString& aRefdes, FIELD_T aFieldType )
792 {
793 for( const SCH_SHEET_PATH& sheetPath : m_schematic->BuildUnorderedSheetList() )
794 {
795 SCH_SCREEN* screen = sheetPath.LastScreen();
796
797 if( !screen )
798 continue;
799
800 for( SCH_ITEM* item : screen->Items().OfType( SCH_SYMBOL_T ) )
801 {
802 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
803
804 if( symbol->GetRef( &sheetPath, false ) != aRefdes )
805 continue;
806
807 if( SCH_FIELD* field = symbol->GetField( aFieldType ) )
808 return field->GetPosition();
809 }
810 }
811
812 return VECTOR2I( INT_MAX, INT_MAX );
813 }
814
817 int FieldHorizJustify( const wxString& aRefdes, FIELD_T aFieldType )
818 {
819 for( const SCH_SHEET_PATH& sheetPath : m_schematic->BuildUnorderedSheetList() )
820 {
821 SCH_SCREEN* screen = sheetPath.LastScreen();
822
823 if( !screen )
824 continue;
825
826 for( SCH_ITEM* item : screen->Items().OfType( SCH_SYMBOL_T ) )
827 {
828 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
829
830 if( symbol->GetRef( &sheetPath, false ) != aRefdes )
831 continue;
832
833 if( SCH_FIELD* field = symbol->GetField( aFieldType ) )
834 return static_cast<int>( field->GetHorizJustify() );
835 }
836 }
837
838 return 99;
839 }
840
842 int CountLabelsOnSheet( const wxString& aText, const wxString& aSheetName )
843 {
844 int count = 0;
845
846 for( const SCH_SHEET_PATH& sheetPath : m_schematic->BuildUnorderedSheetList() )
847 {
848 if( !sheetPath.Last() || sheetPath.Last()->GetName() != aSheetName )
849 continue;
850
851 SCH_SCREEN* screen = sheetPath.LastScreen();
852
853 if( !screen )
854 continue;
855
856 for( SCH_ITEM* item : screen->Items().OfType( SCH_GLOBAL_LABEL_T ) )
857 {
858 if( static_cast<SCH_LABEL_BASE*>( item )->GetText() == aText )
859 count++;
860 }
861 }
862
863 return count;
864 }
865
869 bool LabelConnectsToWireOnSheet( const wxString& aPrefix, const wxString& aSheetName )
870 {
871 for( const SCH_SHEET_PATH& sheetPath : m_schematic->BuildUnorderedSheetList() )
872 {
873 if( !sheetPath.Last() || sheetPath.Last()->GetName() != aSheetName )
874 continue;
875
876 SCH_SCREEN* screen = sheetPath.LastScreen();
877
878 if( !screen )
879 continue;
880
881 for( SCH_ITEM* labelItem : screen->Items().OfType( SCH_GLOBAL_LABEL_T ) )
882 {
883 SCH_LABEL_BASE* label = static_cast<SCH_LABEL_BASE*>( labelItem );
884
885 if( !label->GetText().StartsWith( aPrefix ) )
886 continue;
887
888 VECTOR2I anchor = label->GetPosition();
889
890 for( SCH_ITEM* lineItem : screen->Items().OfType( SCH_LINE_T ) )
891 {
892 SCH_LINE* line = static_cast<SCH_LINE*>( lineItem );
893
894 if( line->GetStartPoint() == anchor || line->GetEndPoint() == anchor )
895 return true;
896 }
897 }
898 }
899
900 return false;
901 }
902
904 {
905 int partCount = 0;
906 int netPortCount = 0;
907 int sheetCount = 0;
908 };
909
910 static bool XmlSubtreeContains( wxXmlNode* aNode, const wxString& aNeedle )
911 {
912 for( wxXmlNode* n = aNode; n; n = n->GetNext() )
913 {
914 if( n->GetType() == wxXML_TEXT_NODE && n->GetContent().Contains( aNeedle ) )
915 return true;
916
917 if( XmlSubtreeContains( n->GetChildren(), aNeedle ) )
918 return true;
919 }
920
921 return false;
922 }
923
924 bool LoadDchXmlCounts( const std::string& aXmlPath, DCH_XML_COUNTS& aCounts )
925 {
926 if( !wxFileExists( aXmlPath ) )
927 return false;
928
929 wxXmlDocument doc;
930
931 if( !doc.Load( aXmlPath ) )
932 return false;
933
934 wxXmlNode* root = doc.GetRoot();
935
936 if( !root || root->GetName() != "Source" )
937 return false;
938
939 wxXmlNode* schematicNode = nullptr;
940
941 for( wxXmlNode* child = root->GetChildren(); child; child = child->GetNext() )
942 {
943 if( child->GetType() == wxXML_ELEMENT_NODE && child->GetName() == "Schematic" )
944 {
945 schematicNode = child;
946 break;
947 }
948 }
949
950 if( !schematicNode )
951 return false;
952
953 int partCount = 0;
954 int netPortCount = 0;
955 int sheetCount = 0;
956 std::vector<wxXmlNode*> stack = { schematicNode };
957
958 while( !stack.empty() )
959 {
960 wxXmlNode* node = stack.back();
961 stack.pop_back();
962
963 if( !node || node->GetType() != wxXML_ELEMENT_NODE )
964 continue;
965
966 if( node->GetName() == "Part" )
967 {
968 partCount++;
969
970 // Net-port placements carry an auto_net_ports library reference; the importer maps
971 // these to global labels rather than symbols, so count them the same way here.
972 if( XmlSubtreeContains( node->GetChildren(), wxT( "auto_net_ports" ) ) )
973 netPortCount++;
974 }
975 else if( node->GetName() == "Sheet" )
976 {
977 sheetCount++;
978 }
979
980 for( wxXmlNode* child = node->GetChildren(); child; child = child->GetNext() )
981 {
982 stack.push_back( child );
983 }
984 }
985
986 aCounts.partCount = partCount;
987 aCounts.netPortCount = netPortCount;
988 aCounts.sheetCount = sheetCount;
989 return true;
990 }
991
992 SCH_SHEET* LoadDipTraceSchematic( const std::string& aFilePath )
993 {
994 m_schematic.reset( new SCHEMATIC( nullptr ) );
995 m_manager.LoadProject( "" );
996 m_schematic->SetProject( &m_manager.Prj() );
997 m_schematic->CurrentSheet().clear();
998 m_schematic->CurrentSheet().push_back( &m_schematic->Root() );
999
1000 m_reporter.Clear();
1001 m_plugin.SetReporter( &m_reporter );
1002 m_loadedRoot = m_plugin.LoadSchematicFile( aFilePath, m_schematic.get() );
1003 return m_loadedRoot;
1004 }
1005
1006 void RemoveGeneratedLibrary( const std::string& aFilePath )
1007 {
1008 wxFileName genLib( aFilePath );
1009 genLib.SetName( genLib.GetName() + wxT( "-diptrace-import" ) );
1010 genLib.SetExt( wxT( "kicad_sym" ) );
1011
1012 if( genLib.FileExists() )
1013 wxRemoveFile( genLib.GetFullPath() );
1014 }
1015};
1016
1017#endif // TEST_DIPTRACE_SCH_IMPORT_FIXTURE_H
Reporter that records the severity of every message so a test can assert that an import ran without w...
std::vector< std::pair< SEVERITY, wxString > > m_messages
std::string MessagesOfSeverity(int aSeverityMask) const
REPORTER & Report(const wxString &aText, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED) override
Report a string with a given severity.
int CountOfSeverity(int aSeverityMask) const
bool HasMessage() const override
Returns true if any messages were reported.
double AsDegrees() const
Definition eda_angle.h:116
FILL_T GetFillMode() const
Definition eda_shape.h:158
SHAPE_POLY_SET & GetPolyShape()
SHAPE_T GetShape() const
Definition eda_shape.h:185
virtual const wxString & GetText() const
Return the string associated with the text object.
Definition eda_text.h:110
virtual EDA_ANGLE GetTextAngle() const
Definition eda_text.h:168
EE_TYPE OfType(KICAD_T aType) const
Definition sch_rtree.h:221
A color representation with 4 components: red, green, blue, alpha.
Definition color4d.h:101
double r
Red component.
Definition color4d.h:389
double g
Green component.
Definition color4d.h:390
double b
Blue component.
Definition color4d.h:391
LIB_ITEMS_CONTAINER & GetDrawItems()
Return a reference to the draw item list.
Definition lib_symbol.h:709
std::vector< SCH_PIN * > GetPins() const override
REPORTER()
Definition reporter.h:73
Holds all the data relating to one schematic.
Definition schematic.h:90
VECTOR2I GetPosition() const override
virtual const wxString & GetText() const override
Return the string associated with the text object.
Definition sch_field.h:128
A SCH_IO derivation for loading DipTrace schematic files (.dch).
Base class for any item which can be embedded within the SCHEMATIC container class,...
Definition sch_item.h:162
int GetUnit() const
Definition sch_item.h:233
Segment description base class to describe items which have 2 end points (track, wire,...
Definition sch_line.h:38
VECTOR2I GetEndPoint() const
Definition sch_line.h:144
VECTOR2I GetStartPoint() const
Definition sch_line.h:135
EE_RTREE & Items()
Get the full RTree, usually for iterating.
Definition sch_screen.h:115
STROKE_PARAMS GetStroke() const override
Definition sch_shape.h:57
Handle access to a stack of flattened SCH_SHEET objects by way of a path for creating a flattened sch...
Sheet symbol placed in a schematic, and is the entry point for a sub schematic.
Definition sch_sheet.h:44
Schematic symbol object.
Definition sch_symbol.h:69
std::vector< const SCH_PIN * > GetPins(const SCH_SHEET_PATH *aSheet) const
Retrieve a list of the SCH_PINs for the given sheet path.
VECTOR2I GetPosition() const override
Definition sch_symbol.h:885
std::vector< SCH_PIN * > GetLibPins() const
Populate a vector with all the pins from the library object that match the current unit and bodyStyle...
int GetUnitCount() const override
Return the number of units per package of the symbol.
std::unique_ptr< LIB_SYMBOL > & GetLibSymbolRef()
Definition sch_symbol.h:177
const wxString GetRef(const SCH_SHEET_PATH *aSheet, bool aIncludeUnit=false) const override
SCH_FIELD * GetField(FIELD_T aFieldType)
Return a mandatory field in this symbol.
VECTOR2I GetPosition() const override
Definition sch_text.h:146
Represent a set of closed polygons.
int TotalVertices() const
Return total number of vertices stored in the set.
const VECTOR2I & CVertex(int aIndex, int aOutline, int aHole) const
Return the index-th vertex in a given hole outline within a given outline.
int GetWidth() const
KIGFX::COLOR4D GetColor() const
virtual bool GetShowPinNames() const
Definition symbol.h:165
SHAPE_T
Definition eda_shape.h:44
@ NO_FILL
Definition eda_shape.h:60
std::string GetEeschemaTestDataDir()
Get the configured location of Eeschema test data.
@ PIN_UP
The pin extends upwards from the connection point: Probably on the bottom side of the symbol.
Definition pin_type.h:123
@ PIN_RIGHT
The pin extends rightwards from the connection point.
Definition pin_type.h:107
@ PIN_LEFT
The pin extends leftwards from the connection point: Probably on the right side of the symbol.
Definition pin_type.h:114
@ PIN_DOWN
The pin extends downwards from the connection: Probably on the top side of the symbol.
Definition pin_type.h:131
SEVERITY
@ RPT_SEVERITY_UNDEFINED
Definition of the SCH_SHEET_PATH and SCH_SHEET_LIST classes for Eeschema.
int netPortCount
Parts with PartType="Net Port" (imported as global labels)
std::vector< int > UnitsForRefdesOnSheet(const wxString &aRefdes, const wxString &aSheetName)
Return the units of all symbols matching the resolved reference on the named sheet.
int FieldHorizJustify(const wxString &aRefdes, FIELD_T aFieldType)
The horizontal justification of a field (by type) of the first matching reference,...
int RefValueFieldSeparation(const wxString &aRefdes)
Distance between the reference and value field positions of the first symbol matching the reference d...
std::set< wxString > LibPinNamesForRefdesUnitOnSheet(const wxString &aRefdes, const wxString &aSheetName, int aUnit)
Return the library pin names for a specific placed unit on a sheet.
void PinOrientationCounts(const wxString &aRefdes, int &aLeft, int &aRight, int &aUp, int &aDown)
Count the pin orientations of the first symbol matching the reference designator, read from its embed...
int LibPinCountForRefdesUnitOnSheet(const wxString &aRefdes, const wxString &aSheetName, int aUnit)
Return the placed symbol's resolved library pin count for a specific unit on a sheet.
static bool XmlSubtreeContains(wxXmlNode *aNode, const wxString &aNeedle)
void RemoveGeneratedLibrary(const std::string &aFilePath)
static VECTOR2I DipTraceXmlSheetPointToKiCad(double aXmm, double aYmm)
int ShowsPinNames(const wxString &aRefdes)
Whether the embedded library symbol of the first matching reference shows its pin names.
int CountOpenPolysWithPointCountForRefdes(const wxString &aRefdes, int aPointCount)
int MaxPinCountForRefdes(const wxString &aRefdes)
int CountLabelsOnSheet(const wxString &aText, const wxString &aSheetName)
Count global labels whose text matches exactly on the sheet with the given name.
int CountFilledPolysForRefdes(const wxString &aRefdes)
wxString GetFootprintForRefdes(const wxString &aRefdes)
int UnitCountForRefdes(const wxString &aRefdes)
Return the unit count of the first library symbol matching the resolved reference.
wxString GetSheetNameForRefdes(const wxString &aRefdes)
Return the DipTrace sheet name carrying the symbol with the given reference, or empty.
bool HasLabelOnSheet(const wxString &aText, const wxString &aSheetName)
True when a global label whose text matches exists on the sheet with the given name.
wxString GetFieldValueForRefdes(const wxString &aRefdes, const wxString &aFieldName)
The text of a named field on the first symbol matching the reference designator, or an empty string w...
double ValueFieldAngleDegrees(const wxString &aRefdes)
The value-field text angle in degrees for the first symbol matching the reference designator,...
bool HasLabelStartingWithOnSheet(const wxString &aPrefix, const wxString &aSheetName)
True when any global label on the named sheet has text beginning with the given prefix.
VECTOR2I FieldPosForRefdes(const wxString &aRefdes, FIELD_T aFieldType)
The position of a field (by type) of the first symbol matching the reference, or a sentinel far-away ...
bool LabelConnectsToWireOnSheet(const wxString &aPrefix, const wxString &aSheetName)
True when a global label whose text starts with the prefix sits on a wire endpoint on the named sheet...
SCH_SHEET * LoadDipTraceSchematic(const std::string &aFilePath)
int CountJunctionsOnSheet(const wxString &aSheetName)
Count junctions on the sheet with the given name.
int CountSymbolShapes(const wxString &aRefdes, SHAPE_T aShapeType)
Count the library-symbol graphic shapes of a given type for the first matching reference.
int CountSheetGraphicLines(const wxString &aSheetName, const VECTOR2I &aStart, const VECTOR2I &aEnd, int aWidth)
int CountSymbolsForRefdesOnSheet(const wxString &aRefdes, const wxString &aSheetName)
int CountLinesOnSheet(const wxString &aSheetName)
Count SCH_LINE items on the DipTrace sheet with the given name.
bool LoadDchXmlCounts(const std::string &aXmlPath, DCH_XML_COUNTS &aCounts)
FIELD_T
The set of all field indices assuming an array like sequence that a SCH_COMPONENT or LIB_PART can hol...
@ FOOTPRINT
Field Name Module PCB, i.e. "16DIP300".
@ REFERENCE
Field Reference of part, i.e. "IC21".
@ VALUE
Field Value of part, i.e. "3.3K".
KIBIS_PIN * pin
KICAD_T
The set of class identification values stored in EDA_ITEM::m_structType.
Definition typeinfo.h:71
@ SCH_LINE_T
Definition typeinfo.h:160
@ SCH_SYMBOL_T
Definition typeinfo.h:169
@ SCH_SHAPE_T
Definition typeinfo.h:146
@ SCH_GLOBAL_LABEL_T
Definition typeinfo.h:165
@ SCH_JUNCTION_T
Definition typeinfo.h:156
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:683