KiCad PCB EDA Suite
sch_screen.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) 2013 Jean-Pierre Charras, jp.charras at wanadoo.fr
5 * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <[email protected]>
6 * Copyright (C) 2008 Wayne Stambaugh <[email protected]>
7 * Copyright (C) 1992-2022 KiCad Developers, see AUTHORS.txt for contributors.
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version 2
12 * of the License, or (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, you may find one here:
21 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
22 * or you may search the http://www.gnu.org website for the version 2 license,
23 * or you may write to the Free Software Foundation, Inc.,
24 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
25 */
26
27#include <wx/filefn.h>
28
29#include <eda_item.h>
30#include <id.h>
31#include <string_utils.h>
32#include <kiway.h>
33#include <plotters/plotter.h>
34#include <project.h>
35#include <reporter.h>
36#include <sch_draw_panel.h>
37#include <sch_edit_frame.h>
38#include <sch_item.h>
39
40#include <symbol_library.h>
41#include <connection_graph.h>
42#include <lib_item.h>
43#include <lib_pin.h>
44#include <lib_shape.h>
45#include <sch_symbol.h>
46#include <sch_junction.h>
47#include <sch_line.h>
48#include <sch_marker.h>
49#include <sch_sheet.h>
50#include <sch_sheet_pin.h>
51#include <sch_text.h>
52#include <schematic.h>
53#include <symbol_lib_table.h>
54#include <tool/common_tools.h>
55
56#include <algorithm>
57
58// TODO(JE) Debugging only
59#include <profile.h>
60#include "sch_bus_entry.h"
61
63 BASE_SCREEN( aParent, SCH_SCREEN_T ),
64 m_fileFormatVersionAtLoad( 0 ),
65 m_paper( wxT( "A4" ) ),
66 m_isReadOnly( false ),
67 m_fileExists( false )
68{
70 m_refCount = 0;
71 m_zoomInitialized = false;
72 m_LastZoomLevel = 1.0;
73
74 // Suitable for schematic only. For symbol_editor and viewlib, must be set to true
75 m_Center = false;
76
78}
79
80
82{
85}
86
87
89{
90 wxCHECK_MSG( GetParent() && GetParent()->Type() == SCHEMATIC_T, nullptr,
91 wxT( "SCH_SCREEN must have a SCHEMATIC parent!" ) );
92
93 return static_cast<SCHEMATIC*>( GetParent() );
94}
95
96
98{
99 for( const std::pair<const wxString, LIB_SYMBOL*>& libSymbol : m_libSymbols )
100 delete libSymbol.second;
101
102 m_libSymbols.clear();
103}
104
105
106void SCH_SCREEN::SetFileName( const wxString& aFileName )
107{
108 wxASSERT( aFileName.IsEmpty() || wxIsAbsolutePath( aFileName ) );
109
110 m_fileName = aFileName;
111}
112
113
115{
116 m_refCount++;
117}
118
119
121{
122 wxCHECK_RET( m_refCount != 0, wxT( "Screen reference count already zero. Bad programmer!" ) );
123 m_refCount--;
124}
125
126
127bool SCH_SCREEN::HasItems( KICAD_T aItemType ) const
128{
129 EE_RTREE::EE_TYPE sheets = m_rtree.OfType( aItemType );
130
131 return sheets.begin() != sheets.end();
132}
133
134
135bool SCH_SCREEN::ClassOf( const EDA_ITEM* aItem )
136{
137 return aItem && SCH_SCREEN_T == aItem->Type();
138}
139
140
142{
143 if( aItem->Type() != SCH_SHEET_PIN_T && aItem->Type() != SCH_FIELD_T )
144 {
145 // Ensure the item can reach the SCHEMATIC through this screen
146 aItem->SetParent( this );
147
148 if( aItem->Type() == SCH_SYMBOL_T )
149 {
150 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( aItem );
151
152 if( symbol->GetLibSymbolRef() )
153 {
154 symbol->GetLibSymbolRef()->GetDrawItems().sort();
155
156 auto it = m_libSymbols.find( symbol->GetSchSymbolLibraryName() );
157
158 if( it == m_libSymbols.end() || !it->second )
159 {
161 new LIB_SYMBOL( *symbol->GetLibSymbolRef() );
162 }
163 else
164 {
165 // The original library symbol may have changed since the last time
166 // it was added to the schematic. If it has changed, then a new name
167 // must be created for the library symbol list to prevent all of the
168 // other schematic symbols referencing that library symbol from changing.
169 LIB_SYMBOL* foundSymbol = it->second;
170
171 foundSymbol->GetDrawItems().sort();
172
173 if( *foundSymbol != *symbol->GetLibSymbolRef() )
174 {
175 int cnt = 1;
176 wxString newName;
177
178 newName.Printf( "%s_%d", symbol->GetLibId().GetUniStringLibItemName(),
179 cnt );
180
181 while( m_libSymbols.find( newName ) != m_libSymbols.end() )
182 {
183 cnt += 1;
184 newName.Printf( "%s_%d", symbol->GetLibId().GetUniStringLibItemName(),
185 cnt );
186 }
187
188 // Update the schematic symbol library link as this symbol only exists
189 // in the schematic.
190 symbol->SetSchSymbolLibraryName( newName );
191
192 LIB_SYMBOL* newLibSymbol = new LIB_SYMBOL( *symbol->GetLibSymbolRef() );
193 LIB_ID newLibId( wxEmptyString, newName );
194
195 newLibSymbol->SetLibId( newLibId );
196 newLibSymbol->SetName( newName );
197 symbol->SetLibSymbol( newLibSymbol->Flatten().release() );
198 m_libSymbols[newName] = newLibSymbol;
199 }
200 }
201 }
202 }
203
204 m_rtree.insert( aItem );
206 }
207}
208
209
211{
212 wxCHECK_RET( aScreen, "Invalid screen object." );
213
214 // No need to descend the hierarchy. Once the top level screen is copied, all of its
215 // children are copied as well.
216 for( SCH_ITEM* aItem : aScreen->m_rtree )
217 Append( aItem );
218
219 aScreen->Clear( false );
220}
221
222
223void SCH_SCREEN::Clear( bool aFree )
224{
225 if( aFree )
226 {
227 FreeDrawList();
229 }
230 else
231 {
232 m_rtree.clear();
233 }
234
235 // Clear the project settings
237
238 m_titles.Clear();
239}
240
241
243{
244 // We don't know which order we will encounter dependent items (e.g. pins or fields), so
245 // we store the items to be deleted until we've fully cleared the tree before deleting
246 std::vector<SCH_ITEM*> delete_list;
247
248 std::copy_if( m_rtree.begin(), m_rtree.end(), std::back_inserter( delete_list ),
249 []( SCH_ITEM* aItem )
250 {
251 return ( aItem->Type() != SCH_SHEET_PIN_T && aItem->Type() != SCH_FIELD_T );
252 } );
253
254 m_rtree.clear();
255
256 for( SCH_ITEM* item : delete_list )
257 delete item;
258}
259
260
262{
263 if( Remove( aItem ) )
264 Append( aItem );
265}
266
267
269{
270 bool retv = m_rtree.remove( aItem );
271
272 // Check if the library symbol for the removed schematic symbol is still required.
273 if( retv && aItem->Type() == SCH_SYMBOL_T )
274 {
275 SCH_SYMBOL* removedSymbol = static_cast<SCH_SYMBOL*>( aItem );
276
277 bool removeUnusedLibSymbol = true;
278
279 for( SCH_ITEM* item : Items().OfType( SCH_SYMBOL_T ) )
280 {
281 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
282
283 if( removedSymbol->GetSchSymbolLibraryName() == symbol->GetSchSymbolLibraryName() )
284 {
285 removeUnusedLibSymbol = false;
286 break;
287 }
288 }
289
290 if( removeUnusedLibSymbol )
291 {
292 auto it = m_libSymbols.find( removedSymbol->GetSchSymbolLibraryName() );
293
294 if( it != m_libSymbols.end() )
295 {
296 delete it->second;
297 m_libSymbols.erase( it );
298 }
299 }
300 }
301
302 return retv;
303}
304
305
307{
308 wxCHECK_RET( aItem, wxT( "Cannot delete invalid item from screen." ) );
309
310 // Markers are not saved in the file, no need to flag as modified.
311 // TODO: Maybe we should have a listing somewhere of items that aren't saved?
312 if( aItem->Type() != SCH_MARKER_T )
314
315 Remove( aItem );
316
317 if( aItem->Type() == SCH_SHEET_PIN_T )
318 {
319 // This structure is attached to a sheet, get the parent sheet object.
320 SCH_SHEET_PIN* sheetPin = (SCH_SHEET_PIN*) aItem;
321 SCH_SHEET* sheet = sheetPin->GetParent();
322 wxCHECK_RET( sheet, wxT( "Sheet pin parent not properly set, bad programmer!" ) );
323 sheet->RemovePin( sheetPin );
324 return;
325 }
326
327 delete aItem;
328}
329
330
331bool SCH_SCREEN::CheckIfOnDrawList( const SCH_ITEM* aItem ) const
332{
333 return m_rtree.contains( aItem, true );
334}
335
336
337SCH_ITEM* SCH_SCREEN::GetItem( const VECTOR2I& aPosition, int aAccuracy, KICAD_T aType ) const
338{
339 BOX2I bbox;
340 bbox.SetOrigin( aPosition );
341 bbox.Inflate( aAccuracy );
342
343 for( SCH_ITEM* item : Items().Overlapping( aType, bbox ) )
344 {
345 if( item->HitTest( aPosition, aAccuracy ) )
346 return item;
347 }
348
349 return nullptr;
350}
351
352
353std::set<SCH_ITEM*> SCH_SCREEN::MarkConnections( SCH_LINE* aSegment, bool aSecondPass )
354{
355#define PROCESSED CANDIDATE // Don't use SKIP_STRUCT; IsConnected() returns false if it's set.
356
357 std::set<SCH_ITEM*> retval;
358 std::stack<SCH_LINE*> to_search;
359
360 wxCHECK_MSG( aSegment && aSegment->Type() == SCH_LINE_T, retval, wxT( "Invalid pointer." ) );
361
362 to_search.push( aSegment );
363
364 while( !to_search.empty() )
365 {
366 SCH_ITEM* item = to_search.top();
367 to_search.pop();
368
369 if( item->HasFlag( PROCESSED ) )
370 continue;
371
372 item->SetFlags( PROCESSED );
373
374 for( SCH_ITEM* candidate : Items().Overlapping( SCH_LINE_T, item->GetBoundingBox() ) )
375 {
376 SCH_LINE* line = static_cast<SCH_LINE*>( candidate );
377
378 if( line->HasFlag( PROCESSED ) )
379 continue;
380
381 // Skip connecting lines on different layers (e.g. buses)
382 if( item->GetLayer() != line->GetLayer() )
383 continue;
384
385 for( VECTOR2I pt : { line->GetStartPoint(), line->GetEndPoint() } )
386 {
387 if( item->IsConnected( pt ) )
388 {
389 SCH_ITEM* junction = GetItem( pt, 0, SCH_JUNCTION_T );
390 SCH_ITEM* pin = GetItem( pt, 0, SCH_PIN_T );
391
392 if( item->IsSelected() && aSecondPass )
393 {
394 if( junction )
395 retval.insert( junction );
396
397 retval.insert( line );
398 to_search.push( line );
399 }
400 else if( !junction && !pin )
401 {
402 retval.insert( line );
403 to_search.push( line );
404 }
405
406 break;
407 }
408 }
409 }
410 }
411
412 for( SCH_ITEM* item : Items() )
413 item->ClearTempFlags();
414
415 return retval;
416}
417
418
419bool SCH_SCREEN::IsJunction( const VECTOR2I& aPosition ) const
420{
421 bool hasExplicitJunction;
422 bool hasBusEntry;
423 bool isJunction = doIsJunction( aPosition, false, &hasExplicitJunction, &hasBusEntry );
424
425 return isJunction;
426}
427
428
429bool SCH_SCREEN::IsExplicitJunction( const VECTOR2I& aPosition ) const
430{
431 bool hasExplicitJunction;
432 bool hasBusEntry;
433 bool isJunction = doIsJunction( aPosition, false, &hasExplicitJunction, &hasBusEntry );
434
435 return isJunction && !hasBusEntry;
436}
437
438
439bool SCH_SCREEN::IsExplicitJunctionNeeded( const VECTOR2I& aPosition ) const
440{
441 bool hasExplicitJunction;
442 bool hasBusEntry;
443 bool isJunction = doIsJunction( aPosition, false, &hasExplicitJunction, &hasBusEntry );
444
445 return isJunction && !hasBusEntry && !hasExplicitJunction;
446}
447
449 TEXT_SPIN_STYLE aDefaultOrientation,
450 const SCH_SHEET_PATH* aSheet ) const
451{
452 auto ret = aDefaultOrientation;
453 for( SCH_ITEM* item : Items().Overlapping( aPosition ) )
454 {
455 if( item->GetEditFlags() & STRUCT_DELETED )
456 continue;
457
458 switch( item->Type() )
459 {
461 {
462 auto busEntry = static_cast<const SCH_BUS_WIRE_ENTRY*>( item );
463 if( busEntry->m_connected_bus_item )
464 {
465 // bus connected, take the bus direction into consideration ony if it is
466 // vertical or horizontal
467 auto bus = static_cast<const SCH_LINE*>( busEntry->m_connected_bus_item );
468 if( bus->Angle().AsDegrees() == 90.0 )
469 {
470 // bus is vertical -> label shall be horizontal and
471 // shall be placed to the side where the bus entry is
472 if( aPosition.x < bus->GetPosition().x )
474 else if( aPosition.x > bus->GetPosition().x )
476 }
477 else if( bus->Angle().AsDegrees() == 0.0 )
478 {
479 // bus is horizontal -> label shall be vertical and
480 // shall be placed to the side where the bus entry is
481 if( aPosition.y < bus->GetPosition().y )
483 else if( aPosition.y > bus->GetPosition().y )
485 }
486 }
487 }
488 break;
489
490 case SCH_LINE_T:
491 {
492 auto line = static_cast<const SCH_LINE*>( item );
493 // line angles goes between -90 and 90 degrees, but normalize
494 auto angle = line->Angle().Normalize90().AsDegrees();
495
496 if( -45 < angle && angle <= 45 )
497 {
498 if( line->GetStartPoint().x <= line->GetEndPoint().x )
499 {
500 ret = line->GetEndPoint() == aPosition ? TEXT_SPIN_STYLE::RIGHT
502 }
503 else
504 {
505 ret = line->GetEndPoint() == aPosition ? TEXT_SPIN_STYLE::LEFT
507 }
508 }
509 else
510 {
511 if( line->GetStartPoint().y <= line->GetEndPoint().y )
512 {
513 ret = line->GetEndPoint() == aPosition ? TEXT_SPIN_STYLE::BOTTOM
515 }
516 else
517 {
518 ret = line->GetEndPoint() == aPosition ? TEXT_SPIN_STYLE::UP
520 }
521 }
522 }
523 break;
524
525 case SCH_SYMBOL_T:
526 {
527 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
528
529 for( SCH_PIN* pin : symbol->GetPins( aSheet ) )
530 {
531 if( pin->GetPosition() == aPosition )
532 {
533 if( pin->GetOrientation() == PIN_RIGHT )
534 {
536 }
537 else if( pin->GetOrientation() == PIN_LEFT )
538 {
540 }
541 else if( pin->GetOrientation() == PIN_UP )
542 {
544 }
545 else if( pin->GetOrientation() == PIN_DOWN )
546 {
548 }
549
550 switch( static_cast<SYMBOL_ORIENTATION_T>(
551 symbol->GetOrientation() & ( ~( SYM_MIRROR_X | SYM_MIRROR_Y ) ) ) )
552 {
554 case SYM_ORIENT_90:
555 if( ret == TEXT_SPIN_STYLE::UP )
557 else if( ret == TEXT_SPIN_STYLE::BOTTOM )
559 else if( ret == TEXT_SPIN_STYLE::LEFT )
561 else if( ret == TEXT_SPIN_STYLE::RIGHT )
563
564 if( symbol->GetOrientation() & SYM_MIRROR_X )
565 {
566 if( ret == TEXT_SPIN_STYLE::UP )
568 else if( ret == TEXT_SPIN_STYLE::BOTTOM )
570 }
571
572 if( symbol->GetOrientation() & SYM_MIRROR_Y )
573 {
574 if( ret == TEXT_SPIN_STYLE::LEFT )
576 else if( ret == TEXT_SPIN_STYLE::RIGHT )
578 }
579 break;
581 case SYM_ORIENT_270:
582 if( ret == TEXT_SPIN_STYLE::UP )
584 else if( ret == TEXT_SPIN_STYLE::BOTTOM )
586 else if( ret == TEXT_SPIN_STYLE::LEFT )
588 else if( ret == TEXT_SPIN_STYLE::RIGHT )
590
591 if( symbol->GetOrientation() & SYM_MIRROR_X )
592 {
593 if( ret == TEXT_SPIN_STYLE::UP )
595 else if( ret == TEXT_SPIN_STYLE::BOTTOM )
597 }
598
599 if( symbol->GetOrientation() & SYM_MIRROR_Y )
600 {
601 if( ret == TEXT_SPIN_STYLE::LEFT )
603 else if( ret == TEXT_SPIN_STYLE::RIGHT )
605 }
606 break;
607 case SYM_ORIENT_180:
608 if( ret == TEXT_SPIN_STYLE::UP )
610 else if( ret == TEXT_SPIN_STYLE::BOTTOM )
612 else if( ret == TEXT_SPIN_STYLE::LEFT )
614 else if( ret == TEXT_SPIN_STYLE::RIGHT )
616
617 if( symbol->GetOrientation() & SYM_MIRROR_X )
618 {
619 if( ret == TEXT_SPIN_STYLE::UP )
621 else if( ret == TEXT_SPIN_STYLE::BOTTOM )
623 }
624
625 if( symbol->GetOrientation() & SYM_MIRROR_Y )
626 {
627 if( ret == TEXT_SPIN_STYLE::LEFT )
629 else if( ret == TEXT_SPIN_STYLE::RIGHT )
631 }
632 break;
633 case SYM_ORIENT_0:
634 case SYM_NORMAL:
635 default:
636 if( symbol->GetOrientation() & SYM_MIRROR_X )
637 {
638 if( ret == TEXT_SPIN_STYLE::UP )
640 else if( ret == TEXT_SPIN_STYLE::BOTTOM )
642 }
643
644 if( symbol->GetOrientation() & SYM_MIRROR_Y )
645 {
646 if( ret == TEXT_SPIN_STYLE::LEFT )
648 else if( ret == TEXT_SPIN_STYLE::RIGHT )
650 }
651 break;
652 }
653
654 break;
655 }
656 }
657 }
658 break;
659 default: break;
660 }
661 }
662 return ret;
663}
664
665
667{
668 bool hasExplicitJunction;
669 bool hasBusEntry;
670 bool isJunction = doIsJunction( aPosition, true, &hasExplicitJunction, &hasBusEntry );
671
672 return isJunction && !hasBusEntry;
673}
674
675
676
677bool SCH_SCREEN::doIsJunction( const VECTOR2I& aPosition, bool aBreakCrossings,
678 bool* aHasExplicitJunctionDot, bool* aHasBusEntry ) const
679{
680 enum layers { WIRES = 0, BUSES };
681
682 *aHasExplicitJunctionDot = false;
683 *aHasBusEntry = false;
684
685 bool breakLines[ 2 ] = { false };
686 std::unordered_set<int> exitAngles[ 2 ];
687 std::vector<const SCH_LINE*> midPointLines[ 2 ];
688
689 // A pin at 90° still shouldn't match a line at 90° so just give pins unique numbers
690 int uniqueAngle = 10000;
691
692 for( const SCH_ITEM* item : Items().Overlapping( aPosition ) )
693 {
694 if( item->GetEditFlags() & STRUCT_DELETED )
695 continue;
696
697 switch( item->Type() )
698 {
699 case SCH_JUNCTION_T:
700 if( item->HitTest( aPosition, -1 ) )
701 *aHasExplicitJunctionDot = true;
702
703 break;
704
705 case SCH_LINE_T:
706 {
707 const SCH_LINE* line = static_cast<const SCH_LINE*>( item );
708 int layer;
709
710 if( line->GetStartPoint() == line->GetEndPoint() )
711 break;
712 else if( line->GetLayer() == LAYER_WIRE )
713 layer = WIRES;
714 else if( line->GetLayer() == LAYER_BUS )
715 layer = BUSES;
716 else
717 break;
718
719 if( line->IsConnected( aPosition ) )
720 {
721 breakLines[ layer ] = true;
722 exitAngles[ layer ].insert( line->GetAngleFrom( aPosition ) );
723 }
724 else if( line->HitTest( aPosition, -1 ) )
725 {
726 if( aBreakCrossings )
727 breakLines[ layer ] = true;
728
729 // Defer any line midpoints until we know whether or not we're breaking them
730 midPointLines[ layer ].push_back( line );
731 }
732 }
733 break;
734
736 if( item->IsConnected( aPosition ) )
737 {
738 breakLines[ BUSES ] = true;
739 exitAngles[ BUSES ].insert( uniqueAngle++ );
740 breakLines[ WIRES ] = true;
741 exitAngles[ WIRES ].insert( uniqueAngle++ );
742 *aHasBusEntry = true;
743 }
744
745 break;
746
747 case SCH_SYMBOL_T:
748 case SCH_SHEET_T:
749 if( item->IsConnected( aPosition ) )
750 {
751 breakLines[ WIRES ] = true;
752 exitAngles[ WIRES ].insert( uniqueAngle++ );
753 }
754
755 break;
756
757 default:
758 break;
759 }
760 }
761
762 for( int layer : { WIRES, BUSES } )
763 {
764 if( breakLines[ layer ] )
765 {
766 for( const SCH_LINE* line : midPointLines[ layer ] )
767 {
768 exitAngles[ layer ].insert( line->GetAngleFrom( aPosition ) );
769 exitAngles[ layer ].insert( line->GetReverseAngleFrom( aPosition ) );
770 }
771 }
772 }
773
774 return exitAngles[ WIRES ].size() >= 3 || exitAngles[ BUSES ].size() >= 3;
775}
776
777
778bool SCH_SCREEN::IsTerminalPoint( const VECTOR2I& aPosition, int aLayer ) const
779{
780 wxCHECK_MSG( aLayer == LAYER_NOTES || aLayer == LAYER_BUS || aLayer == LAYER_WIRE, false,
781 wxT( "Invalid layer type passed to SCH_SCREEN::IsTerminalPoint()." ) );
782
783 SCH_SHEET_PIN* sheetPin;
784 SCH_LABEL_BASE* label;
785
786 switch( aLayer )
787 {
788 case LAYER_BUS:
789 if( GetBus( aPosition ) )
790 return true;
791
792 sheetPin = GetSheetPin( aPosition );
793
794 if( sheetPin && sheetPin->IsConnected( aPosition ) )
795 return true;
796
797 label = GetLabel( aPosition );
798
799 if( label && label->IsConnected( aPosition ) )
800 return true;
801
802 break;
803
804 case LAYER_NOTES:
805 if( GetLine( aPosition ) )
806 return true;
807
808 break;
809
810 case LAYER_WIRE:
811 if( GetItem( aPosition, 1, SCH_BUS_WIRE_ENTRY_T) )
812 return true;
813
814 if( GetItem( aPosition, 1, SCH_JUNCTION_T ) )
815 return true;
816
817 if( GetPin( aPosition, nullptr, true ) )
818 return true;
819
820 if( GetWire( aPosition ) )
821 return true;
822
823 label = GetLabel( aPosition, 1 );
824
825 if( label && label->IsConnected( aPosition ) )
826 return true;
827
828 sheetPin = GetSheetPin( aPosition );
829
830 if( sheetPin && sheetPin->IsConnected( aPosition ) )
831 return true;
832
833 break;
834
835 default:
836 break;
837 }
838
839 return false;
840}
841
842
844{
845 wxCHECK_RET( Schematic(), "Cannot call SCH_SCREEN::UpdateSymbolLinks with no SCHEMATIC" );
846
847 wxString msg;
848 std::unique_ptr< LIB_SYMBOL > libSymbol;
849 std::vector<SCH_SYMBOL*> symbols;
850 SYMBOL_LIB_TABLE* libs = Schematic()->Prj().SchSymbolLibTable();
851
852 // This will be a nullptr if an s-expression schematic is loaded.
853 SYMBOL_LIBS* legacyLibs = Schematic()->Prj().SchLibs();
854
855 for( SCH_ITEM* item : Items().OfType( SCH_SYMBOL_T ) )
856 symbols.push_back( static_cast<SCH_SYMBOL*>( item ) );
857
858 // Remove them from the R tree. There bounding box size may change.
859 for( SCH_SYMBOL* symbol : symbols )
860 Remove( symbol );
861
862 // Clear all existing symbol links.
864
865 for( SCH_SYMBOL* symbol : symbols )
866 {
867 LIB_SYMBOL* tmp = nullptr;
868 libSymbol.reset();
869
870 // If the symbol is already in the internal library, map the symbol to it.
871 auto it = m_libSymbols.find( symbol->GetSchSymbolLibraryName() );
872
873 if( ( it != m_libSymbols.end() ) )
874 {
875 if( aReporter )
876 {
877 msg.Printf( _( "Setting schematic symbol '%s %s' library identifier to '%s'." ),
878 symbol->GetField( REFERENCE_FIELD )->GetText(),
879 symbol->GetField( VALUE_FIELD )->GetText(),
880 UnescapeString( symbol->GetLibId().Format() ) );
881 aReporter->ReportTail( msg, RPT_SEVERITY_INFO );
882 }
883
884 // Internal library symbols are already flattened so just make a copy.
885 symbol->SetLibSymbol( new LIB_SYMBOL( *it->second ) );
886 continue;
887 }
888
889 if( !symbol->GetLibId().IsValid() )
890 {
891 if( aReporter )
892 {
893 msg.Printf( _( "Schematic symbol reference '%s' library identifier is not valid. "
894 "Unable to link library symbol." ),
895 UnescapeString( symbol->GetLibId().Format() ) );
896 aReporter->ReportTail( msg, RPT_SEVERITY_WARNING );
897 }
898
899 continue;
900 }
901
902 // LIB_TABLE_BASE::LoadSymbol() throws an IO_ERROR if the library nickname
903 // is not found in the table so check if the library still exists in the table
904 // before attempting to load the symbol.
905 if( !libs->HasLibrary( symbol->GetLibId().GetLibNickname() ) && !legacyLibs )
906 {
907 if( aReporter )
908 {
909 msg.Printf( _( "Symbol library '%s' not found and no fallback cache library "
910 "available. Unable to link library symbol." ),
911 symbol->GetLibId().GetLibNickname().wx_str() );
912 aReporter->ReportTail( msg, RPT_SEVERITY_WARNING );
913 }
914
915 continue;
916 }
917
918 if( libs->HasLibrary( symbol->GetLibId().GetLibNickname() ) )
919 {
920 try
921 {
922 tmp = libs->LoadSymbol( symbol->GetLibId() );
923 }
924 catch( const IO_ERROR& ioe )
925 {
926 if( aReporter )
927 {
928 msg.Printf( _( "I/O error %s resolving library symbol %s" ), ioe.What(),
929 UnescapeString( symbol->GetLibId().Format() ) );
930 aReporter->ReportTail( msg, RPT_SEVERITY_ERROR );
931 }
932 }
933 }
934
935 if( !tmp && legacyLibs && legacyLibs->GetLibraryCount() )
936 {
937 SYMBOL_LIB& legacyCacheLib = legacyLibs->at( 0 );
938
939 // It better be the cache library.
940 wxCHECK2( legacyCacheLib.IsCache(), continue );
941
942 wxString id = symbol->GetLibId().Format();
943
944 id.Replace( ':', '_' );
945
946 if( aReporter )
947 {
948 msg.Printf( _( "Falling back to cache to set symbol '%s:%s' link '%s'." ),
949 symbol->GetField( REFERENCE_FIELD )->GetText(),
950 symbol->GetField( VALUE_FIELD )->GetText(),
951 UnescapeString( id ) );
952 aReporter->ReportTail( msg, RPT_SEVERITY_WARNING );
953 }
954
955 tmp = legacyCacheLib.FindSymbol( id );
956 }
957
958 if( tmp )
959 {
960 // We want a full symbol not just the top level child symbol.
961 libSymbol = tmp->Flatten();
962 libSymbol->SetParent();
963
964 m_libSymbols.insert( { symbol->GetSchSymbolLibraryName(),
965 new LIB_SYMBOL( *libSymbol.get() ) } );
966
967 if( aReporter )
968 {
969 msg.Printf( _( "Setting schematic symbol '%s %s' library identifier to '%s'." ),
970 symbol->GetField( REFERENCE_FIELD )->GetText(),
971 symbol->GetField( VALUE_FIELD )->GetText(),
972 UnescapeString( symbol->GetLibId().Format() ) );
973 aReporter->ReportTail( msg, RPT_SEVERITY_INFO );
974 }
975 }
976 else
977 {
978 if( aReporter )
979 {
980 msg.Printf( _( "No library symbol found for schematic symbol '%s %s'." ),
981 symbol->GetField( REFERENCE_FIELD )->GetText(),
982 symbol->GetField( VALUE_FIELD )->GetText() );
983 aReporter->ReportTail( msg, RPT_SEVERITY_ERROR );
984 }
985 }
986
987 symbol->SetLibSymbol( libSymbol.release() );
988 }
989
990 // Changing the symbol may adjust the bbox of the symbol. This re-inserts the
991 // item with the new bbox
992 for( SCH_SYMBOL* symbol : symbols )
993 Append( symbol );
994}
995
996
998{
999 std::vector<SCH_SYMBOL*> symbols;
1000
1001 for( SCH_ITEM* item : Items().OfType( SCH_SYMBOL_T ) )
1002 symbols.push_back( static_cast<SCH_SYMBOL*>( item ) );
1003
1004 for( SCH_SYMBOL* symbol : symbols )
1005 {
1006 // Changing the symbol may adjust the bbox of the symbol; remove and reinsert it afterwards.
1007 m_rtree.remove( symbol );
1008
1009 auto it = m_libSymbols.find( symbol->GetSchSymbolLibraryName() );
1010
1011 LIB_SYMBOL* libSymbol = nullptr;
1012
1013 if( it != m_libSymbols.end() )
1014 libSymbol = new LIB_SYMBOL( *it->second );
1015
1016 symbol->SetLibSymbol( libSymbol );
1017
1018 m_rtree.insert( symbol );
1019 }
1020}
1021
1022
1024{
1025 for( SCH_ITEM* item : Items() )
1026 item->SetConnectivityDirty( true );
1027}
1028
1029
1030void SCH_SCREEN::Print( const RENDER_SETTINGS* aSettings )
1031{
1032 // Ensure links are up to date, even if a library was reloaded for some reason:
1033 std::vector<SCH_ITEM*> junctions;
1034 std::vector<SCH_ITEM*> bitmaps;
1035 std::vector<SCH_ITEM*> other;
1036
1037 for( SCH_ITEM* item : Items() )
1038 {
1039 if( item->IsMoving() || item->IsResized() )
1040 continue;
1041
1042 if( item->Type() == SCH_JUNCTION_T )
1043 junctions.push_back( item );
1044 else if( item->Type() == SCH_BITMAP_T )
1045 bitmaps.push_back( item );
1046 else
1047 other.push_back( item );
1048 }
1049
1051 std::stable_sort( other.begin(), other.end(),
1052 []( const SCH_ITEM* a, const SCH_ITEM* b )
1053 {
1054 if( a->Type() == b->Type() )
1055 return a->GetLayer() > b->GetLayer();
1056
1057 return a->Type() < b->Type();
1058 } );
1059
1060 for( SCH_ITEM* item : bitmaps )
1061 item->Print( aSettings, VECTOR2I( 0, 0 ) );
1062
1063 for( SCH_ITEM* item : other )
1064 item->PrintBackground( aSettings, VECTOR2I( 0, 0 ) );
1065
1066 for( SCH_ITEM* item : other )
1067 item->Print( aSettings, VECTOR2I( 0, 0 ) );
1068
1069 for( SCH_ITEM* item : junctions )
1070 item->Print( aSettings, VECTOR2I( 0, 0 ) );
1071}
1072
1073
1074void SCH_SCREEN::Plot( PLOTTER* aPlotter ) const
1075{
1076 // Ensure links are up to date, even if a library was reloaded for some reason:
1077 std::vector<SCH_ITEM*> junctions;
1078 std::vector<SCH_ITEM*> bitmaps;
1079 std::vector<SCH_SYMBOL*> symbols;
1080 std::vector<SCH_ITEM*> other;
1081
1082 for( SCH_ITEM* item : Items() )
1083 {
1084 if( item->IsMoving() || item->IsResized() )
1085 continue;
1086
1087 if( item->Type() == SCH_JUNCTION_T )
1088 junctions.push_back( item );
1089 else if( item->Type() == SCH_BITMAP_T )
1090 bitmaps.push_back( item );
1091 else
1092 other.push_back( item );
1093
1094 // Where the symbols overlap each other, we need to plot the text items a second
1095 // time to get them on top of the overlapping element. This collection is in addition
1096 // to the symbols already collected in `other`
1097 if( item->Type() == SCH_SYMBOL_T )
1098 {
1099 for( SCH_ITEM* sym : m_rtree.Overlapping( SCH_SYMBOL_T, item->GetBoundingBox() ) )
1100 {
1101 if( sym != item )
1102 {
1103 symbols.push_back( static_cast<SCH_SYMBOL*>( item ) );
1104 break;
1105 }
1106 }
1107 }
1108 }
1109
1111 std::sort( other.begin(), other.end(),
1112 []( const SCH_ITEM* a, const SCH_ITEM* b )
1113 {
1114 if( a->Type() == b->Type() )
1115 return a->GetLayer() > b->GetLayer();
1116
1117 return a->Type() > b->Type();
1118 } );
1119
1120 int defaultPenWidth = aPlotter->RenderSettings()->GetDefaultPenWidth();
1121 constexpr bool background = true;
1122
1123 // Bitmaps are drawn first to ensure they are in the background
1124 // This is particularly important for the wxPostscriptDC (used in *nix printers) as
1125 // the bitmap PS command clears the screen
1126 for( const SCH_ITEM* item : bitmaps )
1127 {
1128 aPlotter->SetCurrentLineWidth( std::max( item->GetPenWidth(), defaultPenWidth ) );
1129 item->Plot( aPlotter, background );
1130 }
1131
1132 for( const SCH_ITEM* item : other )
1133 {
1134 aPlotter->SetCurrentLineWidth( std::max( item->GetPenWidth(), defaultPenWidth ) );
1135 item->Plot( aPlotter, background );
1136 }
1137
1138 for( const SCH_ITEM* item : other )
1139 {
1140 aPlotter->SetCurrentLineWidth( std::max( item->GetPenWidth(), defaultPenWidth ) );
1141 item->Plot( aPlotter, !background );
1142 }
1143
1144 // After plotting the symbols as a group above (in `other`), we need to overplot the pins
1145 // and symbols to ensure that they are always visible
1146 for( const SCH_SYMBOL* sym :symbols )
1147 {
1148 aPlotter->SetCurrentLineWidth( std::max( sym->GetPenWidth(), defaultPenWidth ) );
1149
1150 for( SCH_FIELD field : sym->GetFields() )
1151 field.Plot( aPlotter, false );
1152
1153 sym->PlotPins( aPlotter );
1154 }
1155
1156 for( const SCH_ITEM* item : junctions )
1157 {
1158 aPlotter->SetCurrentLineWidth( std::max( item->GetPenWidth(), defaultPenWidth ) );
1159 item->Plot( aPlotter, !background );
1160 }
1161}
1162
1163
1165{
1166 for( SCH_ITEM* item : Items() )
1167 item->ClearTempFlags();
1168}
1169
1170
1171LIB_PIN* SCH_SCREEN::GetPin( const VECTOR2I& aPosition, SCH_SYMBOL** aSymbol,
1172 bool aEndPointOnly ) const
1173{
1174 SCH_SYMBOL* candidate = nullptr;
1175 LIB_PIN* pin = nullptr;
1176
1177 for( SCH_ITEM* item : Items().Overlapping( SCH_SYMBOL_T, aPosition ) )
1178 {
1179 candidate = static_cast<SCH_SYMBOL*>( item );
1180
1181 if( aEndPointOnly )
1182 {
1183 pin = nullptr;
1184
1185 if( !candidate->GetLibSymbolRef() )
1186 continue;
1187
1188 for( pin = candidate->GetLibSymbolRef()->GetNextPin(); pin;
1189 pin = candidate->GetLibSymbolRef()->GetNextPin( pin ) )
1190 {
1191 // Skip items not used for this part.
1192 if( candidate->GetUnit() && pin->GetUnit() &&
1193 ( pin->GetUnit() != candidate->GetUnit() ) )
1194 continue;
1195
1196 if( candidate->GetConvert() && pin->GetConvert() &&
1197 ( pin->GetConvert() != candidate->GetConvert() ) )
1198 continue;
1199
1200 if( candidate->GetPinPhysicalPosition( pin ) == aPosition )
1201 break;
1202 }
1203
1204 if( pin )
1205 break;
1206 }
1207 else
1208 {
1209 pin = (LIB_PIN*) candidate->GetDrawItem( aPosition, LIB_PIN_T );
1210
1211 if( pin )
1212 break;
1213 }
1214 }
1215
1216 if( pin && aSymbol )
1217 *aSymbol = candidate;
1218
1219 return pin;
1220}
1221
1222
1224{
1225 SCH_SHEET_PIN* sheetPin = nullptr;
1226
1227 for( SCH_ITEM* item : Items().Overlapping( SCH_SHEET_T, aPosition ) )
1228 {
1229 SCH_SHEET* sheet = static_cast<SCH_SHEET*>( item );
1230
1231 sheetPin = sheet->GetPin( aPosition );
1232
1233 if( sheetPin )
1234 break;
1235 }
1236
1237 return sheetPin;
1238}
1239
1240
1241size_t SCH_SCREEN::CountConnectedItems( const VECTOR2I& aPos, bool aTestJunctions ) const
1242{
1243 size_t count = 0;
1244
1245 for( const SCH_ITEM* item : Items().Overlapping( aPos ) )
1246 {
1247 if( ( item->Type() != SCH_JUNCTION_T || aTestJunctions ) && item->IsConnected( aPos ) )
1248 count++;
1249 }
1250
1251 return count;
1252}
1253
1254
1255void SCH_SCREEN::ClearAnnotation( SCH_SHEET_PATH* aSheetPath, bool aResetPrefix )
1256{
1257
1258 for( SCH_ITEM* item : Items().OfType( SCH_SYMBOL_T ) )
1259 {
1260 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
1261
1262 symbol->ClearAnnotation( aSheetPath, aResetPrefix );
1263 }
1264}
1265
1266
1268{
1269 if( GetClientSheetPaths().size() <= 1 ) // No need for alternate reference
1270 return;
1271
1272 for( SCH_ITEM* item : Items().OfType( SCH_SYMBOL_T ) )
1273 {
1274 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
1275
1276 // Add (when not existing) all sheet path entries
1277 for( const SCH_SHEET_PATH& sheet : GetClientSheetPaths() )
1278 symbol->AddSheetPathReferenceEntryIfMissing( sheet.Path() );
1279 }
1280}
1281
1282
1283void SCH_SCREEN::GetHierarchicalItems( std::vector<SCH_ITEM*>* aItems ) const
1284{
1285 for( SCH_ITEM* item : Items() )
1286 {
1287 if( item->IsType( { SCH_SYMBOL_T, SCH_SHEET_T, SCH_LABEL_LOCATE_ANY_T } ) )
1288 aItems->push_back( item );
1289 }
1290}
1291
1292
1293void SCH_SCREEN::GetSheets( std::vector<SCH_ITEM*>* aItems ) const
1294{
1295 for( SCH_ITEM* item : Items().OfType( SCH_SHEET_T ) )
1296 aItems->push_back( item );
1297
1298 std::sort( aItems->begin(), aItems->end(),
1299 []( EDA_ITEM* a, EDA_ITEM* b ) -> bool
1300 {
1301 if( a->GetPosition().x == b->GetPosition().x )
1302 {
1303 // Ensure deterministic sort
1304 if( a->GetPosition().y == b->GetPosition().y )
1305 return a->m_Uuid < b->m_Uuid;
1306
1307 return a->GetPosition().y < b->GetPosition().y;
1308 }
1309 else
1310 {
1311 return a->GetPosition().x < b->GetPosition().x;
1312 }
1313 } );
1314}
1315
1316
1318 std::function<void( SCH_ITEM* )>* aChangedHandler ) const
1319{
1320 std::vector<DANGLING_END_ITEM> endPoints;
1321
1322 for( SCH_ITEM* item : Items() )
1323 {
1324 if( item->IsConnectable() )
1325 {
1326 endPoints.clear();
1327
1328 for( SCH_ITEM* overlapping : Items().Overlapping( item->GetBoundingBox() ) )
1329 overlapping->GetEndPoints( endPoints );
1330
1331 if( item->UpdateDanglingState( endPoints, aPath ) )
1332 {
1333 if( aChangedHandler )
1334 (*aChangedHandler)( item );
1335 }
1336 }
1337 }
1338}
1339
1340
1341SCH_LINE* SCH_SCREEN::GetLine( const VECTOR2I& aPosition, int aAccuracy, int aLayer,
1342 SCH_LINE_TEST_T aSearchType ) const
1343{
1344 // an accuracy of 0 had problems with rounding errors; use at least 1
1345 aAccuracy = std::max( aAccuracy, 1 );
1346
1347 for( SCH_ITEM* item : Items().Overlapping( aPosition, aAccuracy ) )
1348 {
1349 if( item->Type() != SCH_LINE_T )
1350 continue;
1351
1352 if( item->GetLayer() != aLayer )
1353 continue;
1354
1355 if( !item->HitTest( aPosition, aAccuracy ) )
1356 continue;
1357
1358 switch( aSearchType )
1359 {
1360 case ENTIRE_LENGTH_T:
1361 return (SCH_LINE*) item;
1362
1364 if( !( (SCH_LINE*) item )->IsEndPoint( aPosition ) )
1365 return (SCH_LINE*) item;
1366 break;
1367
1368 case END_POINTS_ONLY_T:
1369 if( ( (SCH_LINE*) item )->IsEndPoint( aPosition ) )
1370 return (SCH_LINE*) item;
1371 }
1372 }
1373
1374 return nullptr;
1375}
1376
1377
1378SCH_LABEL_BASE* SCH_SCREEN::GetLabel( const VECTOR2I& aPosition, int aAccuracy ) const
1379{
1380 for( SCH_ITEM* item : Items().Overlapping( aPosition, aAccuracy ) )
1381 {
1382 switch( item->Type() )
1383 {
1384 case SCH_LABEL_T:
1385 case SCH_GLOBAL_LABEL_T:
1386 case SCH_HIER_LABEL_T:
1388 if( item->HitTest( aPosition, aAccuracy ) )
1389 return static_cast<SCH_LABEL_BASE*>( item );
1390
1391 break;
1392
1393 default:
1394 ;
1395 }
1396 }
1397
1398 return nullptr;
1399}
1400
1401
1403{
1404 wxCHECK( aLibSymbol, /* void */ );
1405
1406 wxString libSymbolName = aLibSymbol->GetLibId().Format().wx_str();
1407
1408 auto it = m_libSymbols.find( libSymbolName );
1409
1410 if( it != m_libSymbols.end() )
1411 {
1412 delete it->second;
1413 m_libSymbols.erase( it );
1414 }
1415
1416 m_libSymbols[libSymbolName] = aLibSymbol;
1417}
1418
1419
1420void SCH_SCREEN::AddBusAlias( std::shared_ptr<BUS_ALIAS> aAlias )
1421{
1422 m_aliases.insert( aAlias );
1423}
1424
1425
1427{
1428 for( SCH_ITEM* item : Items().OfType( SCH_SYMBOL_T ) )
1429 {
1430 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
1431
1432 // Add missing value and footprint instance data for legacy schematics.
1433 for( const SYMBOL_INSTANCE_REFERENCE& instance : symbol->GetInstanceReferences() )
1434 {
1435 symbol->AddHierarchicalReference( instance.m_Path, instance.m_Reference,
1436 instance.m_Unit,
1437 symbol->GetField( VALUE_FIELD )->GetText(),
1438 symbol->GetField( FOOTPRINT_FIELD )->GetText() );
1439 }
1440 }
1441}
1442
1443
1445{
1446 for( SCH_ITEM* item : Items().OfType( SCH_SYMBOL_T ) )
1447 {
1448 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
1449
1450 wxCHECK2( symbol, continue );
1451
1452 SYMBOL_INSTANCE_REFERENCE symbolDefaultReference = symbol->GetDefaultInstance();
1453
1454 const std::unique_ptr<LIB_SYMBOL>& libSymbol = symbol->GetLibSymbolRef();
1455
1456 if( !libSymbol )
1457 continue;
1458
1459 if( symbolDefaultReference.m_Unit != 1 ||
1460 symbolDefaultReference.m_Reference != symbol->GetPrefix() ||
1461 symbolDefaultReference.m_Value != libSymbol->GetValueField().GetText() ||
1462 symbolDefaultReference.m_Footprint != libSymbol->GetFootprintField().GetText() )
1463 return false;
1464 }
1465
1466 return true;
1467}
1468
1469
1471{
1472 for( SCH_ITEM* item : Items().OfType( SCH_SYMBOL_T ) )
1473 {
1474 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
1475
1476 wxCHECK2( symbol, continue );
1477
1478 if( !symbol->GetInstanceReferences().empty() )
1479 symbol->SetDefaultInstance( symbol->GetInstanceReferences()[0] );
1480 }
1481}
1482
1483
1484#if defined(DEBUG)
1485void SCH_SCREEN::Show( int nestLevel, std::ostream& os ) const
1486{
1487 // for now, make it look like XML, expand on this later.
1488 NestedSpace( nestLevel, os ) << '<' << GetClass().Lower().mb_str() << ">\n";
1489
1490 for( const SCH_ITEM* item : Items() )
1491 item->Show( nestLevel + 1, os );
1492
1493 NestedSpace( nestLevel, os ) << "</" << GetClass().Lower().mb_str() << ">\n";
1494}
1495#endif
1496
1497
1499{
1500 m_index = 0;
1501 buildScreenList( aSheet );
1502}
1503
1504
1506{
1507}
1508
1509
1511{
1512 m_index = 0;
1513
1514 if( m_screens.size() > 0 )
1515 return m_screens[0];
1516
1517 return nullptr;
1518}
1519
1520
1522{
1523 if( m_index < m_screens.size() )
1524 m_index++;
1525
1526 return GetScreen( m_index );
1527}
1528
1529
1530SCH_SCREEN* SCH_SCREENS::GetScreen( unsigned int aIndex ) const
1531{
1532 if( aIndex < m_screens.size() )
1533 return m_screens[ aIndex ];
1534
1535 return nullptr;
1536}
1537
1538
1539SCH_SHEET* SCH_SCREENS::GetSheet( unsigned int aIndex ) const
1540{
1541 if( aIndex < m_sheets.size() )
1542 return m_sheets[ aIndex ];
1543
1544 return nullptr;
1545}
1546
1547
1549{
1550 if( aScreen == nullptr )
1551 return;
1552
1553 for( const SCH_SCREEN* screen : m_screens )
1554 {
1555 if( screen == aScreen )
1556 return;
1557 }
1558
1559 m_screens.push_back( aScreen );
1560 m_sheets.push_back( aSheet );
1561}
1562
1563
1565{
1566 if( aSheet && aSheet->Type() == SCH_SHEET_T )
1567 {
1568 SCH_SCREEN* screen = aSheet->GetScreen();
1569
1570 wxCHECK_RET( screen, "No screen for aSheet" );
1571
1572 addScreenToList( screen, aSheet );
1573
1574 for( SCH_ITEM* item : screen->Items().OfType( SCH_SHEET_T ) )
1575 buildScreenList( static_cast<SCH_SHEET*>( item ) );
1576 }
1577}
1578
1579
1581{
1582 SCH_SCREEN* first = GetFirst();
1583
1584 if( !first )
1585 return;
1586
1587 SCHEMATIC* sch = first->Schematic();
1588
1589 wxCHECK_RET( sch, "Null schematic in SCH_SCREENS::ClearAnnotationOfNewSheetPaths" );
1590
1591 // Clear the annotation for symbols inside new sheetpaths not already in aInitialSheetList
1592 SCH_SCREENS screensList( sch->Root() ); // The list of screens, shared by sheet paths
1593 screensList.BuildClientSheetPathList(); // build the shared by sheet paths, by screen
1594
1595 // Search for new sheet paths, not existing in aInitialSheetPathList
1596 // and existing in sheetpathList
1597 for( SCH_SHEET_PATH& sheetpath : sch->GetSheets() )
1598 {
1599 bool path_exists = false;
1600
1601 for( const SCH_SHEET_PATH& existing_sheetpath: aInitialSheetPathList )
1602 {
1603 if( existing_sheetpath.Path() == sheetpath.Path() )
1604 {
1605 path_exists = true;
1606 break;
1607 }
1608 }
1609
1610 if( !path_exists )
1611 {
1612 // A new sheet path is found: clear the annotation corresponding to this new path:
1613 SCH_SCREEN* curr_screen = sheetpath.LastScreen();
1614
1615 // Clear annotation and create the AR for this path, if not exists,
1616 // when the screen is shared by sheet paths.
1617 // Otherwise ClearAnnotation do nothing, because the F1 field is used as
1618 // reference default value and takes the latest displayed value
1619 curr_screen->EnsureAlternateReferencesExist();
1620 curr_screen->ClearAnnotation( &sheetpath, false );
1621 }
1622 }
1623}
1624
1625
1627{
1628 std::vector<SCH_ITEM*> items;
1629 int count = 0;
1630
1631 auto timestamp_cmp = []( const EDA_ITEM* a, const EDA_ITEM* b ) -> bool
1632 {
1633 return a->m_Uuid < b->m_Uuid;
1634 };
1635
1636 std::set<EDA_ITEM*, decltype( timestamp_cmp )> unique_stamps( timestamp_cmp );
1637
1638 for( SCH_SCREEN* screen : m_screens )
1639 screen->GetHierarchicalItems( &items );
1640
1641 if( items.size() < 2 )
1642 return 0;
1643
1644 for( EDA_ITEM* item : items )
1645 {
1646 if( !unique_stamps.insert( item ).second )
1647 {
1648 // Reset to fully random UUID. This may lose reference, but better to be
1649 // deterministic about it rather than to have duplicate UUIDs with random
1650 // side-effects.
1651 const_cast<KIID&>( item->m_Uuid ) = KIID();
1652 count++;
1653
1654 // @todo If the item is a sheet, we need to decend the heirarchy from the sheet
1655 // and repace all instances of the changed UUID in sheet paths. Otherwise,
1656 // all instance paths with the sheet's UUID will get clobbered.
1657 }
1658 }
1659
1660 return count;
1661}
1662
1663
1665{
1666 for( SCH_SCREEN* screen = GetFirst(); screen; screen = GetNext() )
1667 {
1668 for( SCH_ITEM* item : screen->Items() )
1669 item->ClearEditFlags();
1670 }
1671}
1672
1673
1675{
1676 for( SCH_SCREEN* screen = GetFirst(); screen; screen = GetNext() )
1677 {
1678 for( SCH_ITEM* item : screen->Items().OfType( SCH_MARKER_T ) )
1679 {
1680 if( item == aMarker )
1681 {
1682 screen->DeleteItem( item );
1683 return;
1684 }
1685 }
1686 }
1687}
1688
1689
1690void SCH_SCREENS::DeleteMarkers( enum MARKER_BASE::TYPEMARKER aMarkerType, int aErrorCode,
1691 bool aIncludeExclusions )
1692{
1693 for( SCH_SCREEN* screen = GetFirst(); screen; screen = GetNext() )
1694 {
1695 std::vector<SCH_ITEM*> markers;
1696
1697 for( SCH_ITEM* item : screen->Items().OfType( SCH_MARKER_T ) )
1698 {
1699 SCH_MARKER* marker = static_cast<SCH_MARKER*>( item );
1700 std::shared_ptr<RC_ITEM>rcItem = marker->GetRCItem();
1701
1702 if( marker->GetMarkerType() == aMarkerType
1703 && ( aErrorCode == ERCE_UNSPECIFIED || rcItem->GetErrorCode() == aErrorCode )
1704 && ( !marker->IsExcluded() || aIncludeExclusions ) )
1705 {
1706 markers.push_back( item );
1707 }
1708 }
1709
1710 for( SCH_ITEM* marker : markers )
1711 screen->DeleteItem( marker );
1712 }
1713}
1714
1715
1717 bool aIncludeExclusions )
1718{
1719 DeleteMarkers( aMarkerType, ERCE_UNSPECIFIED, aIncludeExclusions );
1720}
1721
1722
1724{
1725 for( SCH_SCREEN* screen = GetFirst(); screen; screen = GetNext() )
1726 screen->UpdateSymbolLinks( aReporter );
1727
1728 SCH_SCREEN* first = GetFirst();
1729
1730 if( !first )
1731 return;
1732
1733 SCHEMATIC* sch = first->Schematic();
1734
1735 wxCHECK_RET( sch, "Null schematic in SCH_SCREENS::UpdateSymbolLinks" );
1736
1737 SCH_SHEET_LIST sheets = sch->GetSheets();
1738
1739 // All of the library symbols have been replaced with copies so the connection graph
1740 // pointers are stale.
1741 if( sch->ConnectionGraph() )
1742 sch->ConnectionGraph()->Recalculate( sheets, true );
1743}
1744
1745
1747{
1748 bool has_symbols = false;
1749
1750 for( SCH_SCREEN* screen = GetFirst(); screen; screen = GetNext() )
1751 {
1752 for( SCH_ITEM* item : screen->Items().OfType( SCH_SYMBOL_T ) )
1753 {
1754 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
1755 has_symbols = true;
1756
1757 if( !symbol->GetLibId().GetLibNickname().empty() )
1758 return false;
1759 }
1760 }
1761
1762 // return true (i.e. has no fully defined symbol) only if at least one symbol is found
1763 return has_symbols ? true : false;
1764}
1765
1766
1767size_t SCH_SCREENS::GetLibNicknames( wxArrayString& aLibNicknames )
1768{
1769 for( SCH_SCREEN* screen = GetFirst(); screen; screen = GetNext() )
1770 {
1771 for( SCH_ITEM* item : screen->Items().OfType( SCH_SYMBOL_T ) )
1772 {
1773 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
1774 const UTF8& nickname = symbol->GetLibId().GetLibNickname();
1775
1776 if( !nickname.empty() && ( aLibNicknames.Index( nickname ) == wxNOT_FOUND ) )
1777 aLibNicknames.Add( nickname );
1778 }
1779 }
1780
1781 return aLibNicknames.GetCount();
1782}
1783
1784
1785int SCH_SCREENS::ChangeSymbolLibNickname( const wxString& aFrom, const wxString& aTo )
1786{
1787 SCH_SCREEN* screen;
1788 int cnt = 0;
1789
1790 for( screen = GetFirst(); screen; screen = GetNext() )
1791 {
1792 for( SCH_ITEM* item : screen->Items().OfType( SCH_SYMBOL_T ) )
1793 {
1794 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
1795
1796 if( symbol->GetLibId().GetLibNickname() != aFrom )
1797 continue;
1798
1799 LIB_ID id = symbol->GetLibId();
1800 id.SetLibNickname( aTo );
1801 symbol->SetLibId( id );
1802 cnt++;
1803 }
1804 }
1805
1806 return cnt;
1807}
1808
1809
1810bool SCH_SCREENS::HasSchematic( const wxString& aSchematicFileName )
1811{
1812 for( const SCH_SCREEN* screen = GetFirst(); screen; screen = GetNext() )
1813 {
1814 if( screen->GetFileName() == aSchematicFileName )
1815 return true;
1816 }
1817
1818 return false;
1819}
1820
1821
1822bool SCH_SCREENS::CanCauseCaseSensitivityIssue( const wxString& aSchematicFileName ) const
1823{
1824 wxString lhsLower;
1825 wxString rhsLower;
1826 wxFileName lhs;
1827 wxFileName rhs = aSchematicFileName;
1828
1829 wxCHECK( rhs.IsAbsolute(), false );
1830
1831 for( const SCH_SCREEN* screen : m_screens )
1832 {
1833 lhs = screen->GetFileName();
1834
1835 if( lhs.GetPath() != rhs.GetPath() )
1836 continue;
1837
1838 lhsLower = lhs.GetFullName().Lower();
1839 rhsLower = rhs.GetFullName().Lower();
1840
1841 if( lhsLower == rhsLower && lhs.GetFullName() != rhs.GetFullName() )
1842 return true;
1843 }
1844
1845 return false;
1846}
1847
1848
1850{
1851 SCH_SCREEN* first = GetFirst();
1852
1853 if( !first )
1854 return;
1855
1856 SCHEMATIC* sch = first->Schematic();
1857
1858 wxCHECK_RET( sch, "Null schematic in SCH_SCREENS::BuildClientSheetPathList" );
1859
1860 for( SCH_SCREEN* curr_screen = GetFirst(); curr_screen; curr_screen = GetNext() )
1861 curr_screen->GetClientSheetPaths().clear();
1862
1863 for( SCH_SHEET_PATH& sheetpath : sch->GetSheets() )
1864 {
1865 SCH_SCREEN* used_screen = sheetpath.LastScreen();
1866
1867 // SEarch for the used_screen in list and add this unique sheet path:
1868 for( SCH_SCREEN* curr_screen = GetFirst(); curr_screen; curr_screen = GetNext() )
1869 {
1870 if( used_screen == curr_screen )
1871 {
1872 curr_screen->GetClientSheetPaths().push_back( sheetpath );
1873 break;
1874 }
1875 }
1876 }
1877}
1878
1879
1881{
1882
1883 for( SCH_SCREEN* screen = GetFirst(); screen; screen = GetNext() )
1884 screen->SetLegacySymbolInstanceData();
1885}
1886
1887
1889{
1890 for( SCH_SCREEN* screen = GetFirst(); screen; screen = GetNext() )
1891 {
1892 if( screen->GetFileFormatVersionAtLoad() <= 20220622 )
1893 {
1894 if( screen->AllSymbolDefaultInstancesNotSet() )
1895 screen->SetAllSymbolDefaultInstances();
1896 }
1897 }
1898}
constexpr EDA_IU_SCALE schIUScale
Definition: base_units.h:111
Handles how to draw a screen (a board, a schematic ...)
Definition: base_screen.h:41
int m_virtualPageNumber
An integer based page number used for printing a range of pages.
Definition: base_screen.h:119
bool m_Center
Center on screen.
Definition: base_screen.h:96
int m_pageCount
The number of BASE_SCREEN objects in this design.
Definition: base_screen.h:111
void InitDataPoints(const wxSize &aPageSizeInternalUnits)
Definition: base_screen.cpp:46
void SetContentModified(bool aModified=true)
Definition: base_screen.h:59
void SetOrigin(const Vec &pos)
Definition: box2.h:202
BOX2< Vec > & Inflate(coord_type dx, coord_type dy)
Inflates the rectangle horizontally by dx and vertically by dy.
Definition: box2.h:506
void Recalculate(const SCH_SHEET_LIST &aSheetList, bool aUnconditional=false, std::function< void(SCH_ITEM *)> *aChangedItemHandler=nullptr)
Updates the connection graph for the given list of sheets.
A base class for most all the KiCad significant classes used in schematics and boards.
Definition: eda_item.h:85
virtual const BOX2I GetBoundingBox() const
Return the orthogonal bounding box of this object for display purposes.
Definition: eda_item.cpp:74
void SetFlags(EDA_ITEM_FLAGS aMask)
Definition: eda_item.h:142
const KIID m_Uuid
Definition: eda_item.h:492
KICAD_T Type() const
Returns the type of object.
Definition: eda_item.h:97
bool IsSelected() const
Definition: eda_item.h:107
virtual void SetParent(EDA_ITEM *aParent)
Definition: eda_item.h:100
EDA_ITEM * GetParent() const
Definition: eda_item.h:99
bool HasFlag(EDA_ITEM_FLAGS aFlag) const
Definition: eda_item.h:145
virtual const wxString & GetText() const
Return the string associated with the text object.
Definition: eda_text.h:87
EE_TYPE Overlapping(const BOX2I &aRect) const
Definition: sch_rtree.h:243
bool remove(SCH_ITEM *aItem)
Remove an item from the tree.
Definition: sch_rtree.h:78
void insert(SCH_ITEM *aItem)
Insert an item into the tree.
Definition: sch_rtree.h:59
bool contains(const SCH_ITEM *aItem, bool aRobust=false) const
Determine if a given item exists in the tree.
Definition: sch_rtree.h:125
iterator end()
Returns a read/write iterator that points to one past the last element in the EE_RTREE.
Definition: sch_rtree.h:285
iterator begin()
Returns a read/write iterator that points to the first element in the EE_RTREE N.B.
Definition: sch_rtree.h:276
EE_TYPE OfType(KICAD_T aType) const
Definition: sch_rtree.h:238
void clear()
Remove all items from the RTree.
Definition: sch_rtree.h:111
Hold an error message and may be used when throwing exceptions containing meaningful error messages.
Definition: ki_exception.h:76
virtual const wxString What() const
A composite of Problem() and Where()
Definition: exceptions.cpp:30
Container for all the knowledge about how graphical objects are drawn on any output surface/device.
int GetDefaultPenWidth() const
Definition: kiid.h:47
A logical library item identifier and consists of various portions much like a URI.
Definition: lib_id.h:49
UTF8 Format() const
Definition: lib_id.cpp:117
const wxString GetUniStringLibItemName() const
Get strings for display messages in dialogs.
Definition: lib_id.h:111
int SetLibNickname(const UTF8 &aNickname)
Override the logical library name portion of the LIB_ID to aNickname.
Definition: lib_id.cpp:98
const UTF8 & GetLibNickname() const
Return the logical library name portion of a LIB_ID.
Definition: lib_id.h:87
Define a library symbol object.
Definition: lib_symbol.h:98
LIB_ITEMS_CONTAINER & GetDrawItems()
Return a reference to the draw item list.
Definition: lib_symbol.h:519
LIB_ID GetLibId() const override
Definition: lib_symbol.h:139
std::unique_ptr< LIB_SYMBOL > Flatten() const
Return a flattened symbol inheritance to the caller.
Definition: lib_symbol.cpp:460
void SetLibId(const LIB_ID &aLibId)
Definition: lib_symbol.h:140
virtual void SetName(const wxString &aName)
Definition: lib_symbol.cpp:441
bool HasLibrary(const wxString &aNickname, bool aCheckEnabled=false) const
Test for the existence of aNickname in the library table.
bool IsExcluded() const
Definition: marker_base.h:97
std::shared_ptr< RC_ITEM > GetRCItem() const
Definition: marker_base.h:105
enum TYPEMARKER GetMarkerType() const
Definition: marker_base.h:95
void sort()
Definition: multivector.h:247
const wxSize GetSizeIU(double aIUScale) const
Gets the page size in internal units.
Definition: page_info.h:162
Base plotter engine class.
Definition: plotter.h:110
RENDER_SETTINGS * RenderSettings()
Definition: plotter.h:141
virtual void SetCurrentLineWidth(int width, void *aData=nullptr)=0
Set the line width for the next drawing.
A pure virtual class used to derive REPORTER objects from.
Definition: reporter.h:71
virtual REPORTER & ReportTail(const wxString &aText, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED)
Places the report at the end of the list, for objects that support report ordering.
Definition: reporter.h:99
Holds all the data relating to one schematic.
Definition: schematic.h:60
CONNECTION_GRAPH * ConnectionGraph() const override
Definition: schematic.h:129
SCH_SHEET_LIST GetSheets() const override
Builds and returns an updated schematic hierarchy TODO: can this be cached?
Definition: schematic.h:85
SCH_SHEET & Root() const
Definition: schematic.h:90
PROJECT & Prj() const override
Return a reference to the project this schematic is part of.
Definition: schematic.h:75
Class for a wire to bus entry.
Instances are attached to a symbol or sheet and provide a place for the symbol's value,...
Definition: sch_field.h:50
Base class for any item which can be embedded within the SCHEMATIC container class,...
Definition: sch_item.h:147
SCH_LAYER_ID GetLayer() const
Return the layer this item is on.
Definition: sch_item.h:246
bool IsConnected(const VECTOR2I &aPoint) const
Test the item to see if it is connected to aPoint.
Definition: sch_item.cpp:137
Segment description base class to describe items which have 2 end points (track, wire,...
Definition: sch_line.h:40
bool HitTest(const VECTOR2I &aPosition, int aAccuracy=0) const override
Test if aPosition is inside or on the boundary of this item.
Definition: sch_line.cpp:765
int GetAngleFrom(const VECTOR2I &aPoint) const
Definition: sch_line.cpp:402
VECTOR2I GetEndPoint() const
Definition: sch_line.h:137
VECTOR2I GetStartPoint() const
Definition: sch_line.h:132
Container class that holds multiple SCH_SCREEN objects in a hierarchy.
Definition: sch_screen.h:613
SCH_SCREEN * GetNext()
unsigned int m_index
Definition: sch_screen.h:755
std::vector< SCH_SHEET * > m_sheets
Definition: sch_screen.h:754
SCH_SCREEN * GetScreen(unsigned int aIndex) const
void UpdateSymbolLinks(REPORTER *aReporter=nullptr)
Initialize the LIB_SYMBOL reference for each SCH_SYMBOL found in the full schematic.
void DeleteMarker(SCH_MARKER *aMarker)
Delete a specific marker.
void buildScreenList(SCH_SHEET *aSheet)
void DeleteMarkers(enum MARKER_BASE::TYPEMARKER aMarkerTyp, int aErrorCode, bool aIncludeExclusions=true)
Delete all markers of a particular type and error code.
SCH_SCREEN * GetFirst()
int ChangeSymbolLibNickname(const wxString &aFrom, const wxString &aTo)
Change all of the symbol library nicknames.
SCH_SCREENS(SCH_SHEET *aSheet)
void SetAllSymbolDefaultInstances()
Set symbol default instances to the first instance in the instance list.
void BuildClientSheetPathList()
built the list of sheet paths sharing a screen for each screen in use
void ClearAnnotationOfNewSheetPaths(SCH_SHEET_LIST &aInitialSheetPathList)
Clear the annotation for the symbols inside new sheetpaths when a complex hierarchy is modified and n...
bool CanCauseCaseSensitivityIssue(const wxString &aSchematicFileName) const
Check aSchematicFileName for a potential file name case sensitivity issue.
bool HasNoFullyDefinedLibIds()
Test all of the schematic symbols to see if all LIB_ID objects library nickname is not set.
void ClearEditFlags()
SCH_SHEET * GetSheet(unsigned int aIndex) const
int ReplaceDuplicateTimeStamps()
Test all sheet and symbol objects in the schematic for duplicate time stamps and replaces them as nec...
void DeleteAllMarkers(enum MARKER_BASE::TYPEMARKER aMarkerType, bool aIncludeExclusions)
Delete all electronic rules check markers of aMarkerType from all the screens in the list.
std::vector< SCH_SCREEN * > m_screens
Definition: sch_screen.h:753
bool HasSchematic(const wxString &aSchematicFileName)
Check if one of the schematics in the list of screens is aSchematicFileName.
size_t GetLibNicknames(wxArrayString &aLibNicknames)
Fetch all of the symbol library nicknames into aLibNicknames.
void SetLegacySymbolInstanceData()
Update the symbol value and footprint instance data for legacy designs.
void addScreenToList(SCH_SCREEN *aScreen, SCH_SHEET *aSheet)
std::map< wxString, LIB_SYMBOL * > m_libSymbols
Library symbols required for this schematic.
Definition: sch_screen.h:574
void ClearDrawingState()
Clear the state flags of all the items in the screen.
SCH_LINE * GetLine(const VECTOR2I &aPosition, int aAccuracy=0, int aLayer=LAYER_NOTES, SCH_LINE_TEST_T aSearchType=ENTIRE_LENGTH_T) const
Return a line item located at aPosition.
void SetAllSymbolDefaultInstances()
Set symbol default instances to the first instance in the instance list.
void Update(SCH_ITEM *aItem)
Update aItem's bounding box in the tree.
Definition: sch_screen.cpp:261
void AddLibSymbol(LIB_SYMBOL *aLibSymbol)
Add aLibSymbol to the library symbol map.
void AddBusAlias(std::shared_ptr< BUS_ALIAS > aAlias)
Add a bus alias definition (and transfers ownership of the pointer).
bool HasItems(KICAD_T aItemType) const
Definition: sch_screen.cpp:127
void Clear(bool aFree=true)
Delete all draw items and clears the project settings.
Definition: sch_screen.cpp:223
LIB_PIN * GetPin(const VECTOR2I &aPosition, SCH_SYMBOL **aSymbol=nullptr, bool aEndPointOnly=false) const
Test the screen for a symbol pin item at aPosition.
bool Remove(SCH_ITEM *aItem)
Remove aItem from the schematic associated with this screen.
Definition: sch_screen.cpp:268
std::vector< SCH_SHEET_PATH > & GetClientSheetPaths()
Return the number of times this screen is used.
Definition: sch_screen.h:177
void UpdateSymbolLinks(REPORTER *aReporter=nullptr)
Initialize the LIB_SYMBOL reference for each SCH_SYMBOL found in this schematic from the project SYMB...
Definition: sch_screen.cpp:843
SCH_LINE * GetWire(const VECTOR2I &aPosition, int aAccuracy=0, SCH_LINE_TEST_T aSearchType=ENTIRE_LENGTH_T) const
Definition: sch_screen.h:426
int m_refCount
Definition: sch_screen.h:542
TITLE_BLOCK m_titles
Definition: sch_screen.h:555
void TestDanglingEnds(const SCH_SHEET_PATH *aPath=nullptr, std::function< void(SCH_ITEM *)> *aChangedHandler=nullptr) const
Test all of the connectable objects in the schematic for unused connection points.
void EnsureAlternateReferencesExist()
For screens shared by many sheetpaths (complex hierarchies): to be able to clear or modify any refere...
bool AllSymbolDefaultInstancesNotSet()
Check all symbol default instance to see if they are not set yet.
int m_modification_sync
Definition: sch_screen.h:559
double m_LastZoomLevel
last value for the zoom level, useful in Eeschema when changing the current displayed sheet to reuse ...
Definition: sch_screen.h:527
bool IsExplicitJunction(const VECTOR2I &aPosition) const
Indicates that a junction dot is necessary at the given location.
Definition: sch_screen.cpp:429
EE_RTREE & Items()
Gets the full RTree, usually for iterating.
Definition: sch_screen.h:108
void Print(const RENDER_SETTINGS *aSettings)
Print all the items in the screen to aDC.
void DecRefCount()
Definition: sch_screen.cpp:120
std::set< SCH_ITEM * > MarkConnections(SCH_LINE *aSegment, bool aSecondPass)
Return all wires and junctions connected to aSegment which are not connected any symbol pin.
Definition: sch_screen.cpp:353
SCH_ITEM * GetItem(const VECTOR2I &aPosition, int aAccuracy=0, KICAD_T aType=SCH_LOCATE_ANY_T) const
Check aPosition within a distance of aAccuracy for items of type aFilter.
Definition: sch_screen.cpp:337
bool IsExplicitJunctionAllowed(const VECTOR2I &aPosition) const
Indicates that a juction dot may be placed at the given location.
Definition: sch_screen.cpp:666
void clearLibSymbols()
Definition: sch_screen.cpp:97
wxString m_fileName
Definition: sch_screen.h:540
bool IsTerminalPoint(const VECTOR2I &aPosition, int aLayer) const
Test if aPosition is a connection point on aLayer.
Definition: sch_screen.cpp:778
void UpdateLocalLibSymbolLinks()
Initialize the LIB_SYMBOL reference for each SCH_SYMBOL found in this schematic with the local projec...
Definition: sch_screen.cpp:997
void IncRefCount()
Definition: sch_screen.cpp:114
std::set< std::shared_ptr< BUS_ALIAS > > m_aliases
List of bus aliases stored in this screen.
Definition: sch_screen.h:571
void SetFileName(const wxString &aFileName)
Set the file name for this screen to aFileName.
Definition: sch_screen.cpp:106
static bool ClassOf(const EDA_ITEM *aItem)
Definition: sch_screen.cpp:135
void SetLegacySymbolInstanceData()
Update the symbol value and footprint instance data for legacy designs.
SCH_LINE * GetBus(const VECTOR2I &aPosition, int aAccuracy=0, SCH_LINE_TEST_T aSearchType=ENTIRE_LENGTH_T) const
Definition: sch_screen.h:432
SCH_SCREEN(EDA_ITEM *aParent=nullptr)
Definition: sch_screen.cpp:62
SCHEMATIC * Schematic() const
Definition: sch_screen.cpp:88
EE_RTREE m_rtree
Definition: sch_screen.h:557
void GetHierarchicalItems(std::vector< SCH_ITEM * > *aItems) const
Add all schematic sheet and symbol objects in the screen to aItems.
bool IsExplicitJunctionNeeded(const VECTOR2I &aPosition) const
Indicates that a junction dot is necessary at the given location, and does not yet exist.
Definition: sch_screen.cpp:439
SCH_SHEET_PIN * GetSheetPin(const VECTOR2I &aPosition) const
Test the screen if aPosition is a sheet label object.
void Plot(PLOTTER *aPlotter) const
Plot all the schematic objects to aPlotter.
void FreeDrawList()
Free all the items from the schematic associated with the screen.
Definition: sch_screen.cpp:242
virtual wxString GetClass() const override
Return the class name.
Definition: sch_screen.h:122
void SetConnectivityDirty()
bool m_zoomInitialized
Definition: sch_screen.h:562
PAGE_INFO m_paper
Definition: sch_screen.h:554
bool IsJunction(const VECTOR2I &aPosition) const
Test if a junction is required for the items at aPosition on the screen.
Definition: sch_screen.cpp:419
TEXT_SPIN_STYLE GetLabelOrientationForPoint(const VECTOR2I &aPosition, TEXT_SPIN_STYLE aDefaultOrientation, const SCH_SHEET_PATH *aSheet) const
Definition: sch_screen.cpp:448
void GetSheets(std::vector< SCH_ITEM * > *aItems) const
Similar to Items().OfType( SCH_SHEET_T ), but return the sheets in a deterministic order (L-R,...
bool CheckIfOnDrawList(const SCH_ITEM *aItem) const
Definition: sch_screen.cpp:331
void ClearAnnotation(SCH_SHEET_PATH *aSheetPath, bool aResetPrefix)
Clear the annotation for the symbols in aSheetPath on the screen.
bool doIsJunction(const VECTOR2I &aPosition, bool aBreakCrossings, bool *aHasExplicitJunctionDot, bool *aHasBusEntry) const
Definition: sch_screen.cpp:677
size_t CountConnectedItems(const VECTOR2I &aPos, bool aTestJunctions) const
void Append(SCH_ITEM *aItem)
Definition: sch_screen.cpp:141
void DeleteItem(SCH_ITEM *aItem)
Removes aItem from the linked list and deletes the object.
Definition: sch_screen.cpp:306
SCH_LABEL_BASE * GetLabel(const VECTOR2I &aPosition, int aAccuracy=0) const
Return a label item located at aPosition.
A container for handling SCH_SHEET_PATH objects in a flattened hierarchy.
Handle access to a stack of flattened SCH_SHEET objects by way of a path for creating a flattened sch...
Define a sheet pin (label) used in sheets to create hierarchical schematics.
Definition: sch_sheet_pin.h:66
SCH_SHEET * GetParent() const
Get the parent sheet object of this sheet pin.
Sheet symbol placed in a schematic, and is the entry point for a sub schematic.
Definition: sch_sheet.h:55
SCH_SHEET_PIN * GetPin(const VECTOR2I &aPosition)
Return the sheet pin item found at aPosition in the sheet.
Definition: sch_sheet.cpp:566
void RemovePin(const SCH_SHEET_PIN *aSheetPin)
Remove aSheetPin from the sheet.
Definition: sch_sheet.cpp:364
SCH_SCREEN * GetScreen() const
Definition: sch_sheet.h:103
Schematic symbol object.
Definition: sch_symbol.h:80
const std::vector< SYMBOL_INSTANCE_REFERENCE > & GetInstanceReferences()
Definition: sch_symbol.h:139
void SetLibId(const LIB_ID &aName)
Definition: sch_symbol.cpp:286
void AddHierarchicalReference(const KIID_PATH &aPath, const wxString &aRef, int aUnit, const wxString &aValue=wxEmptyString, const wxString &aFootprint=wxEmptyString)
Add a full hierarchical reference to this symbol.
Definition: sch_symbol.cpp:525
LIB_ITEM * GetDrawItem(const VECTOR2I &aPosition, KICAD_T aType=TYPE_NOT_INIT)
Return the symbol library item at aPosition that is part of this symbol.
int GetUnit() const
Definition: sch_symbol.h:231
wxString GetSchSymbolLibraryName() const
Definition: sch_symbol.cpp:296
const SYMBOL_INSTANCE_REFERENCE & GetDefaultInstance() const
Definition: sch_symbol.h:154
bool AddSheetPathReferenceEntryIfMissing(const KIID_PATH &aSheetPath)
Add an instance to the alternate references list (m_instanceReferences), if this entry does not alrea...
SCH_FIELD * GetField(MANDATORY_FIELD_T aFieldType)
Return a mandatory field in this symbol.
Definition: sch_symbol.cpp:892
VECTOR2I GetPinPhysicalPosition(const LIB_PIN *Pin) const
int GetConvert() const
Definition: sch_symbol.h:273
void SetDefaultInstance(const SYMBOL_INSTANCE_REFERENCE &aInstance)
Definition: sch_symbol.h:147
void ClearAnnotation(const SCH_SHEET_PATH *aSheetPath, bool aResetPrefix)
Clear exiting symbol annotation.
std::vector< SCH_PIN * > GetPins(const SCH_SHEET_PATH *aSheet=nullptr) const
Retrieve a list of the SCH_PINs for the given sheet path.
void SetSchSymbolLibraryName(const wxString &aName)
The name of the symbol in the schematic library symbol list.
Definition: sch_symbol.h:191
int GetOrientation() const
Get the display symbol orientation.
const LIB_ID & GetLibId() const
Definition: sch_symbol.h:178
std::unique_ptr< LIB_SYMBOL > & GetLibSymbolRef()
Definition: sch_symbol.h:195
void SetLibSymbol(LIB_SYMBOL *aLibSymbol)
Set this schematic symbol library symbol reference to aLibSymbol.
Definition: sch_symbol.cpp:305
wxString GetPrefix() const
Definition: sch_symbol.h:277
A collection of SYMBOL_LIB objects.
int GetLibraryCount()
LIB_SYMBOL * LoadSymbol(const wxString &aNickname, const wxString &aName)
Load a LIB_SYMBOL having aName from the library given by aNickname.
Object used to load, save, search, and otherwise manipulate symbol library files.
bool IsCache() const
LIB_SYMBOL * FindSymbol(const wxString &aName) const
Find LIB_SYMBOL by aName.
void Clear()
Definition: title_block.h:113
An 8 bit string that is assuredly encoded in UTF8, and supplies special conversion support to and fro...
Definition: utf8.h:71
bool empty() const
Definition: utf8.h:103
wxString wx_str() const
Definition: utf8.cpp:46
#define _(s)
#define STRUCT_DELETED
flag indication structures to be erased
@ ERCE_UNSPECIFIED
Definition: erc_settings.h:38
@ LAYER_WIRE
Definition: layer_ids.h:344
@ LAYER_NOTES
Definition: layer_ids.h:358
@ LAYER_BUS
Definition: layer_ids.h:345
@ PIN_LEFT
Definition: lib_pin.h:46
@ PIN_RIGHT
Definition: lib_pin.h:45
@ PIN_UP
Definition: lib_pin.h:47
@ PIN_DOWN
Definition: lib_pin.h:48
boost::ptr_vector< WIRE > WIRES
Definition: specctra.h:2983
static DIRECTION_45::AngleType angle(const VECTOR2I &a, const VECTOR2I &b)
Plot settings, and plotting engines (PostScript, Gerber, HPGL and DXF)
@ RPT_SEVERITY_WARNING
@ RPT_SEVERITY_ERROR
@ RPT_SEVERITY_INFO
SYMBOL_ORIENTATION_T
enum used in RotationMiroir()
@ SYM_ORIENT_270
@ SYM_ROTATE_CLOCKWISE
@ SYM_ROTATE_COUNTERCLOCKWISE
@ SYM_MIRROR_Y
@ SYM_ORIENT_180
@ SYM_MIRROR_X
@ SYM_NORMAL
@ SYM_ORIENT_90
@ SYM_ORIENT_0
#define PROCESSED
SCH_LINE_TEST_T
Definition: sch_screen.h:70
@ ENTIRE_LENGTH_T
Definition: sch_screen.h:71
@ EXCLUDE_END_POINTS_T
Definition: sch_screen.h:73
@ END_POINTS_ONLY_T
Definition: sch_screen.h:72
wxString UnescapeString(const wxString &aSource)
const double IU_PER_MILS
Definition: base_units.h:78
The EE_TYPE struct provides a type-specific auto-range iterator to the RTree.
Definition: sch_rtree.h:192
iterator begin()
Definition: sch_rtree.h:222
iterator end()
Definition: sch_rtree.h:227
A simple container for schematic symbol instance information.
Definition for symbol library class.
@ FOOTPRINT_FIELD
Field Name Module PCB, i.e. "16DIP300".
@ VALUE_FIELD
Field Value of part, i.e. "3.3K".
@ REFERENCE_FIELD
Field Reference of part, i.e. "IC21".
KICAD_T
The set of class identification values stored in EDA_ITEM::m_structType.
Definition: typeinfo.h:78
@ SCH_LINE_T
Definition: typeinfo.h:145
@ SCH_SYMBOL_T
Definition: typeinfo.h:155
@ SCH_FIELD_T
Definition: typeinfo.h:154
@ SCH_DIRECTIVE_LABEL_T
Definition: typeinfo.h:153
@ SCH_LABEL_T
Definition: typeinfo.h:150
@ SCH_SHEET_T
Definition: typeinfo.h:157
@ SCH_MARKER_T
Definition: typeinfo.h:140
@ SCH_HIER_LABEL_T
Definition: typeinfo.h:152
@ LIB_PIN_T
Definition: typeinfo.h:202
@ SCH_SCREEN_T
Definition: typeinfo.h:185
@ SCHEMATIC_T
Definition: typeinfo.h:187
@ SCH_SHEET_PIN_T
Definition: typeinfo.h:156
@ SCH_BUS_WIRE_ENTRY_T
Definition: typeinfo.h:143
@ SCH_BITMAP_T
Definition: typeinfo.h:147
@ SCH_GLOBAL_LABEL_T
Definition: typeinfo.h:151
@ SCH_JUNCTION_T
Definition: typeinfo.h:141
@ SCH_PIN_T
Definition: typeinfo.h:158
VECTOR2< int > VECTOR2I
Definition: vector2d.h:618