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, you may find one here:
18 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
19 * or you may search the http://www.gnu.org website for the version 2 license,
20 * or you may write to the Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
22 */
23
24#ifndef TEST_DIPTRACE_SCH_IMPORT_FIXTURE_H
25#define TEST_DIPTRACE_SCH_IMPORT_FIXTURE_H
26
31
33
36
37#include <connection_graph.h>
38#include <eeschema_helpers.h>
39#include <sch_connection.h>
40#include <sch_label.h>
41#include <sch_line.h>
42#include <sch_pin.h>
43#include <sch_screen.h>
44#include <sch_shape.h>
45#include <sch_sheet_path.h>
46#include <sch_symbol.h>
47#include <schematic.h>
49
50#include <lib_symbol.h>
51
52#include <climits>
53
54#include <algorithm>
55#include <cmath>
56#include <cstdlib>
57#include <filesystem>
58#include <memory>
59#include <set>
60#include <sstream>
61#include <vector>
62
63#include <reporter.h>
64
65#include <wx/filefn.h>
66#include <wx/ffile.h>
67#include <wx/xml/xml.h>
68
69
73{
74public:
75 REPORTER& Report( const wxString& aText, SEVERITY aSeverity = RPT_SEVERITY_UNDEFINED ) override
76 {
77 m_messages.emplace_back( aSeverity, aText );
78 return *this;
79 }
80
81 bool HasMessage() const override { return !m_messages.empty(); }
82
83 int CountOfSeverity( int aSeverityMask ) const
84 {
85 int n = 0;
86
87 for( const auto& [sev, text] : m_messages )
88 {
89 if( sev & aSeverityMask )
90 n++;
91 }
92
93 return n;
94 }
95
96 std::string MessagesOfSeverity( int aSeverityMask ) const
97 {
98 std::ostringstream out;
99
100 for( const auto& [sev, text] : m_messages )
101 {
102 if( !( sev & aSeverityMask ) )
103 continue;
104
105 if( out.tellp() > 0 )
106 out << "; ";
107
108 out << text.ToStdString();
109 }
110
111 return out.str();
112 }
113
114 void Clear() override { m_messages.clear(); }
115
116 std::vector<std::pair<SEVERITY, wxString>> m_messages;
117};
118
119
121{
123 m_schematic( new SCHEMATIC( nullptr ) )
124 {
125 m_manager.LoadProject( "" );
126 m_schematic->SetProject( &m_manager.Prj() );
127 m_schematic->CurrentSheet().clear();
128 m_schematic->CurrentSheet().push_back( &m_schematic->Root() );
129 }
130
132 std::unique_ptr<SCHEMATIC> m_schematic;
136
137 std::string GetTestDataDir() { return KI_TEST::GetEeschemaTestDataDir() + "plugins/diptrace/"; }
138
140 {
141 const char* examplesEnv = std::getenv( "DIPTRACE_VIEWER_EXAMPLES_DIR" );
142
143 return examplesEnv && *examplesEnv ? examplesEnv : "/home/seth/Downloads/DipTrace Viewer/Examples";
144 }
145
147 {
148 std::set<SCH_SCREEN*> seenScreens;
149 int count = 0;
150
151 for( const SCH_SHEET_PATH& sheetPath : m_schematic->BuildUnorderedSheetList() )
152 {
153 SCH_SCREEN* screen = sheetPath.LastScreen();
154
155 if( !screen || !seenScreens.insert( screen ).second )
156 continue;
157
158 for( SCH_ITEM* item : screen->Items() )
159 {
160 if( item->Type() == aType )
161 count++;
162 }
163 }
164
165 return count;
166 }
167
169 {
170 std::set<SCH_SCREEN*> seenScreens;
171
172 for( const SCH_SHEET_PATH& sheetPath : m_schematic->BuildUnorderedSheetList() )
173 {
174 SCH_SCREEN* screen = sheetPath.LastScreen();
175
176 if( !screen || !seenScreens.insert( screen ).second )
177 continue;
178 }
179
180 return static_cast<int>( seenScreens.size() );
181 }
182
183 // Symbol references are resolved per sheet path through instance data, so iterate the
184 // hierarchy and match each symbol's path-resolved reference rather than its raw field text.
185 int MaxPinCountForRefdes( const wxString& aRefdes )
186 {
187 int maxPins = -1;
188
189 for( const SCH_SHEET_PATH& sheetPath : m_schematic->BuildUnorderedSheetList() )
190 {
191 SCH_SCREEN* screen = sheetPath.LastScreen();
192
193 if( !screen )
194 continue;
195
196 for( SCH_ITEM* item : screen->Items().OfType( SCH_SYMBOL_T ) )
197 {
198 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
199
200 if( symbol->GetRef( &sheetPath, false ) == aRefdes )
201 maxPins = std::max( maxPins, static_cast<int>( symbol->GetPins().size() ) );
202 }
203 }
204
205 return maxPins;
206 }
207
208 wxString GetFootprintForRefdes( const wxString& aRefdes )
209 {
210 for( const SCH_SHEET_PATH& sheetPath : m_schematic->BuildUnorderedSheetList() )
211 {
212 SCH_SCREEN* screen = sheetPath.LastScreen();
213
214 if( !screen )
215 continue;
216
217 for( SCH_ITEM* item : screen->Items().OfType( SCH_SYMBOL_T ) )
218 {
219 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
220
221 if( symbol->GetRef( &sheetPath, false ) == aRefdes )
222 {
223 SCH_FIELD* fpField = symbol->GetField( FIELD_T::FOOTPRINT );
224 return fpField ? fpField->GetText() : wxString();
225 }
226 }
227 }
228
229 return wxString();
230 }
231
233 wxString GetSheetNameForRefdes( const wxString& aRefdes )
234 {
235 for( const SCH_SHEET_PATH& sheetPath : m_schematic->BuildUnorderedSheetList() )
236 {
237 SCH_SCREEN* screen = sheetPath.LastScreen();
238
239 if( !screen )
240 continue;
241
242 for( SCH_ITEM* item : screen->Items().OfType( SCH_SYMBOL_T ) )
243 {
244 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
245
246 if( symbol->GetRef( &sheetPath, false ) == aRefdes )
247 return sheetPath.Last() ? sheetPath.Last()->GetName() : wxString();
248 }
249 }
250
251 return wxString();
252 }
253
256 void PinOrientationCounts( const wxString& aRefdes, int& aLeft, int& aRight, int& aUp, int& aDown )
257 {
258 aLeft = aRight = aUp = aDown = 0;
259
260 for( const SCH_SHEET_PATH& sheetPath : m_schematic->BuildUnorderedSheetList() )
261 {
262 SCH_SCREEN* screen = sheetPath.LastScreen();
263
264 if( !screen )
265 continue;
266
267 for( SCH_ITEM* item : screen->Items().OfType( SCH_SYMBOL_T ) )
268 {
269 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
270
271 if( symbol->GetRef( &sheetPath, false ) != aRefdes || !symbol->GetLibSymbolRef() )
272 continue;
273
274 for( SCH_PIN* pin : symbol->GetLibSymbolRef()->GetPins() )
275 {
276 switch( pin->GetOrientation() )
277 {
278 case PIN_ORIENTATION::PIN_LEFT: aLeft++; break;
279 case PIN_ORIENTATION::PIN_RIGHT: aRight++; break;
280 case PIN_ORIENTATION::PIN_UP: aUp++; break;
281 case PIN_ORIENTATION::PIN_DOWN: aDown++; break;
282 default: break;
283 }
284 }
285
286 return;
287 }
288 }
289 }
290
294 bool HasLabelOnSheet( const wxString& aText, const wxString& aSheetName )
295 {
296 for( const SCH_SHEET_PATH& sheetPath : m_schematic->BuildUnorderedSheetList() )
297 {
298 if( !sheetPath.Last() || sheetPath.Last()->GetName() != aSheetName )
299 continue;
300
301 SCH_SCREEN* screen = sheetPath.LastScreen();
302
303 if( !screen )
304 continue;
305
306 for( SCH_ITEM* item : screen->Items().OfType( SCH_GLOBAL_LABEL_T ) )
307 {
308 SCH_LABEL_BASE* label = static_cast<SCH_LABEL_BASE*>( item );
309
310 if( label->GetText() == aText )
311 return true;
312 }
313 }
314
315 return false;
316 }
317
321 bool HasLabelStartingWithOnSheet( const wxString& aPrefix, const wxString& aSheetName )
322 {
323 for( const SCH_SHEET_PATH& sheetPath : m_schematic->BuildUnorderedSheetList() )
324 {
325 if( !sheetPath.Last() || sheetPath.Last()->GetName() != aSheetName )
326 continue;
327
328 SCH_SCREEN* screen = sheetPath.LastScreen();
329
330 if( !screen )
331 continue;
332
333 for( SCH_ITEM* item : screen->Items().OfType( SCH_GLOBAL_LABEL_T ) )
334 {
335 SCH_LABEL_BASE* label = static_cast<SCH_LABEL_BASE*>( item );
336
337 if( label->GetText().StartsWith( aPrefix ) )
338 return true;
339 }
340 }
341
342 return false;
343 }
344
346 int CountLinesOnSheet( const wxString& aSheetName )
347 {
348 int lines = 0;
349
350 for( const SCH_SHEET_PATH& sheetPath : m_schematic->BuildUnorderedSheetList() )
351 {
352 if( !sheetPath.Last() || sheetPath.Last()->GetName() != aSheetName )
353 continue;
354
355 SCH_SCREEN* screen = sheetPath.LastScreen();
356
357 if( !screen )
358 continue;
359
360 for( SCH_ITEM* item : screen->Items().OfType( SCH_LINE_T ) )
361 {
362 static_cast<void>( item );
363 lines++;
364 }
365 }
366
367 return lines;
368 }
369
373 int RefValueFieldSeparation( const wxString& aRefdes )
374 {
375 for( const SCH_SHEET_PATH& sheetPath : m_schematic->BuildUnorderedSheetList() )
376 {
377 SCH_SCREEN* screen = sheetPath.LastScreen();
378
379 if( !screen )
380 continue;
381
382 for( SCH_ITEM* item : screen->Items().OfType( SCH_SYMBOL_T ) )
383 {
384 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
385
386 if( symbol->GetRef( &sheetPath, false ) != aRefdes )
387 continue;
388
389 SCH_FIELD* refField = symbol->GetField( FIELD_T::REFERENCE );
390 SCH_FIELD* valField = symbol->GetField( FIELD_T::VALUE );
391
392 if( !refField || !valField )
393 return -1;
394
395 return ( refField->GetPosition() - valField->GetPosition() ).EuclideanNorm();
396 }
397 }
398
399 return -1;
400 }
401
404 wxString GetFieldValueForRefdes( const wxString& aRefdes, const wxString& aFieldName )
405 {
406 for( const SCH_SHEET_PATH& sheetPath : m_schematic->BuildUnorderedSheetList() )
407 {
408 SCH_SCREEN* screen = sheetPath.LastScreen();
409
410 if( !screen )
411 continue;
412
413 for( SCH_ITEM* item : screen->Items().OfType( SCH_SYMBOL_T ) )
414 {
415 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
416
417 if( symbol->GetRef( &sheetPath, false ) != aRefdes )
418 continue;
419
420 const SCH_FIELD* field = symbol->GetField( aFieldName );
421 return field ? field->GetText() : wxString();
422 }
423 }
424
425 return wxString();
426 }
427
430 double ValueFieldAngleDegrees( const wxString& aRefdes )
431 {
432 for( const SCH_SHEET_PATH& sheetPath : m_schematic->BuildUnorderedSheetList() )
433 {
434 SCH_SCREEN* screen = sheetPath.LastScreen();
435
436 if( !screen )
437 continue;
438
439 for( SCH_ITEM* item : screen->Items().OfType( SCH_SYMBOL_T ) )
440 {
441 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
442
443 if( symbol->GetRef( &sheetPath, false ) != aRefdes )
444 continue;
445
446 const SCH_FIELD* field = symbol->GetField( FIELD_T::VALUE );
447 return field ? field->GetTextAngle().AsDegrees() : -1;
448 }
449 }
450
451 return -1;
452 }
453
456 int ShowsPinNames( const wxString& aRefdes )
457 {
458 for( const SCH_SHEET_PATH& sheetPath : m_schematic->BuildUnorderedSheetList() )
459 {
460 SCH_SCREEN* screen = sheetPath.LastScreen();
461
462 if( !screen )
463 continue;
464
465 for( SCH_ITEM* item : screen->Items().OfType( SCH_SYMBOL_T ) )
466 {
467 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
468
469 if( symbol->GetRef( &sheetPath, false ) != aRefdes || !symbol->GetLibSymbolRef() )
470 continue;
471
472 return symbol->GetLibSymbolRef()->GetShowPinNames() ? 1 : 0;
473 }
474 }
475
476 return -1;
477 }
478
480 int CountSymbolShapes( const wxString& aRefdes, SHAPE_T aShapeType )
481 {
482 for( const SCH_SHEET_PATH& sheetPath : m_schematic->BuildUnorderedSheetList() )
483 {
484 SCH_SCREEN* screen = sheetPath.LastScreen();
485
486 if( !screen )
487 continue;
488
489 for( SCH_ITEM* item : screen->Items().OfType( SCH_SYMBOL_T ) )
490 {
491 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
492
493 if( symbol->GetRef( &sheetPath, false ) != aRefdes || !symbol->GetLibSymbolRef() )
494 continue;
495
496 int count = 0;
497
498 for( const SCH_ITEM& draw : symbol->GetLibSymbolRef()->GetDrawItems() )
499 {
500 if( draw.Type() == SCH_SHAPE_T && static_cast<const SCH_SHAPE&>( draw ).GetShape() == aShapeType )
501 {
502 count++;
503 }
504 }
505
506 return count;
507 }
508 }
509
510 return -1;
511 }
512
513 int CountSymbolsForRefdesOnSheet( const wxString& aRefdes, const wxString& aSheetName )
514 {
515 int count = 0;
516
517 for( const SCH_SHEET_PATH& sheetPath : m_schematic->BuildUnorderedSheetList() )
518 {
519 if( !sheetPath.Last() || sheetPath.Last()->GetName() != aSheetName )
520 continue;
521
522 SCH_SCREEN* screen = sheetPath.LastScreen();
523
524 if( !screen )
525 continue;
526
527 for( SCH_ITEM* item : screen->Items().OfType( SCH_SYMBOL_T ) )
528 {
529 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
530
531 if( symbol->GetRef( &sheetPath, false ) == aRefdes )
532 count++;
533 }
534 }
535
536 return count;
537 }
538
539 static int DipTraceMmToSchIU( double aMm ) { return static_cast<int>( std::lround( aMm * 10000.0 ) ); }
540
541 static VECTOR2I DipTraceXmlSheetPointToKiCad( double aXmm, double aYmm )
542 {
543 return VECTOR2I( DipTraceMmToSchIU( 210.0 + aXmm ), DipTraceMmToSchIU( 148.5 - aYmm ) );
544 }
545
546 int CountSheetGraphicLines( const wxString& aSheetName, const VECTOR2I& aStart, const VECTOR2I& aEnd, int aWidth )
547 {
548 int count = 0;
549
550 for( const SCH_SHEET_PATH& sheetPath : m_schematic->BuildUnorderedSheetList() )
551 {
552 if( !sheetPath.Last() || sheetPath.Last()->GetName() != aSheetName )
553 continue;
554
555 SCH_SCREEN* screen = sheetPath.LastScreen();
556
557 if( !screen )
558 continue;
559
560 for( SCH_ITEM* item : screen->Items().OfType( SCH_SHAPE_T ) )
561 {
562 SCH_SHAPE* shape = static_cast<SCH_SHAPE*>( item );
563
564 if( shape->GetShape() != SHAPE_T::POLY || shape->GetStroke().GetWidth() != aWidth )
565 continue;
566
567 const KIGFX::COLOR4D color = shape->GetStroke().GetColor();
568
569 if( color.r > 0.01 || color.g > 0.01 || color.b < 0.99 )
570 continue;
571
572 const SHAPE_POLY_SET& poly = shape->GetPolyShape();
573
574 if( poly.TotalVertices() != 2 )
575 continue;
576
577 VECTOR2I p0 = poly.CVertex( 0 );
578 VECTOR2I p1 = poly.CVertex( 1 );
579
580 if( ( p0 == aStart && p1 == aEnd ) || ( p0 == aEnd && p1 == aStart ) )
581 count++;
582 }
583 }
584
585 return count;
586 }
587
588 int CountFilledPolysForRefdes( const wxString& aRefdes )
589 {
590 for( const SCH_SHEET_PATH& sheetPath : m_schematic->BuildUnorderedSheetList() )
591 {
592 SCH_SCREEN* screen = sheetPath.LastScreen();
593
594 if( !screen )
595 continue;
596
597 for( SCH_ITEM* item : screen->Items().OfType( SCH_SYMBOL_T ) )
598 {
599 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
600
601 if( symbol->GetRef( &sheetPath, false ) != aRefdes || !symbol->GetLibSymbolRef() )
602 continue;
603
604 int count = 0;
605
606 for( const SCH_ITEM& draw : symbol->GetLibSymbolRef()->GetDrawItems() )
607 {
608 if( draw.Type() == SCH_SHAPE_T && static_cast<const SCH_SHAPE&>( draw ).GetShape() == SHAPE_T::POLY
609 && static_cast<const SCH_SHAPE&>( draw ).GetFillMode() != FILL_T::NO_FILL )
610 {
611 count++;
612 }
613 }
614
615 return count;
616 }
617 }
618
619 return -1;
620 }
621
622 int CountOpenPolysWithPointCountForRefdes( const wxString& aRefdes, int aPointCount )
623 {
624 for( const SCH_SHEET_PATH& sheetPath : m_schematic->BuildUnorderedSheetList() )
625 {
626 SCH_SCREEN* screen = sheetPath.LastScreen();
627
628 if( !screen )
629 continue;
630
631 for( SCH_ITEM* item : screen->Items().OfType( SCH_SYMBOL_T ) )
632 {
633 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
634
635 if( symbol->GetRef( &sheetPath, false ) != aRefdes || !symbol->GetLibSymbolRef() )
636 continue;
637
638 int count = 0;
639
640 for( const SCH_ITEM& draw : symbol->GetLibSymbolRef()->GetDrawItems() )
641 {
642 if( draw.Type() != SCH_SHAPE_T )
643 continue;
644
645 const SCH_SHAPE& shape = static_cast<const SCH_SHAPE&>( draw );
646
647 if( shape.GetShape() == SHAPE_T::POLY && shape.GetFillMode() == FILL_T::NO_FILL
648 && shape.GetPolyShape().TotalVertices() == aPointCount )
649 {
650 count++;
651 }
652 }
653
654 return count;
655 }
656 }
657
658 return -1;
659 }
660
662 std::vector<int> UnitsForRefdesOnSheet( const wxString& aRefdes, const wxString& aSheetName )
663 {
664 std::vector<int> units;
665
666 for( const SCH_SHEET_PATH& sheetPath : m_schematic->BuildUnorderedSheetList() )
667 {
668 if( !sheetPath.Last() || sheetPath.Last()->GetName() != aSheetName )
669 continue;
670
671 SCH_SCREEN* screen = sheetPath.LastScreen();
672
673 if( !screen )
674 continue;
675
676 for( SCH_ITEM* item : screen->Items().OfType( SCH_SYMBOL_T ) )
677 {
678 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
679
680 if( symbol->GetRef( &sheetPath, false ) == aRefdes )
681 units.push_back( symbol->GetUnit() );
682 }
683 }
684
685 std::sort( units.begin(), units.end() );
686 return units;
687 }
688
690 int UnitCountForRefdes( const wxString& aRefdes )
691 {
692 for( const SCH_SHEET_PATH& sheetPath : m_schematic->BuildUnorderedSheetList() )
693 {
694 SCH_SCREEN* screen = sheetPath.LastScreen();
695
696 if( !screen )
697 continue;
698
699 for( SCH_ITEM* item : screen->Items().OfType( SCH_SYMBOL_T ) )
700 {
701 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
702
703 if( symbol->GetRef( &sheetPath, false ) == aRefdes )
704 return symbol->GetUnitCount();
705 }
706 }
707
708 return -1;
709 }
710
712 int LibPinCountForRefdesUnitOnSheet( const wxString& aRefdes, const wxString& aSheetName, int aUnit )
713 {
714 for( const SCH_SHEET_PATH& sheetPath : m_schematic->BuildUnorderedSheetList() )
715 {
716 if( !sheetPath.Last() || sheetPath.Last()->GetName() != aSheetName )
717 continue;
718
719 SCH_SCREEN* screen = sheetPath.LastScreen();
720
721 if( !screen )
722 continue;
723
724 for( SCH_ITEM* item : screen->Items().OfType( SCH_SYMBOL_T ) )
725 {
726 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
727
728 if( symbol->GetRef( &sheetPath, false ) == aRefdes && symbol->GetUnit() == aUnit )
729 return static_cast<int>( symbol->GetLibPins().size() );
730 }
731 }
732
733 return -1;
734 }
735
737 std::set<wxString> LibPinNamesForRefdesUnitOnSheet( const wxString& aRefdes, const wxString& aSheetName, int aUnit )
738 {
739 for( const SCH_SHEET_PATH& sheetPath : m_schematic->BuildUnorderedSheetList() )
740 {
741 if( !sheetPath.Last() || sheetPath.Last()->GetName() != aSheetName )
742 continue;
743
744 SCH_SCREEN* screen = sheetPath.LastScreen();
745
746 if( !screen )
747 continue;
748
749 for( SCH_ITEM* item : screen->Items().OfType( SCH_SYMBOL_T ) )
750 {
751 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
752
753 if( symbol->GetRef( &sheetPath, false ) != aRefdes || symbol->GetUnit() != aUnit )
754 continue;
755
756 std::set<wxString> names;
757
758 for( SCH_PIN* pin : symbol->GetLibPins() )
759 names.insert( pin->GetName() );
760
761 return names;
762 }
763 }
764
765 return {};
766 }
767
769 int CountJunctionsOnSheet( const wxString& aSheetName )
770 {
771 int count = 0;
772
773 for( const SCH_SHEET_PATH& sheetPath : m_schematic->BuildUnorderedSheetList() )
774 {
775 if( !sheetPath.Last() || sheetPath.Last()->GetName() != aSheetName )
776 continue;
777
778 SCH_SCREEN* screen = sheetPath.LastScreen();
779
780 if( !screen )
781 continue;
782
783 for( SCH_ITEM* item : screen->Items().OfType( SCH_JUNCTION_T ) )
784 {
785 static_cast<void>( item );
786 count++;
787 }
788 }
789
790 return count;
791 }
792
795 VECTOR2I FieldPosForRefdes( const wxString& aRefdes, FIELD_T aFieldType )
796 {
797 for( const SCH_SHEET_PATH& sheetPath : m_schematic->BuildUnorderedSheetList() )
798 {
799 SCH_SCREEN* screen = sheetPath.LastScreen();
800
801 if( !screen )
802 continue;
803
804 for( SCH_ITEM* item : screen->Items().OfType( SCH_SYMBOL_T ) )
805 {
806 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
807
808 if( symbol->GetRef( &sheetPath, false ) != aRefdes )
809 continue;
810
811 if( SCH_FIELD* field = symbol->GetField( aFieldType ) )
812 return field->GetPosition();
813 }
814 }
815
816 return VECTOR2I( INT_MAX, INT_MAX );
817 }
818
821 int FieldHorizJustify( const wxString& aRefdes, FIELD_T aFieldType )
822 {
823 for( const SCH_SHEET_PATH& sheetPath : m_schematic->BuildUnorderedSheetList() )
824 {
825 SCH_SCREEN* screen = sheetPath.LastScreen();
826
827 if( !screen )
828 continue;
829
830 for( SCH_ITEM* item : screen->Items().OfType( SCH_SYMBOL_T ) )
831 {
832 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
833
834 if( symbol->GetRef( &sheetPath, false ) != aRefdes )
835 continue;
836
837 if( SCH_FIELD* field = symbol->GetField( aFieldType ) )
838 return static_cast<int>( field->GetHorizJustify() );
839 }
840 }
841
842 return 99;
843 }
844
846 int CountLabelsOnSheet( const wxString& aText, const wxString& aSheetName )
847 {
848 int count = 0;
849
850 for( const SCH_SHEET_PATH& sheetPath : m_schematic->BuildUnorderedSheetList() )
851 {
852 if( !sheetPath.Last() || sheetPath.Last()->GetName() != aSheetName )
853 continue;
854
855 SCH_SCREEN* screen = sheetPath.LastScreen();
856
857 if( !screen )
858 continue;
859
860 for( SCH_ITEM* item : screen->Items().OfType( SCH_GLOBAL_LABEL_T ) )
861 {
862 if( static_cast<SCH_LABEL_BASE*>( item )->GetText() == aText )
863 count++;
864 }
865 }
866
867 return count;
868 }
869
873 bool LabelConnectsToWireOnSheet( const wxString& aPrefix, const wxString& aSheetName )
874 {
875 for( const SCH_SHEET_PATH& sheetPath : m_schematic->BuildUnorderedSheetList() )
876 {
877 if( !sheetPath.Last() || sheetPath.Last()->GetName() != aSheetName )
878 continue;
879
880 SCH_SCREEN* screen = sheetPath.LastScreen();
881
882 if( !screen )
883 continue;
884
885 for( SCH_ITEM* labelItem : screen->Items().OfType( SCH_GLOBAL_LABEL_T ) )
886 {
887 SCH_LABEL_BASE* label = static_cast<SCH_LABEL_BASE*>( labelItem );
888
889 if( !label->GetText().StartsWith( aPrefix ) )
890 continue;
891
892 VECTOR2I anchor = label->GetPosition();
893
894 for( SCH_ITEM* lineItem : screen->Items().OfType( SCH_LINE_T ) )
895 {
896 SCH_LINE* line = static_cast<SCH_LINE*>( lineItem );
897
898 if( line->GetStartPoint() == anchor || line->GetEndPoint() == anchor )
899 return true;
900 }
901 }
902 }
903
904 return false;
905 }
906
908 {
909 int partCount = 0;
910 int netPortCount = 0;
911 int sheetCount = 0;
912 };
913
914 static bool XmlSubtreeContains( wxXmlNode* aNode, const wxString& aNeedle )
915 {
916 for( wxXmlNode* n = aNode; n; n = n->GetNext() )
917 {
918 if( n->GetType() == wxXML_TEXT_NODE && n->GetContent().Contains( aNeedle ) )
919 return true;
920
921 if( XmlSubtreeContains( n->GetChildren(), aNeedle ) )
922 return true;
923 }
924
925 return false;
926 }
927
928 bool LoadDchXmlCounts( const std::string& aXmlPath, DCH_XML_COUNTS& aCounts )
929 {
930 if( !wxFileExists( aXmlPath ) )
931 return false;
932
933 wxXmlDocument doc;
934
935 if( !doc.Load( aXmlPath ) )
936 return false;
937
938 wxXmlNode* root = doc.GetRoot();
939
940 if( !root || root->GetName() != "Source" )
941 return false;
942
943 wxXmlNode* schematicNode = nullptr;
944
945 for( wxXmlNode* child = root->GetChildren(); child; child = child->GetNext() )
946 {
947 if( child->GetType() == wxXML_ELEMENT_NODE && child->GetName() == "Schematic" )
948 {
949 schematicNode = child;
950 break;
951 }
952 }
953
954 if( !schematicNode )
955 return false;
956
957 int partCount = 0;
958 int netPortCount = 0;
959 int sheetCount = 0;
960 std::vector<wxXmlNode*> stack = { schematicNode };
961
962 while( !stack.empty() )
963 {
964 wxXmlNode* node = stack.back();
965 stack.pop_back();
966
967 if( !node || node->GetType() != wxXML_ELEMENT_NODE )
968 continue;
969
970 if( node->GetName() == "Part" )
971 {
972 partCount++;
973
974 // Net-port placements carry an auto_net_ports library reference; the importer maps
975 // these to global labels rather than symbols, so count them the same way here.
976 if( XmlSubtreeContains( node->GetChildren(), wxT( "auto_net_ports" ) ) )
977 netPortCount++;
978 }
979 else if( node->GetName() == "Sheet" )
980 {
981 sheetCount++;
982 }
983
984 for( wxXmlNode* child = node->GetChildren(); child; child = child->GetNext() )
985 {
986 stack.push_back( child );
987 }
988 }
989
990 aCounts.partCount = partCount;
991 aCounts.netPortCount = netPortCount;
992 aCounts.sheetCount = sheetCount;
993 return true;
994 }
995
996 SCH_SHEET* LoadDipTraceSchematic( const std::string& aFilePath )
997 {
998 m_schematic.reset( new SCHEMATIC( nullptr ) );
999 m_manager.LoadProject( "" );
1000 m_schematic->SetProject( &m_manager.Prj() );
1001 m_schematic->CurrentSheet().clear();
1002 m_schematic->CurrentSheet().push_back( &m_schematic->Root() );
1003
1004 m_reporter.Clear();
1005 m_plugin.SetReporter( &m_reporter );
1006 m_loadedRoot = m_plugin.LoadSchematicFile( aFilePath, m_schematic.get() );
1007 return m_loadedRoot;
1008 }
1009
1010 void RemoveGeneratedLibrary( const std::string& aFilePath )
1011 {
1012 wxFileName genLib( aFilePath );
1013 genLib.SetName( genLib.GetName() + wxT( "-diptrace-import" ) );
1014 genLib.SetExt( wxT( "kicad_sym" ) );
1015
1016 if( genLib.FileExists() )
1017 wxRemoveFile( genLib.GetFullPath() );
1018 }
1019};
1020
1021#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:162
SHAPE_POLY_SET & GetPolyShape()
SHAPE_T GetShape() const
Definition eda_shape.h:189
const EDA_ANGLE & GetTextAngle() const
Definition eda_text.h:172
virtual const wxString & GetText() const
Return the string associated with the text object.
Definition eda_text.h:114
EE_TYPE OfType(KICAD_T aType) const
Definition sch_rtree.h:225
A color representation with 4 components: red, green, blue, alpha.
Definition color4d.h:105
double r
Red component.
Definition color4d.h:393
double g
Green component.
Definition color4d.h:394
double b
Blue component.
Definition color4d.h:395
LIB_ITEMS_CONTAINER & GetDrawItems()
Return a reference to the draw item list.
Definition lib_symbol.h:713
std::vector< SCH_PIN * > GetPins() const override
REPORTER()
Definition reporter.h:77
Holds all the data relating to one schematic.
Definition schematic.h:89
VECTOR2I GetPosition() const override
virtual const wxString & GetText() const override
Return the string associated with the text object.
Definition sch_field.h:132
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:166
int GetUnit() const
Definition sch_item.h:237
Segment description base class to describe items which have 2 end points (track, wire,...
Definition sch_line.h:42
VECTOR2I GetEndPoint() const
Definition sch_line.h:148
VECTOR2I GetStartPoint() const
Definition sch_line.h:139
EE_RTREE & Items()
Get the full RTree, usually for iterating.
Definition sch_screen.h:119
STROKE_PARAMS GetStroke() const override
Definition sch_shape.h:61
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:48
Schematic symbol object.
Definition sch_symbol.h:73
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:889
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:181
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:150
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:169
SHAPE_T
Definition eda_shape.h:48
@ NO_FILL
Definition eda_shape.h:64
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:127
@ PIN_RIGHT
The pin extends rightwards from the connection point.
Definition pin_type.h:111
@ PIN_LEFT
The pin extends leftwards from the connection point: Probably on the right side of the symbol.
Definition pin_type.h:118
@ PIN_DOWN
The pin extends downwards from the connection: Probably on the top side of the symbol.
Definition pin_type.h:135
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:75
@ SCH_LINE_T
Definition typeinfo.h:164
@ SCH_SYMBOL_T
Definition typeinfo.h:173
@ SCH_SHAPE_T
Definition typeinfo.h:150
@ SCH_GLOBAL_LABEL_T
Definition typeinfo.h:169
@ SCH_JUNCTION_T
Definition typeinfo.h:160
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:687