KiCad PCB EDA Suite
Loading...
Searching...
No Matches
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 The 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 <stack>
28#include <wx/filefn.h>
29#include <wx/log.h>
30
31#include <eda_item.h>
32#include <id.h>
33#include <string_utils.h>
34#include <kiway.h>
35#include <plotters/plotter.h>
36#include <sch_plotter.h>
37#include <project.h>
38#include <project_sch.h>
39#include <reporter.h>
40#include <trace_helpers.h>
41#include <sch_edit_frame.h>
42#include <sch_item.h>
43
44#include <symbol_library.h>
45#include <connection_graph.h>
46#include <junction_helpers.h>
47#include <sch_pin.h>
48#include <sch_symbol.h>
49#include <sch_group.h>
50#include <sch_junction.h>
51#include <sch_line.h>
52#include <sch_marker.h>
53#include <sch_sheet.h>
54#include <sch_sheet_pin.h>
55#include <sch_text.h>
56#include <schematic.h>
58#include <symbol_lib_table.h>
59#include <tool/common_tools.h>
60#include <sim/sim_model.h> // For V6 to V7 simulation model migration.
61#include <locale_io.h>
62
63#include <algorithm>
64#include <math/vector3.h>
65
66// TODO(JE) Debugging only
67#include <core/profile.h>
68#include "sch_bus_entry.h"
69#include "sch_shape.h"
70
76static const wxChar DanglingProfileMask[] = wxT( "DANGLING_PROFILE" );
77
78
80 BASE_SCREEN( aParent, SCH_SCREEN_T ),
81 m_fileFormatVersionAtLoad( 0 ),
82 m_paper( wxT( "A4" ) ),
83 m_isReadOnly( false ),
84 m_fileExists( false )
85{
87 m_refCount = 0;
88 m_zoomInitialized = false;
89 m_LastZoomLevel = 1.0;
90
91 // Suitable for schematic only. For symbol_editor and viewlib, must be set to true
92 m_Center = false;
93
95}
96
97
99{
101 FreeDrawList();
102}
103
104
106{
107 wxCHECK_MSG( GetParent() && GetParent()->Type() == SCHEMATIC_T, nullptr,
108 wxT( "SCH_SCREEN must have a SCHEMATIC parent!" ) );
109
110 return static_cast<SCHEMATIC*>( GetParent() );
111}
112
113
115{
116 for( const std::pair<const wxString, LIB_SYMBOL*>& libSymbol : m_libSymbols )
117 delete libSymbol.second;
118
119 m_libSymbols.clear();
120}
121
122
123void SCH_SCREEN::SetFileName( const wxString& aFileName )
124{
125 // Don't assert here. We still call this after failing to load a file in order to show the
126 // user what we *tried* to load.
127 // wxASSERT( aFileName.IsEmpty() || wxIsAbsolutePath( aFileName ) );
128
129 m_fileName = aFileName;
130}
131
132
134{
135 m_refCount++;
136}
137
138
140{
141 wxCHECK_RET( m_refCount != 0, wxT( "Screen reference count already zero. Bad programmer!" ) );
142 m_refCount--;
143}
144
145
146bool SCH_SCREEN::HasItems( KICAD_T aItemType ) const
147{
148 EE_RTREE::EE_TYPE sheets = m_rtree.OfType( aItemType );
149
150 return sheets.begin() != sheets.end();
151}
152
153
154bool SCH_SCREEN::ClassOf( const EDA_ITEM* aItem )
155{
156 return aItem && SCH_SCREEN_T == aItem->Type();
157}
158
159
160void SCH_SCREEN::Append( SCH_ITEM* aItem, bool aUpdateLibSymbol )
161{
162 if( aItem->Type() != SCH_SHEET_PIN_T && aItem->Type() != SCH_FIELD_T )
163 {
164 // Ensure the item can reach the SCHEMATIC through this screen
165 aItem->SetParent( this );
166
167 if( aItem->Type() == SCH_SYMBOL_T && aUpdateLibSymbol )
168 {
169 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( aItem );
170
171 if( symbol->GetLibSymbolRef() )
172 {
173 symbol->GetLibSymbolRef()->GetDrawItems().sort();
174
175 auto it = m_libSymbols.find( symbol->GetSchSymbolLibraryName() );
176
177 if( it == m_libSymbols.end() || !it->second )
178 {
180 new LIB_SYMBOL( *symbol->GetLibSymbolRef() );
181 }
182 else
183 {
184 // The original library symbol may have changed since the last time
185 // it was added to the schematic. If it has changed, then a new name
186 // must be created for the library symbol list to prevent all of the
187 // other schematic symbols referencing that library symbol from changing.
188 LIB_SYMBOL* foundSymbol = it->second;
189
190 foundSymbol->GetDrawItems().sort();
191
192 if( *foundSymbol != *symbol->GetLibSymbolRef() )
193 {
194 wxString newName;
195 std::vector<wxString> matches;
196
197 getLibSymbolNameMatches( *symbol, matches );
198 foundSymbol = nullptr;
199
200 for( const wxString& libSymbolName : matches )
201 {
202 it = m_libSymbols.find( libSymbolName );
203
204 if( it == m_libSymbols.end() )
205 continue;
206
207 foundSymbol = it->second;
208
209 wxCHECK2( foundSymbol, continue );
210
211 wxString tmp = symbol->GetLibSymbolRef()->GetName();
212
213 // Temporarily update the new symbol library symbol name so it
214 // doesn't fail on the name comparison below.
215 symbol->GetLibSymbolRef()->SetName( foundSymbol->GetName() );
216
217 if( *foundSymbol == *symbol->GetLibSymbolRef() )
218 {
219 newName = libSymbolName;
220 symbol->GetLibSymbolRef()->SetName( tmp );
221 break;
222 }
223
224 symbol->GetLibSymbolRef()->SetName( tmp );
225 foundSymbol = nullptr;
226 }
227
228 if( !foundSymbol )
229 {
230 int cnt = 1;
231
232 newName.Printf( wxT( "%s_%d" ),
234 cnt );
235
236 while( m_libSymbols.find( newName ) != m_libSymbols.end() )
237 {
238 cnt += 1;
239 newName.Printf( wxT( "%s_%d" ),
241 cnt );
242 }
243 }
244
245 // Update the schematic symbol library link as this symbol only exists
246 // in the schematic.
247 symbol->SetSchSymbolLibraryName( newName );
248
249 if( !foundSymbol )
250 {
251 // Update the schematic symbol library link as this symbol does not
252 // exist in any symbol library.
253 LIB_ID newLibId( wxEmptyString, newName );
254 LIB_SYMBOL* newLibSymbol = new LIB_SYMBOL( *symbol->GetLibSymbolRef() );
255
256 newLibSymbol->SetLibId( newLibId );
257 newLibSymbol->SetName( newName );
258 symbol->SetLibSymbol( newLibSymbol->Flatten().release() );
259 m_libSymbols[newName] = newLibSymbol;
260 }
261 }
262 }
263 }
264 }
265
266 m_rtree.insert( aItem );
268 }
269}
270
271
273{
274 wxCHECK_RET( aScreen, "Invalid screen object." );
275
276 // No need to descend the hierarchy. Once the top level screen is copied, all of its
277 // children are copied as well.
278 for( SCH_ITEM* aItem : aScreen->m_rtree )
279 Append( aItem );
280
281 aScreen->Clear( false );
282}
283
284
285void SCH_SCREEN::Clear( bool aFree )
286{
287 if( aFree )
288 {
289 FreeDrawList();
291 }
292 else
293 {
294 m_rtree.clear();
295 }
296
297 // Clear the project settings
299
300 m_titles.Clear();
301}
302
303
305{
306 // We don't know which order we will encounter dependent items (e.g. pins or fields), so
307 // we store the items to be deleted until we've fully cleared the tree before deleting
308 std::vector<SCH_ITEM*> delete_list;
309
310 std::copy_if( m_rtree.begin(), m_rtree.end(), std::back_inserter( delete_list ),
311 []( SCH_ITEM* aItem )
312 {
313 return ( aItem->Type() != SCH_SHEET_PIN_T && aItem->Type() != SCH_FIELD_T );
314 } );
315
316 m_rtree.clear();
317
318 for( SCH_ITEM* item : delete_list )
319 delete item;
320}
321
322
323void SCH_SCREEN::Update( SCH_ITEM* aItem, bool aUpdateLibSymbol )
324{
325 if( Remove( aItem, aUpdateLibSymbol ) )
326 Append( aItem, aUpdateLibSymbol );
327}
328
329
330bool SCH_SCREEN::Remove( SCH_ITEM* aItem, bool aUpdateLibSymbol )
331{
332 bool retv = m_rtree.remove( aItem );
333
334 // Check if the library symbol for the removed schematic symbol is still required.
335 if( retv && aItem->Type() == SCH_SYMBOL_T && aUpdateLibSymbol )
336 {
337 SCH_SYMBOL* removedSymbol = static_cast<SCH_SYMBOL*>( aItem );
338
339 bool removeUnusedLibSymbol = true;
340
341 for( SCH_ITEM* item : Items().OfType( SCH_SYMBOL_T ) )
342 {
343 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
344
345 if( removedSymbol->GetSchSymbolLibraryName() == symbol->GetSchSymbolLibraryName() )
346 {
347 removeUnusedLibSymbol = false;
348 break;
349 }
350 }
351
352 if( removeUnusedLibSymbol )
353 {
354 auto it = m_libSymbols.find( removedSymbol->GetSchSymbolLibraryName() );
355
356 if( it != m_libSymbols.end() )
357 {
358 delete it->second;
359 m_libSymbols.erase( it );
360 }
361 }
362 }
363
364 return retv;
365}
366
367
369{
370 wxCHECK_RET( aItem, wxT( "Cannot delete invalid item from screen." ) );
371
372 // Markers are not saved in the file, no need to flag as modified.
373 // TODO: Maybe we should have a listing somewhere of items that aren't saved?
374 if( aItem->Type() != SCH_MARKER_T )
376
377 Remove( aItem );
378
379 if( aItem->Type() == SCH_SHEET_PIN_T )
380 {
381 // This structure is attached to a sheet, get the parent sheet object.
382 SCH_SHEET_PIN* sheetPin = (SCH_SHEET_PIN*) aItem;
383 SCH_SHEET* sheet = sheetPin->GetParent();
384 wxCHECK_RET( sheet, wxT( "Sheet pin parent not properly set, bad programmer!" ) );
385 sheet->RemovePin( sheetPin );
386 return;
387 }
388
389 delete aItem;
390}
391
392
393bool SCH_SCREEN::CheckIfOnDrawList( const SCH_ITEM* aItem ) const
394{
395 return m_rtree.contains( aItem, true );
396}
397
398
399SCH_ITEM* SCH_SCREEN::GetItem( const VECTOR2I& aPosition, int aAccuracy, KICAD_T aType ) const
400{
401 BOX2I bbox;
402 bbox.SetOrigin( aPosition );
403 bbox.Inflate( aAccuracy );
404
405 for( SCH_ITEM* item : Items().Overlapping( aType, bbox ) )
406 {
407 if( item->HitTest( aPosition, aAccuracy ) )
408 return item;
409 }
410
411 return nullptr;
412}
413
414
415std::set<SCH_ITEM*> SCH_SCREEN::MarkConnections( SCH_LINE* aSegment, bool aSecondPass )
416{
417#define PROCESSED CANDIDATE // Don't use SKIP_STRUCT; IsConnected() returns false if it's set.
418
419 std::set<SCH_ITEM*> retval;
420 std::stack<SCH_LINE*> to_search;
421
422 wxCHECK_MSG( aSegment && aSegment->Type() == SCH_LINE_T, retval, wxT( "Invalid pointer." ) );
423
424 to_search.push( aSegment );
425
426 while( !to_search.empty() )
427 {
428 SCH_ITEM* item = to_search.top();
429 to_search.pop();
430
431 if( item->HasFlag( PROCESSED ) )
432 continue;
433
434 item->SetFlags( PROCESSED );
435
436 for( SCH_ITEM* candidate : Items().Overlapping( SCH_LINE_T, item->GetBoundingBox() ) )
437 {
438 SCH_LINE* line = static_cast<SCH_LINE*>( candidate );
439
440 if( line->HasFlag( PROCESSED ) )
441 continue;
442
443 // Skip connecting lines on different layers (e.g. buses)
444 if( item->GetLayer() != line->GetLayer() )
445 continue;
446
447 // SCH_RTREE::Overlapping() included crossing lines.
448 if( !item->IsEndPoint( line->GetStartPoint() ) && !item->IsEndPoint( line->GetEndPoint() ) )
449 continue;
450
451 to_search.push( line );
452 retval.insert( line );
453
454 for( VECTOR2I pt : { line->GetStartPoint(), line->GetEndPoint() } )
455 {
456 if( item->IsConnected( pt ) )
457 {
458 SCH_ITEM* junction = GetItem( pt, 0, SCH_JUNCTION_T );
459
460 if( aSecondPass && junction )
461 retval.insert( junction );
462 }
463 }
464 }
465 }
466
467 for( SCH_ITEM* item : Items() )
468 item->ClearTempFlags();
469
470 return retval;
471}
472
473
474bool SCH_SCREEN::IsJunction( const VECTOR2I& aPosition ) const
475{
477 JUNCTION_HELPERS::AnalyzePoint( Items(), aPosition, false );
478 return info.isJunction;
479}
480
481
482bool SCH_SCREEN::IsExplicitJunction( const VECTOR2I& aPosition ) const
483{
485 JUNCTION_HELPERS::AnalyzePoint( Items(), aPosition, false );
486
487 return info.isJunction && ( !info.hasBusEntry || info.hasBusEntryToMultipleWires );
488}
489
490
491bool SCH_SCREEN::IsExplicitJunctionNeeded( const VECTOR2I& aPosition ) const
492{
494 JUNCTION_HELPERS::AnalyzePoint( Items(), aPosition, false );
495
496 return info.isJunction && ( !info.hasBusEntry || info.hasBusEntryToMultipleWires )
497 && !info.hasExplicitJunctionDot;
498}
499
500
502{
504 JUNCTION_HELPERS::AnalyzePoint( Items(), aPosition, true );
505
506 return info.isJunction && (!info.hasBusEntry || info.hasBusEntryToMultipleWires );
507}
508
509
511 SPIN_STYLE aDefaultOrientation,
512 const SCH_SHEET_PATH* aSheet ) const
513{
514 auto ret = aDefaultOrientation;
515
516 for( SCH_ITEM* item : Items().Overlapping( aPosition ) )
517 {
518 if( item->GetEditFlags() & STRUCT_DELETED )
519 continue;
520
521 switch( item->Type() )
522 {
524 {
525 auto busEntry = static_cast<const SCH_BUS_WIRE_ENTRY*>( item );
526 if( busEntry->m_connected_bus_item )
527 {
528 // bus connected, take the bus direction into consideration only if it is
529 // vertical or horizontal
530 auto bus = static_cast<const SCH_LINE*>( busEntry->m_connected_bus_item );
531 if( bus->Angle().AsDegrees() == 90.0 )
532 {
533 // bus is vertical -> label shall be horizontal and
534 // shall be placed to the side where the bus entry is
535 if( aPosition.x < bus->GetPosition().x )
536 ret = SPIN_STYLE::LEFT;
537 else if( aPosition.x > bus->GetPosition().x )
538 ret = SPIN_STYLE::RIGHT;
539 }
540 else if( bus->Angle().AsDegrees() == 0.0 )
541 {
542 // bus is horizontal -> label shall be vertical and
543 // shall be placed to the side where the bus entry is
544 if( aPosition.y < bus->GetPosition().y )
545 ret = SPIN_STYLE::UP;
546 else if( aPosition.y > bus->GetPosition().y )
547 ret = SPIN_STYLE::BOTTOM;
548 }
549 }
550 }
551 break;
552
553 case SCH_LINE_T:
554 {
555 auto line = static_cast<const SCH_LINE*>( item );
556 // line angles goes between -90 and 90 degrees, but normalize
557 auto angle = line->Angle().Normalize90().AsDegrees();
558
559 if( -45 < angle && angle <= 45 )
560 {
561 if( line->GetStartPoint().x <= line->GetEndPoint().x )
562 ret = line->GetEndPoint() == aPosition ? SPIN_STYLE::RIGHT : SPIN_STYLE::LEFT;
563 else
564 ret = line->GetEndPoint() == aPosition ? SPIN_STYLE::LEFT : SPIN_STYLE::RIGHT;
565 }
566 else
567 {
568 if( line->GetStartPoint().y <= line->GetEndPoint().y )
569 ret = line->GetEndPoint() == aPosition ? SPIN_STYLE::BOTTOM : SPIN_STYLE::UP;
570 else
571 ret = line->GetEndPoint() == aPosition ? SPIN_STYLE::UP : SPIN_STYLE::BOTTOM;
572 }
573 }
574 break;
575
576 case SCH_SYMBOL_T:
577 {
578 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
579
580 for( SCH_PIN* pin : symbol->GetPins( aSheet ) )
581 {
582 if( pin->GetPosition() == aPosition )
583 {
584 ret = GetPinSpinStyle( *pin, *symbol );
585 break;
586 }
587 }
588 }
589 break;
590
591 default: break;
592 }
593 }
594
595 return ret;
596}
597
598
599bool SCH_SCREEN::IsTerminalPoint( const VECTOR2I& aPosition, int aLayer ) const
600{
601 wxCHECK_MSG( aLayer == LAYER_NOTES || aLayer == LAYER_BUS || aLayer == LAYER_WIRE, false,
602 wxT( "Invalid layer type passed to SCH_SCREEN::IsTerminalPoint()." ) );
603
604 SCH_SHEET_PIN* sheetPin;
605 SCH_LABEL_BASE* label;
606
607 switch( aLayer )
608 {
609 case LAYER_BUS:
610 if( GetBus( aPosition ) )
611 return true;
612
613 sheetPin = GetSheetPin( aPosition );
614
615 if( sheetPin && sheetPin->IsConnected( aPosition ) )
616 return true;
617
618 label = GetLabel( aPosition );
619
620 if( label && !label->IsNew() && label->IsConnected( aPosition ) )
621 return true;
622
623 break;
624
625 case LAYER_NOTES:
626 if( GetLine( aPosition ) )
627 return true;
628
629 break;
630
631 case LAYER_WIRE:
632 if( GetItem( aPosition, 1, SCH_BUS_WIRE_ENTRY_T ) )
633 return true;
634
635 if( GetItem( aPosition, 1, SCH_JUNCTION_T ) )
636 return true;
637
638 if( GetPin( aPosition, nullptr, true ) )
639 return true;
640
641 if( GetWire( aPosition ) )
642 return true;
643
644 label = GetLabel( aPosition, 1 );
645
646 if( label && !label->IsNew() && label->IsConnected( aPosition ) )
647 return true;
648
649 sheetPin = GetSheetPin( aPosition );
650
651 if( sheetPin && sheetPin->IsConnected( aPosition ) )
652 return true;
653
654 break;
655
656 default:
657 break;
658 }
659
660 return false;
661}
662
663
665{
666 wxCHECK_RET( Schematic(), "Cannot call SCH_SCREEN::UpdateSymbolLinks with no SCHEMATIC" );
667
668 wxString msg;
669 std::vector<SCH_SYMBOL*> symbols;
671
672 // This will be a nullptr if an s-expression schematic is loaded.
673 SYMBOL_LIBS* legacyLibs = PROJECT_SCH::SchLibs( &Schematic()->Project() );
674
675 for( SCH_ITEM* item : Items().OfType( SCH_SYMBOL_T ) )
676 symbols.push_back( static_cast<SCH_SYMBOL*>( item ) );
677
678 // Remove them from the R tree. Their bounding box size may change.
679 for( SCH_SYMBOL* symbol : symbols )
680 Remove( symbol );
681
682 // Clear all existing symbol links.
684
685 for( SCH_SYMBOL* symbol : symbols )
686 {
687 LIB_SYMBOL* tmp = nullptr;
688
689 // If the symbol is already in the internal library, map the symbol to it.
690 auto it = m_libSymbols.find( symbol->GetSchSymbolLibraryName() );
691
692 if( ( it != m_libSymbols.end() ) )
693 {
694 if( aReporter )
695 {
696 msg.Printf( _( "Setting schematic symbol '%s %s' library identifier to '%s'." ),
697 symbol->GetField( FIELD_T::REFERENCE )->GetText(),
698 symbol->GetField( FIELD_T::VALUE )->GetText(),
699 UnescapeString( symbol->GetLibId().Format() ) );
700 aReporter->ReportTail( msg, RPT_SEVERITY_INFO );
701 }
702
703 // Internal library symbols are already flattened so just make a copy.
704 symbol->SetLibSymbol( new LIB_SYMBOL( *it->second ) );
705 continue;
706 }
707
708 if( !symbol->GetLibId().IsValid() )
709 {
710 if( aReporter )
711 {
712 msg.Printf( _( "Schematic symbol reference '%s' library identifier is not valid. "
713 "Unable to link library symbol." ),
714 UnescapeString( symbol->GetLibId().Format() ) );
715 aReporter->ReportTail( msg, RPT_SEVERITY_WARNING );
716 }
717
718 continue;
719 }
720
721 // LIB_TABLE_BASE::LoadSymbol() throws an IO_ERROR if the library nickname
722 // is not found in the table so check if the library still exists in the table
723 // before attempting to load the symbol.
724 if( !libs->HasLibrary( symbol->GetLibId().GetLibNickname() ) && !legacyLibs )
725 {
726 if( aReporter )
727 {
728 msg.Printf( _( "Symbol library '%s' not found and no fallback cache library "
729 "available. Unable to link library symbol." ),
730 symbol->GetLibId().GetLibNickname().wx_str() );
731 aReporter->ReportTail( msg, RPT_SEVERITY_WARNING );
732 }
733
734 continue;
735 }
736
737 if( libs->HasLibrary( symbol->GetLibId().GetLibNickname() ) )
738 {
739 try
740 {
741 tmp = libs->LoadSymbol( symbol->GetLibId() );
742 }
743 catch( const IO_ERROR& ioe )
744 {
745 if( aReporter )
746 {
747 msg.Printf( _( "I/O error %s resolving library symbol %s" ), ioe.What(),
748 UnescapeString( symbol->GetLibId().Format() ) );
749 aReporter->ReportTail( msg, RPT_SEVERITY_ERROR );
750 }
751 }
752 }
753
754 if( !tmp && legacyLibs && legacyLibs->GetLibraryCount() )
755 {
756 SYMBOL_LIB& legacyCacheLib = legacyLibs->back();
757
758 // It better be the cache library.
759 wxCHECK2( legacyCacheLib.IsCache(), continue );
760
761 wxString id = symbol->GetLibId().Format();
762
763 id.Replace( ':', '_' );
764
765 if( aReporter )
766 {
767 msg.Printf( _( "Falling back to cache to set symbol '%s:%s' link '%s'." ),
768 symbol->GetField( FIELD_T::REFERENCE )->GetText(),
769 symbol->GetField( FIELD_T::VALUE )->GetText(),
770 UnescapeString( id ) );
771 aReporter->ReportTail( msg, RPT_SEVERITY_WARNING );
772 }
773
774 tmp = legacyCacheLib.FindSymbol( id );
775 }
776
777 if( tmp )
778 {
779 // We want a full symbol not just the top level child symbol.
780 std::unique_ptr<LIB_SYMBOL> libSymbol = tmp->Flatten();
781 libSymbol->SetParent();
782
783 m_libSymbols.insert( { symbol->GetSchSymbolLibraryName(),
784 new LIB_SYMBOL( *libSymbol ) } );
785
786 if( aReporter )
787 {
788 msg.Printf( _( "Setting schematic symbol '%s %s' library identifier to '%s'." ),
789 symbol->GetField( FIELD_T::REFERENCE )->GetText(),
790 symbol->GetField( FIELD_T::VALUE )->GetText(),
791 UnescapeString( symbol->GetLibId().Format() ) );
792 aReporter->ReportTail( msg, RPT_SEVERITY_INFO );
793 }
794
795 symbol->SetLibSymbol( libSymbol.release() );
796 }
797 else
798 {
799 if( aReporter )
800 {
801 msg.Printf( _( "No library symbol found for schematic symbol '%s %s'." ),
802 symbol->GetField( FIELD_T::REFERENCE )->GetText(),
803 symbol->GetField( FIELD_T::VALUE )->GetText() );
804 aReporter->ReportTail( msg, RPT_SEVERITY_ERROR );
805 }
806 }
807 }
808
809 // Changing the symbol may adjust the bbox of the symbol. This re-inserts the
810 // item with the new bbox
811 for( SCH_SYMBOL* symbol : symbols )
812 Append( symbol );
813}
814
815
817{
818 std::vector<SCH_SYMBOL*> symbols;
819
820 for( SCH_ITEM* item : Items().OfType( SCH_SYMBOL_T ) )
821 symbols.push_back( static_cast<SCH_SYMBOL*>( item ) );
822
823 for( SCH_SYMBOL* symbol : symbols )
824 {
825 // Changing the symbol may adjust the bbox of the symbol; remove and reinsert it afterwards.
826 m_rtree.remove( symbol );
827
828 auto it = m_libSymbols.find( symbol->GetSchSymbolLibraryName() );
829
830 if( it != m_libSymbols.end() )
831 symbol->SetLibSymbol( new LIB_SYMBOL( *it->second ) );
832 else
833 symbol->SetLibSymbol( nullptr );
834
835 m_rtree.insert( symbol );
836 }
837}
838
839
841{
842 for( SCH_ITEM* item : Items() )
843 item->SetConnectivityDirty( true );
844}
845
846
847void SCH_SCREEN::Plot( PLOTTER* aPlotter, const SCH_PLOT_OPTS& aPlotOpts ) const
848{
849 // Ensure links are up to date, even if a library was reloaded for some reason:
850 std::vector<SCH_ITEM*> junctions;
851 std::vector<SCH_ITEM*> bitmaps;
852 std::vector<SCH_SYMBOL*> symbols;
853 std::vector<SCH_ITEM*> other;
854
855 for( SCH_ITEM* item : Items() )
856 {
857 if( item->IsMoving() )
858 continue;
859
860 if( item->Type() == SCH_JUNCTION_T )
861 junctions.push_back( item );
862 else if( item->Type() == SCH_BITMAP_T )
863 bitmaps.push_back( item );
864 else
865 other.push_back( item );
866
867 // Where the symbols overlap each other, we need to plot the text items a second
868 // time to get them on top of the overlapping element. This collection is in addition
869 // to the symbols already collected in `other`
870 if( item->Type() == SCH_SYMBOL_T )
871 {
872 for( SCH_ITEM* sym : m_rtree.Overlapping( SCH_SYMBOL_T, item->GetBoundingBox() ) )
873 {
874 if( sym != item )
875 {
876 symbols.push_back( static_cast<SCH_SYMBOL*>( item ) );
877 break;
878 }
879 }
880 }
881 }
882
884 std::sort( other.begin(), other.end(),
885 []( const SCH_ITEM* a, const SCH_ITEM* b )
886 {
887 if( a->Type() == b->Type() )
888 return a->GetLayer() > b->GetLayer();
889
890 return a->Type() > b->Type();
891 } );
892
893 auto* renderSettings = static_cast<SCH_RENDER_SETTINGS*>( aPlotter->RenderSettings() );
894 constexpr bool background = true;
895
896 // Bitmaps are drawn first to ensure they are in the background
897 // This is particularly important for the wxPostscriptDC (used in *nix printers) as
898 // the bitmap PS command clears the screen
899 for( SCH_ITEM* item : bitmaps )
900 {
901 aPlotter->SetCurrentLineWidth( item->GetEffectivePenWidth( renderSettings ) );
902 item->Plot( aPlotter, background, aPlotOpts, 0, 0, { 0, 0 }, false );
903 }
904
905 // Plot the background items
906 for( SCH_ITEM* item : other )
907 {
908 aPlotter->SetCurrentLineWidth( item->GetEffectivePenWidth( renderSettings ) );
909 item->Plot( aPlotter, background, aPlotOpts, 0, 0, { 0, 0 }, false );
910 }
911
912 // Plot the foreground items
913 for( SCH_ITEM* item : other )
914 {
915 double lineWidth = item->GetEffectivePenWidth( renderSettings );
916 aPlotter->SetCurrentLineWidth( lineWidth );
917
918 if( item->Type() != SCH_LINE_T )
919 item->Plot( aPlotter, !background, aPlotOpts, 0, 0, { 0, 0 }, false );
920 else
921 {
922 SCH_LINE* aLine = static_cast<SCH_LINE*>( item );
923
924 if( !aLine->IsWire() || !aPlotOpts.m_plotHopOver )
925 {
926 item->Plot( aPlotter, !background, aPlotOpts, 0, 0, { 0, 0 }, false );
927 }
928 else
929 {
930 double arcRadius = lineWidth * aLine->Schematic()->Settings().m_HopOverScale;
931 std::vector<VECTOR3I> curr_wire_shape = aLine->BuildWireWithHopShape( this, arcRadius );
932
933 for( size_t ii = 1; ii < curr_wire_shape.size(); ii++ )
934 {
935 VECTOR2I start( curr_wire_shape[ii-1].x, curr_wire_shape[ii-1].y );
936
937 if( curr_wire_shape[ii-1].z == 0 ) // This is the start point of a segment
938 // there are always 2 points in list for a segment
939 {
940 VECTOR2I end( curr_wire_shape[ii].x, curr_wire_shape[ii].y );
941
942 SCH_LINE curr_line( *aLine );
943 curr_line.SetStartPoint( start );
944 curr_line.SetEndPoint( end );
945 curr_line.Plot( aPlotter, !background, aPlotOpts, 0, 0, { 0, 0 }, false );
946 }
947 else // This is the start point of a arc. there are always 3 points in list for an arc
948 {
949 VECTOR2I arc_middle( curr_wire_shape[ii].x, curr_wire_shape[ii].y );
950 ii++;
951 VECTOR2I arc_end( curr_wire_shape[ii].x, curr_wire_shape[ii].y );
952 ii++;
953
954 SCH_SHAPE arc( SHAPE_T::ARC, aLine->GetLayer(), lineWidth );
955
956 arc.SetArcGeometry( start, arc_middle, arc_end );
957 // Hop are a small arc, so use a solid line style gives best results
958 arc.SetLineStyle( LINE_STYLE::SOLID );
959 arc.Plot( aPlotter, !background, aPlotOpts, 0, 0, { 0, 0 }, false );
960 }
961 }
962 }
963 }
964 }
965
966 // After plotting the symbols as a group above (in `other`), we need to overplot the pins
967 // and symbols to ensure that they are always visible
968 TRANSFORM savedTransform = renderSettings->m_Transform;
969
970 for( const SCH_SYMBOL* sym :symbols )
971 {
972 renderSettings->m_Transform = sym->GetTransform();
973 aPlotter->SetCurrentLineWidth( sym->GetEffectivePenWidth( renderSettings ) );
974
975 for( SCH_FIELD field : sym->GetFields() )
976 {
977 field.ClearRenderCache();
978 field.Plot( aPlotter, false, aPlotOpts, sym->GetUnit(), sym->GetBodyStyle(), { 0, 0 },
979 sym->GetDNP() );
980 }
981
982 sym->PlotPins( aPlotter );
983
984 if( sym->GetDNP() )
985 sym->PlotDNP( aPlotter );
986 }
987
988 renderSettings->m_Transform = savedTransform;
989
990 for( SCH_ITEM* item : junctions )
991 {
992 aPlotter->SetCurrentLineWidth( item->GetEffectivePenWidth( renderSettings ) );
993 item->Plot( aPlotter, !background, aPlotOpts, 0, 0, { 0, 0 }, false );
994 }
995}
996
997
999{
1000 for( SCH_ITEM* item : Items() )
1001 item->ClearTempFlags();
1002}
1003
1004
1005SCH_PIN* SCH_SCREEN::GetPin( const VECTOR2I& aPosition, SCH_SYMBOL** aSymbol,
1006 bool aEndPointOnly ) const
1007{
1008 SCH_SYMBOL* candidate = nullptr;
1009 SCH_PIN* pin = nullptr;
1010
1011 for( SCH_ITEM* item : Items().Overlapping( SCH_SYMBOL_T, aPosition ) )
1012 {
1013 candidate = static_cast<SCH_SYMBOL*>( item );
1014
1015 if( aEndPointOnly )
1016 {
1017 pin = nullptr;
1018
1019 if( !candidate->GetLibSymbolRef() )
1020 continue;
1021
1022 for( SCH_PIN* test_pin : candidate->GetLibPins() )
1023 {
1024 if( candidate->GetPinPhysicalPosition( test_pin ) == aPosition )
1025 {
1026 pin = test_pin;
1027 break;
1028 }
1029 }
1030
1031 if( pin )
1032 break;
1033 }
1034 else
1035 {
1036 pin = static_cast<SCH_PIN*>( candidate->GetDrawItem( aPosition, SCH_PIN_T ) );
1037
1038 if( pin )
1039 break;
1040 }
1041 }
1042
1043 if( pin && aSymbol )
1044 *aSymbol = candidate;
1045
1046 return pin;
1047}
1048
1049
1051{
1052 SCH_SHEET_PIN* sheetPin = nullptr;
1053
1054 for( SCH_ITEM* item : Items().Overlapping( SCH_SHEET_T, aPosition ) )
1055 {
1056 SCH_SHEET* sheet = static_cast<SCH_SHEET*>( item );
1057
1058 sheetPin = sheet->GetPin( aPosition );
1059
1060 if( sheetPin )
1061 break;
1062 }
1063
1064 return sheetPin;
1065}
1066
1067
1068size_t SCH_SCREEN::CountConnectedItems( const VECTOR2I& aPos, bool aTestJunctions ) const
1069{
1070 size_t count = 0;
1071
1072 for( const SCH_ITEM* item : Items().Overlapping( aPos ) )
1073 {
1074 if( ( item->Type() != SCH_JUNCTION_T || aTestJunctions ) && item->IsConnected( aPos ) )
1075 count++;
1076 }
1077
1078 return count;
1079}
1080
1081
1082void SCH_SCREEN::ClearAnnotation( SCH_SHEET_PATH* aSheetPath, bool aResetPrefix )
1083{
1084
1085 for( SCH_ITEM* item : Items().OfType( SCH_SYMBOL_T ) )
1086 {
1087 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
1088
1089 symbol->ClearAnnotation( aSheetPath, aResetPrefix );
1090 }
1091}
1092
1093
1095{
1096 if( GetClientSheetPaths().size() <= 1 ) // No need for alternate reference
1097 return;
1098
1099 for( SCH_ITEM* item : Items().OfType( SCH_SYMBOL_T ) )
1100 {
1101 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
1102
1103 // Add (when not existing) all sheet path entries
1104 for( const SCH_SHEET_PATH& sheet : GetClientSheetPaths() )
1105 symbol->AddSheetPathReferenceEntryIfMissing( sheet.Path() );
1106 }
1107}
1108
1109
1110void SCH_SCREEN::GetHierarchicalItems( std::vector<SCH_ITEM*>* aItems ) const
1111{
1112 static const std::vector<KICAD_T> hierarchicalTypes = { SCH_SYMBOL_T,
1115
1116 for( SCH_ITEM* item : Items() )
1117 {
1118 if( item->IsType( hierarchicalTypes ) )
1119 aItems->push_back( item );
1120 }
1121}
1122
1123
1124void SCH_SCREEN::GetSheets( std::vector<SCH_ITEM*>* aItems ) const
1125{
1126 for( SCH_ITEM* item : Items().OfType( SCH_SHEET_T ) )
1127 aItems->push_back( item );
1128
1129 std::sort( aItems->begin(), aItems->end(),
1130 []( EDA_ITEM* a, EDA_ITEM* b ) -> bool
1131 {
1132 if( a->GetPosition().x == b->GetPosition().x )
1133 {
1134 // Ensure deterministic sort
1135 if( a->GetPosition().y == b->GetPosition().y )
1136 return a->m_Uuid < b->m_Uuid;
1137
1138 return a->GetPosition().y < b->GetPosition().y;
1139 }
1140 else
1141 {
1142 return a->GetPosition().x < b->GetPosition().x;
1143 }
1144 } );
1145}
1146
1147
1149 std::function<void( SCH_ITEM* )>* aChangedHandler ) const
1150{
1151 PROF_TIMER timer( __FUNCTION__ );
1152
1153 std::vector<DANGLING_END_ITEM> endPointsByPos;
1154 std::vector<DANGLING_END_ITEM> endPointsByType;
1155
1156 auto get_ends =
1157 [&]( SCH_ITEM* item )
1158 {
1159 if( item->IsConnectable() )
1160 item->GetEndPoints( endPointsByType );
1161 };
1162
1163 auto update_state =
1164 [&]( SCH_ITEM* item )
1165 {
1166 if( item->UpdateDanglingState( endPointsByType, endPointsByPos, aPath ) )
1167 {
1168 if( aChangedHandler )
1169 ( *aChangedHandler )( item );
1170 }
1171 };
1172
1173 for( SCH_ITEM* item : Items() )
1174 {
1175 get_ends( item );
1176 item->RunOnChildren( get_ends, RECURSE_MODE::NO_RECURSE );
1177 }
1178
1179 PROF_TIMER sortTimer( "SCH_SCREEN::TestDanglingEnds pre-sort" );
1180 endPointsByPos = endPointsByType;
1181 DANGLING_END_ITEM_HELPER::sort_dangling_end_items( endPointsByType, endPointsByPos );
1182 sortTimer.Stop();
1183
1184 if( wxLog::IsAllowedTraceMask( DanglingProfileMask ) )
1185 sortTimer.Show();
1186
1187 for( SCH_ITEM* item : Items() )
1188 {
1189 update_state( item );
1190 item->RunOnChildren( update_state, RECURSE_MODE::NO_RECURSE );
1191 }
1192
1193 if( wxLog::IsAllowedTraceMask( DanglingProfileMask ) )
1194 timer.Show();
1195}
1196
1197
1198SCH_LINE* SCH_SCREEN::GetLine( const VECTOR2I& aPosition, int aAccuracy, int aLayer,
1199 SCH_LINE_TEST_T aSearchType ) const
1200{
1201 // an accuracy of 0 had problems with rounding errors; use at least 1
1202 aAccuracy = std::max( aAccuracy, 1 );
1203
1204 for( SCH_ITEM* item : Items().Overlapping( aPosition, aAccuracy ) )
1205 {
1206 if( item->Type() != SCH_LINE_T )
1207 continue;
1208
1209 if( item->GetLayer() != aLayer )
1210 continue;
1211
1212 if( !item->HitTest( aPosition, aAccuracy ) )
1213 continue;
1214
1215 switch( aSearchType )
1216 {
1217 case ENTIRE_LENGTH_T:
1218 return (SCH_LINE*) item;
1219
1221 if( !( (SCH_LINE*) item )->IsEndPoint( aPosition ) )
1222 return (SCH_LINE*) item;
1223 break;
1224
1225 case END_POINTS_ONLY_T:
1226 if( ( (SCH_LINE*) item )->IsEndPoint( aPosition ) )
1227 return (SCH_LINE*) item;
1228 }
1229 }
1230
1231 return nullptr;
1232}
1233
1234
1235std::vector<SCH_LINE*> SCH_SCREEN::GetBusesAndWires( const VECTOR2I& aPosition,
1236 bool aIgnoreEndpoints ) const
1237{
1238 std::vector<SCH_LINE*> retVal;
1239
1240 for( SCH_ITEM* item : Items().Overlapping( SCH_LINE_T, aPosition ) )
1241 {
1242 if( item->IsType( { SCH_ITEM_LOCATE_WIRE_T, SCH_ITEM_LOCATE_BUS_T } ) )
1243 {
1244 SCH_LINE* wire = static_cast<SCH_LINE*>( item );
1245
1246 if( aIgnoreEndpoints && wire->IsEndPoint( aPosition ) )
1247 continue;
1248
1249 if( IsPointOnSegment( wire->GetStartPoint(), wire->GetEndPoint(), aPosition ) )
1250 retVal.push_back( wire );
1251 }
1252 }
1253
1254 return retVal;
1255}
1256
1257
1258std::vector<VECTOR2I> SCH_SCREEN::GetConnections() const
1259{
1260 std::vector<VECTOR2I> retval;
1261
1262 for( SCH_ITEM* item : Items() )
1263 {
1264 // Avoid items that are changing
1265 if( !( item->GetEditFlags() & ( IS_MOVING | IS_DELETED ) ) )
1266 {
1267 std::vector<VECTOR2I> pts = item->GetConnectionPoints();
1268 retval.insert( retval.end(), pts.begin(), pts.end() );
1269 }
1270 }
1271
1272 // We always have some overlapping connection points. Drop duplicates here
1273 std::sort( retval.begin(), retval.end(),
1274 []( const VECTOR2I& a, const VECTOR2I& b ) -> bool
1275 {
1276 return a.x < b.x || ( a.x == b.x && a.y < b.y );
1277 } );
1278
1279 retval.erase( std::unique( retval.begin(), retval.end() ), retval.end() );
1280
1281 return retval;
1282}
1283
1284
1285std::vector<VECTOR2I> SCH_SCREEN::GetNeededJunctions( const std::deque<EDA_ITEM*>& aItems ) const
1286{
1287 std::vector<VECTOR2I> pts;
1288 std::vector<VECTOR2I> connections = GetConnections();
1289
1290 for( const EDA_ITEM* edaItem : aItems )
1291 {
1292 const SCH_ITEM* item = dynamic_cast<const SCH_ITEM*>( edaItem );
1293
1294 if( !item || !item->IsConnectable() )
1295 continue;
1296
1297 std::vector<VECTOR2I> new_pts = item->GetConnectionPoints();
1298 pts.insert( pts.end(), new_pts.begin(), new_pts.end() );
1299
1300 // If the item is a line, we also add any connection points from the rest of the schematic
1301 // that terminate on the line after it is moved.
1302 if( item->Type() == SCH_LINE_T )
1303 {
1304 SCH_LINE* line = (SCH_LINE*) item;
1305
1306 for( const VECTOR2I& pt : connections )
1307 {
1308 if( IsPointOnSegment( line->GetStartPoint(), line->GetEndPoint(), pt ) )
1309 pts.push_back( pt );
1310 }
1311 }
1312 }
1313
1314 // We always have some overlapping connection points. Drop duplicates here
1315 std::sort( pts.begin(), pts.end(),
1316 []( const VECTOR2I& a, const VECTOR2I& b ) -> bool
1317 {
1318 return a.x < b.x || ( a.x == b.x && a.y < b.y );
1319 } );
1320
1321 pts.erase( unique( pts.begin(), pts.end() ), pts.end() );
1322
1323 // We only want the needed junction points, remove all the others
1324 pts.erase( std::remove_if( pts.begin(), pts.end(),
1325 [this]( const VECTOR2I& a ) -> bool
1326 {
1327 return !IsExplicitJunctionNeeded( a );
1328 } ),
1329 pts.end() );
1330
1331 return pts;
1332}
1333
1334
1335SCH_LABEL_BASE* SCH_SCREEN::GetLabel( const VECTOR2I& aPosition, int aAccuracy ) const
1336{
1337 for( SCH_ITEM* item : Items().Overlapping( aPosition, aAccuracy ) )
1338 {
1339 switch( item->Type() )
1340 {
1341 case SCH_LABEL_T:
1342 case SCH_GLOBAL_LABEL_T:
1343 case SCH_HIER_LABEL_T:
1345 if( item->HitTest( aPosition, aAccuracy ) )
1346 return static_cast<SCH_LABEL_BASE*>( item );
1347
1348 break;
1349
1350 default:
1351 ;
1352 }
1353 }
1354
1355 return nullptr;
1356}
1357
1358
1360{
1361 wxCHECK( aLibSymbol, /* void */ );
1362
1363 wxString libSymbolName = aLibSymbol->GetLibId().Format().wx_str();
1364
1365 auto it = m_libSymbols.find( libSymbolName );
1366
1367 if( it != m_libSymbols.end() )
1368 {
1369 delete it->second;
1370 m_libSymbols.erase( it );
1371 }
1372
1373 m_libSymbols[libSymbolName] = aLibSymbol;
1374}
1375
1376
1378{
1379 SCHEMATIC* schematic = Schematic();
1380
1381 const std::vector<wxString>* embeddedFonts = schematic->GetEmbeddedFiles()->UpdateFontFiles();
1382
1383 for( auto& [name, libSym] : m_libSymbols )
1384 {
1385 for( auto& [filename, embeddedFile] : libSym->EmbeddedFileMap() )
1386 {
1387 EMBEDDED_FILES::EMBEDDED_FILE* file = schematic->GetEmbeddedFile( filename );
1388
1389 if( file )
1390 {
1391 embeddedFile->compressedEncodedData = file->compressedEncodedData;
1392 embeddedFile->decompressedData = file->decompressedData;
1393 embeddedFile->data_hash = file->data_hash;
1394 embeddedFile->is_valid = file->is_valid;
1395 }
1396 }
1397
1398 libSym->RunOnChildren(
1399 [&]( SCH_ITEM* aChild )
1400 {
1401 if( EDA_TEXT* textItem = dynamic_cast<EDA_TEXT*>( aChild ) )
1402 textItem->ResolveFont( embeddedFonts );
1403 },
1404 RECURSE_MODE::NO_RECURSE );
1405 }
1406
1407 std::vector<SCH_ITEM*> items_to_update;
1408
1409 for( SCH_ITEM* item : Items() )
1410 {
1411 bool update = false;
1412
1413 if( EDA_TEXT* textItem = dynamic_cast<EDA_TEXT*>( item ) )
1414 update |= textItem->ResolveFont( embeddedFonts );
1415
1416 item->RunOnChildren(
1417 [&]( SCH_ITEM* aChild )
1418 {
1419 if( EDA_TEXT* textItem = dynamic_cast<EDA_TEXT*>( aChild ) )
1420 update |= textItem->ResolveFont( embeddedFonts );
1421 },
1422 RECURSE_MODE::NO_RECURSE );
1423
1424 if( update )
1425 items_to_update.push_back( item );
1426 }
1427
1428 for( SCH_ITEM* item : items_to_update )
1429 Update( item );
1430}
1431
1432
1433void SCH_SCREEN::AddBusAlias( std::shared_ptr<BUS_ALIAS> aAlias )
1434{
1435 m_aliases.insert( aAlias );
1436}
1437
1438
1440{
1441 for( SCH_ITEM* item : Items().OfType( SCH_SYMBOL_T ) )
1442 {
1443 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
1444
1445 // Add missing value and footprint instance data for legacy schematics.
1446 for( const SCH_SYMBOL_INSTANCE& instance : symbol->GetInstances() )
1447 {
1448 symbol->AddHierarchicalReference( instance.m_Path, instance.m_Reference,
1449 instance.m_Unit );
1450 }
1451 }
1452}
1453
1454
1456{
1457 for( SCH_ITEM* item : Items().OfType( SCH_SYMBOL_T ) )
1458 {
1459 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
1460
1461 // Fix pre-8.0 legacy power symbols with invisible pins
1462 // that have mismatched pin names and value fields
1463 if( symbol->GetLibSymbolRef()
1464 && symbol->GetLibSymbolRef()->IsGlobalPower()
1465 && symbol->GetAllLibPins().size() > 0
1466 && symbol->GetAllLibPins()[0]->IsGlobalPower()
1467 && !symbol->GetAllLibPins()[0]->IsVisible() )
1468 {
1469 symbol->SetValueFieldText( symbol->GetAllLibPins()[0]->GetName() );
1470 }
1471 }
1472}
1473
1474
1476 std::vector<wxString>& aMatches )
1477{
1478 wxString searchName = aSymbol.GetLibId().GetUniStringLibId();
1479
1480 if( m_libSymbols.find( searchName ) != m_libSymbols.end() )
1481 aMatches.emplace_back( searchName );
1482
1483 searchName = aSymbol.GetLibId().GetUniStringLibItemName() + wxS( "_" );
1484
1485 long tmp;
1486 wxString suffix;
1487
1488 for( auto& pair : m_libSymbols )
1489 {
1490 if( pair.first.StartsWith( searchName, &suffix ) && suffix.ToLong( &tmp ) )
1491 aMatches.emplace_back( pair.first );
1492 }
1493
1494 return aMatches.size();
1495}
1496
1497
1498void SCH_SCREEN::PruneOrphanedSymbolInstances( const wxString& aProjectName,
1499 const SCH_SHEET_LIST& aValidSheetPaths )
1500{
1501 // The project name cannot be empty. Projects older than 7.0 did not save project names
1502 // when saving instance data. Running this algorithm with an empty project name would
1503 // clobber all instance data for projects other than the current one when a schematic
1504 // file is shared across multiple projects. Because running the schematic editor in
1505 // stand alone mode can result in an empty project name, do not assert here.
1506 if( aProjectName.IsEmpty() )
1507 return;
1508
1509 for( SCH_ITEM* item : Items().OfType( SCH_SYMBOL_T ) )
1510 {
1511 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
1512
1513 wxCHECK2( symbol, continue );
1514
1515 std::set<KIID_PATH> pathsToPrune;
1516 const std::vector<SCH_SYMBOL_INSTANCE> instances = symbol->GetInstances();
1517
1518 for( const SCH_SYMBOL_INSTANCE& instance : instances )
1519 {
1520 // Ignore instance paths from other projects.
1521 if( aProjectName != instance.m_ProjectName )
1522 continue;
1523
1524 std::optional<SCH_SHEET_PATH> pathFound =
1525 aValidSheetPaths.GetSheetPathByKIIDPath( instance.m_Path );
1526
1527 // Check for paths that do not exist in the current project and paths that do
1528 // not contain the current symbol.
1529 if( !pathFound )
1530 pathsToPrune.emplace( instance.m_Path );
1531 else if( pathFound.value().LastScreen() != this )
1532 pathsToPrune.emplace( pathFound.value().Path() );
1533 }
1534
1535 for( const KIID_PATH& sheetPath : pathsToPrune )
1536 {
1537 wxLogTrace( traceSchSheetPaths, wxS( "Pruning project '%s' symbol instance %s." ),
1538 aProjectName, sheetPath.AsString() );
1539 symbol->RemoveInstance( sheetPath );
1540 }
1541 }
1542}
1543
1544
1545void SCH_SCREEN::PruneOrphanedSheetInstances( const wxString& aProjectName,
1546 const SCH_SHEET_LIST& aValidSheetPaths )
1547{
1548 // The project name cannot be empty. Projects older than 7.0 did not save project names
1549 // when saving instance data. Running this algorithm with an empty project name would
1550 // clobber all instance data for projects other than the current one when a schematic
1551 // file is shared across multiple projects. Because running the schematic editor in
1552 // stand alone mode can result in an empty project name, do not assert here.
1553 if( aProjectName.IsEmpty() )
1554 return;
1555
1556 for( SCH_ITEM* item : Items().OfType( SCH_SHEET_T ) )
1557 {
1558 SCH_SHEET* sheet = static_cast<SCH_SHEET*>( item );
1559
1560 wxCHECK2( sheet, continue );
1561
1562 std::set<KIID_PATH> pathsToPrune;
1563 const std::vector<SCH_SHEET_INSTANCE> instances = sheet->GetInstances();
1564
1565 for( const SCH_SHEET_INSTANCE& instance : instances )
1566 {
1567 // Ignore instance paths from other projects.
1568 if( aProjectName != instance.m_ProjectName )
1569 continue;
1570
1571 std::optional<SCH_SHEET_PATH> pathFound =
1572 aValidSheetPaths.GetSheetPathByKIIDPath( instance.m_Path );
1573
1574 // Check for paths that do not exist in the current project and paths that do
1575 // not contain the current symbol.
1576 if( !pathFound )
1577 pathsToPrune.emplace( instance.m_Path );
1578 else if( pathFound.value().LastScreen() != this )
1579 pathsToPrune.emplace( pathFound.value().Path() );
1580 }
1581
1582 for( const KIID_PATH& sheetPath : pathsToPrune )
1583 {
1584 wxLogTrace( traceSchSheetPaths, wxS( "Pruning project '%s' sheet instance %s." ),
1585 aProjectName, sheetPath.AsString() );
1586 sheet->RemoveInstance( sheetPath );
1587 }
1588 }
1589}
1590
1591
1593{
1594 wxString trimmedFieldName;
1595
1596 for( const SCH_ITEM* item : Items().OfType( SCH_SYMBOL_T ) )
1597 {
1598 const SCH_SYMBOL* symbol = static_cast<const SCH_SYMBOL*>( item );
1599
1600 wxCHECK2( symbol, continue );
1601
1602 for( const SCH_FIELD& field : symbol->GetFields() )
1603 {
1604 trimmedFieldName = field.GetName();
1605 trimmedFieldName.Trim();
1606 trimmedFieldName.Trim( false );
1607
1608 if( field.GetName() != trimmedFieldName )
1609 return true;
1610 }
1611 }
1612
1613 return false;
1614}
1615
1616
1617std::set<wxString> SCH_SCREEN::GetSheetNames() const
1618{
1619 std::set<wxString> retv;
1620
1621 for( SCH_ITEM* item : Items().OfType( SCH_SHEET_T ) )
1622 {
1623 SCH_SHEET* sheet = static_cast<SCH_SHEET*>( item );
1624
1625 wxCHECK2( sheet, continue );
1626
1627 retv.emplace( sheet->GetName() );
1628 }
1629
1630 return retv;
1631}
1632
1633
1635{
1636 wxCHECK( Schematic(), false );
1637
1638 SCH_SHEET_LIST hierarchy = Schematic()->Hierarchy();
1639
1640 for( const SCH_ITEM* item : Items().OfType( SCH_SYMBOL_T ) )
1641 {
1642 const SCH_SYMBOL* symbol = static_cast<const SCH_SYMBOL*>( item );
1643
1644 const std::vector<SCH_SYMBOL_INSTANCE> symbolInstances = symbol->GetInstances();
1645
1646 for( const SCH_SYMBOL_INSTANCE& instance : symbolInstances )
1647 {
1648 if( !hierarchy.HasPath( instance.m_Path ) )
1649 return true;
1650 }
1651 }
1652
1653 return false;
1654}
1655
1656
1657wxString SCH_SCREEN::GroupsSanityCheck( bool repair )
1658{
1659 if( repair )
1660 {
1661 while( GroupsSanityCheckInternal( repair ) != wxEmptyString )
1662 {
1663 };
1664
1665 return wxEmptyString;
1666 }
1667 return GroupsSanityCheckInternal( repair );
1668}
1669
1670
1672{
1673 // Cycle detection
1674 //
1675 // Each group has at most one parent group.
1676 // So we start at group 0 and traverse the parent chain, marking groups seen along the way.
1677 // If we ever see a group that we've already marked, that's a cycle.
1678 // If we reach the end of the chain, we know all groups in that chain are not part of any cycle.
1679 //
1680 // Algorithm below is linear in the # of groups because each group is visited only once.
1681 // There may be extra time taken due to the container access calls and iterators.
1682 //
1683 // Groups we know are cycle free
1684 std::unordered_set<EDA_GROUP*> knownCycleFreeGroups;
1685 // Groups in the current chain we're exploring.
1686 std::unordered_set<EDA_GROUP*> currentChainGroups;
1687 // Groups we haven't checked yet.
1688 std::unordered_set<EDA_GROUP*> toCheckGroups;
1689
1690 // Initialize set of groups and generators to check that could participate in a cycle.
1691 for( SCH_ITEM* item : Items().OfType( SCH_GROUP_T ) )
1692 toCheckGroups.insert( static_cast<SCH_GROUP*>( item ) );
1693
1694 while( !toCheckGroups.empty() )
1695 {
1696 currentChainGroups.clear();
1697 EDA_GROUP* group = *toCheckGroups.begin();
1698
1699 while( true )
1700 {
1701 if( currentChainGroups.find( group ) != currentChainGroups.end() )
1702 {
1703 if( repair )
1704 Remove( static_cast<SCH_ITEM*>( group->AsEdaItem() ) );
1705
1706 return "Cycle detected in group membership";
1707 }
1708 else if( knownCycleFreeGroups.find( group ) != knownCycleFreeGroups.end() )
1709 {
1710 // Parent is a group we know does not lead to a cycle
1711 break;
1712 }
1713
1714 currentChainGroups.insert( group );
1715 // We haven't visited currIdx yet, so it must be in toCheckGroups
1716 toCheckGroups.erase( group );
1717
1718 group = group->AsEdaItem()->GetParentGroup();
1719
1720 if( !group )
1721 {
1722 // end of chain and no cycles found in this chain
1723 break;
1724 }
1725 }
1726
1727 // No cycles found in chain, so add it to set of groups we know don't participate
1728 // in a cycle.
1729 knownCycleFreeGroups.insert( currentChainGroups.begin(), currentChainGroups.end() );
1730 }
1731
1732 // Success
1733 return "";
1734}
1735
1736
1738{
1739 wxCHECK( Schematic() && !m_fileName.IsEmpty(), false );
1740
1741 wxFileName thisScreenFn( m_fileName );
1742 wxFileName thisProjectFn( Schematic()->Project().GetProjectFullName() );
1743
1744 wxCHECK( thisProjectFn.IsAbsolute(), false );
1745
1746 if( thisScreenFn.GetDirCount() < thisProjectFn.GetDirCount() )
1747 return false;
1748
1749 while( thisProjectFn.GetDirCount() != thisScreenFn.GetDirCount() )
1750 thisScreenFn.RemoveLastDir();
1751
1752 return thisScreenFn.GetPath() == thisProjectFn.GetPath();
1753}
1754
1755
1756#if defined(DEBUG)
1757void SCH_SCREEN::Show( int nestLevel, std::ostream& os ) const
1758{
1759 // for now, make it look like XML, expand on this later.
1760 NestedSpace( nestLevel, os ) << '<' << GetClass().Lower().mb_str() << ">\n";
1761
1762 for( const SCH_ITEM* item : Items() )
1763 item->Show( nestLevel + 1, os );
1764
1765 NestedSpace( nestLevel, os ) << "</" << GetClass().Lower().mb_str() << ">\n";
1766}
1767#endif
1768
1769
1771{
1772 m_index = 0;
1773 buildScreenList( aSheet );
1774}
1775
1776
1778{
1779}
1780
1781
1783{
1784 m_index = 0;
1785
1786 if( m_screens.size() > 0 )
1787 return m_screens[0];
1788
1789 return nullptr;
1790}
1791
1792
1794{
1795 if( m_index < m_screens.size() )
1796 m_index++;
1797
1798 return GetScreen( m_index );
1799}
1800
1801
1802SCH_SCREEN* SCH_SCREENS::GetScreen( unsigned int aIndex ) const
1803{
1804 if( aIndex < m_screens.size() )
1805 return m_screens[ aIndex ];
1806
1807 return nullptr;
1808}
1809
1810
1811SCH_SHEET* SCH_SCREENS::GetSheet( unsigned int aIndex ) const
1812{
1813 if( aIndex < m_sheets.size() )
1814 return m_sheets[ aIndex ];
1815
1816 return nullptr;
1817}
1818
1819
1821{
1822 if( aScreen == nullptr )
1823 return;
1824
1825 for( const SCH_SCREEN* screen : m_screens )
1826 {
1827 if( screen == aScreen )
1828 return;
1829 }
1830
1831 m_screens.push_back( aScreen );
1832 m_sheets.push_back( aSheet );
1833}
1834
1835
1837{
1838 if( aSheet && aSheet->Type() == SCH_SHEET_T )
1839 {
1840 SCH_SCREEN* screen = aSheet->GetScreen();
1841
1842 wxCHECK_RET( screen, "No screen for aSheet" );
1843
1844 addScreenToList( screen, aSheet );
1845
1846 for( SCH_ITEM* item : screen->Items().OfType( SCH_SHEET_T ) )
1847 buildScreenList( static_cast<SCH_SHEET*>( item ) );
1848 }
1849}
1850
1851
1853{
1854 SCH_SCREEN* first = GetFirst();
1855
1856 if( !first )
1857 return;
1858
1859 SCHEMATIC* sch = first->Schematic();
1860
1861 wxCHECK_RET( sch, "Null schematic in SCH_SCREENS::ClearAnnotationOfNewSheetPaths" );
1862
1863 // Clear the annotation for symbols inside new sheetpaths not already in aInitialSheetList
1864 SCH_SCREENS screensList( sch->Root() ); // The list of screens, shared by sheet paths
1865 screensList.BuildClientSheetPathList(); // build the shared by sheet paths, by screen
1866
1867 // Search for new sheet paths, not existing in aInitialSheetPathList
1868 // and existing in sheetpathList
1869 for( SCH_SHEET_PATH& sheetpath : sch->Hierarchy() )
1870 {
1871 bool path_exists = false;
1872
1873 for( const SCH_SHEET_PATH& existing_sheetpath: aInitialSheetPathList )
1874 {
1875 if( existing_sheetpath.Path() == sheetpath.Path() )
1876 {
1877 path_exists = true;
1878 break;
1879 }
1880 }
1881
1882 if( !path_exists )
1883 {
1884 // A new sheet path is found: clear the annotation corresponding to this new path:
1885 SCH_SCREEN* curr_screen = sheetpath.LastScreen();
1886
1887 // Clear annotation and create the AR for this path, if not exists,
1888 // when the screen is shared by sheet paths.
1889 // Otherwise ClearAnnotation do nothing, because the F1 field is used as
1890 // reference default value and takes the latest displayed value
1891 curr_screen->EnsureAlternateReferencesExist();
1892 curr_screen->ClearAnnotation( &sheetpath, false );
1893 }
1894 }
1895}
1896
1897
1899{
1900 std::vector<SCH_ITEM*> items;
1901 int count = 0;
1902
1903 auto timestamp_cmp = []( const EDA_ITEM* a, const EDA_ITEM* b ) -> bool
1904 {
1905 return a->m_Uuid < b->m_Uuid;
1906 };
1907
1908 std::set<EDA_ITEM*, decltype( timestamp_cmp )> unique_stamps( timestamp_cmp );
1909
1910 for( SCH_SCREEN* screen : m_screens )
1911 screen->GetHierarchicalItems( &items );
1912
1913 if( items.size() < 2 )
1914 return 0;
1915
1916 for( EDA_ITEM* item : items )
1917 {
1918 if( !unique_stamps.insert( item ).second )
1919 {
1920 // Reset to fully random UUID. This may lose reference, but better to be
1921 // deterministic about it rather than to have duplicate UUIDs with random
1922 // side-effects.
1923 const_cast<KIID&>( item->m_Uuid ) = KIID();
1924 count++;
1925
1926 // @todo If the item is a sheet, we need to descend the hierarchy from the sheet
1927 // and replace all instances of the changed UUID in sheet paths. Otherwise,
1928 // all instance paths with the sheet's UUID will get clobbered.
1929 }
1930 }
1931
1932 return count;
1933}
1934
1935
1937{
1938 for( SCH_SCREEN* screen = GetFirst(); screen; screen = GetNext() )
1939 {
1940 for( SCH_ITEM* item : screen->Items() )
1941 item->ClearEditFlags();
1942 }
1943}
1944
1945
1947{
1948 for( SCH_SCREEN* screen = GetFirst(); screen; screen = GetNext() )
1949 {
1950 for( SCH_ITEM* item : screen->Items().OfType( SCH_MARKER_T ) )
1951 {
1952 if( item == aMarker )
1953 {
1954 screen->DeleteItem( item );
1955 return;
1956 }
1957 }
1958 }
1959}
1960
1961
1962void SCH_SCREENS::DeleteMarkers( enum MARKER_BASE::MARKER_T aMarkerType, int aErrorCode,
1963 bool aIncludeExclusions )
1964{
1965 for( SCH_SCREEN* screen = GetFirst(); screen; screen = GetNext() )
1966 {
1967 std::vector<SCH_ITEM*> markers;
1968
1969 for( SCH_ITEM* item : screen->Items().OfType( SCH_MARKER_T ) )
1970 {
1971 SCH_MARKER* marker = static_cast<SCH_MARKER*>( item );
1972 std::shared_ptr<RC_ITEM>rcItem = marker->GetRCItem();
1973
1974 if( marker->GetMarkerType() == aMarkerType
1975 && ( aErrorCode == ERCE_UNSPECIFIED || rcItem->GetErrorCode() == aErrorCode )
1976 && ( !marker->IsExcluded() || aIncludeExclusions ) )
1977 {
1978 markers.push_back( item );
1979 }
1980 }
1981
1982 for( SCH_ITEM* marker : markers )
1983 screen->DeleteItem( marker );
1984 }
1985}
1986
1987
1989 bool aIncludeExclusions )
1990{
1991 DeleteMarkers( aMarkerType, ERCE_UNSPECIFIED, aIncludeExclusions );
1992}
1993
1994
1996{
1997 for( SCH_SCREEN* screen = GetFirst(); screen; screen = GetNext() )
1998 screen->UpdateSymbolLinks( aReporter );
1999
2000 SCH_SCREEN* first = GetFirst();
2001
2002 if( !first )
2003 return;
2004
2005 SCHEMATIC* sch = first->Schematic();
2006
2007 wxCHECK_RET( sch, "Null schematic in SCH_SCREENS::UpdateSymbolLinks" );
2008
2009 SCH_SHEET_LIST sheets = sch->Hierarchy();
2010
2011 // All of the library symbols have been replaced with copies so the connection graph
2012 // pointers are stale.
2013 if( sch->ConnectionGraph() )
2014 sch->ConnectionGraph()->Recalculate( sheets, true );
2015}
2016
2017
2019{
2020 bool has_symbols = false;
2021
2022 for( SCH_SCREEN* screen = GetFirst(); screen; screen = GetNext() )
2023 {
2024 for( SCH_ITEM* item : screen->Items().OfType( SCH_SYMBOL_T ) )
2025 {
2026 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
2027 has_symbols = true;
2028
2029 if( !symbol->GetLibId().GetLibNickname().empty() )
2030 return false;
2031 }
2032 }
2033
2034 // return true (i.e. has no fully defined symbol) only if at least one symbol is found
2035 return has_symbols ? true : false;
2036}
2037
2038
2039size_t SCH_SCREENS::GetLibNicknames( wxArrayString& aLibNicknames )
2040{
2041 for( SCH_SCREEN* screen = GetFirst(); screen; screen = GetNext() )
2042 {
2043 for( SCH_ITEM* item : screen->Items().OfType( SCH_SYMBOL_T ) )
2044 {
2045 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
2046 const UTF8& nickname = symbol->GetLibId().GetLibNickname();
2047
2048 if( !nickname.empty() && ( aLibNicknames.Index( nickname ) == wxNOT_FOUND ) )
2049 aLibNicknames.Add( nickname );
2050 }
2051 }
2052
2053 return aLibNicknames.GetCount();
2054}
2055
2056
2057int SCH_SCREENS::ChangeSymbolLibNickname( const wxString& aFrom, const wxString& aTo )
2058{
2059 SCH_SCREEN* screen;
2060 int cnt = 0;
2061
2062 for( screen = GetFirst(); screen; screen = GetNext() )
2063 {
2064 for( SCH_ITEM* item : screen->Items().OfType( SCH_SYMBOL_T ) )
2065 {
2066 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
2067
2068 if( symbol->GetLibId().GetLibNickname().wx_str() != aFrom )
2069 continue;
2070
2071 LIB_ID id = symbol->GetLibId();
2072 id.SetLibNickname( aTo );
2073 symbol->SetLibId( id );
2074 cnt++;
2075 }
2076 }
2077
2078 return cnt;
2079}
2080
2081
2082bool SCH_SCREENS::HasSchematic( const wxString& aSchematicFileName )
2083{
2084 for( const SCH_SCREEN* screen = GetFirst(); screen; screen = GetNext() )
2085 {
2086 if( screen->GetFileName() == aSchematicFileName )
2087 return true;
2088 }
2089
2090 return false;
2091}
2092
2093
2095{
2096 SCH_SCREEN* first = GetFirst();
2097
2098 if( !first )
2099 return;
2100
2101 SCHEMATIC* sch = first->Schematic();
2102
2103 wxCHECK_RET( sch, "Null schematic in SCH_SCREENS::BuildClientSheetPathList" );
2104
2105 for( SCH_SCREEN* curr_screen = GetFirst(); curr_screen; curr_screen = GetNext() )
2106 curr_screen->GetClientSheetPaths().clear();
2107
2108 for( SCH_SHEET_PATH& sheetpath : sch->Hierarchy() )
2109 {
2110 SCH_SCREEN* used_screen = sheetpath.LastScreen();
2111
2112 // Search for the used_screen in list and add this unique sheet path:
2113 for( SCH_SCREEN* curr_screen = GetFirst(); curr_screen; curr_screen = GetNext() )
2114 {
2115 if( used_screen == curr_screen )
2116 {
2117 curr_screen->GetClientSheetPaths().push_back( sheetpath );
2118 break;
2119 }
2120 }
2121 }
2122}
2123
2124
2126{
2127 for( SCH_SCREEN* screen = GetFirst(); screen; screen = GetNext() )
2128 screen->SetLegacySymbolInstanceData();
2129}
2130
2131
2133{
2134 for( SCH_SCREEN* screen = GetFirst(); screen; screen = GetNext() )
2135 screen->FixLegacyPowerSymbolMismatches();
2136}
2137
2138
2140{
2141 LOCALE_IO toggle;
2142
2143 // V6 schematics may specify model names in Value fields, which we don't do in V7.
2144 // Migrate by adding an equivalent model for these symbols.
2145
2146 for( SCH_ITEM* item : Items().OfType( SCH_SYMBOL_T ) )
2147 {
2148 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
2149 SIM_MODEL::MigrateSimModel<SCH_SYMBOL>( *symbol, &Schematic()->Project() );
2150 }
2151}
2152
2153
2154void SCH_SCREENS::PruneOrphanedSymbolInstances( const wxString& aProjectName,
2155 const SCH_SHEET_LIST& aValidSheetPaths )
2156{
2157 if( aProjectName.IsEmpty() )
2158 return;
2159
2160 for( SCH_SCREEN* screen = GetFirst(); screen; screen = GetNext() )
2161 screen->PruneOrphanedSymbolInstances( aProjectName, aValidSheetPaths );
2162}
2163
2164
2165void SCH_SCREENS::PruneOrphanedSheetInstances( const wxString& aProjectName,
2166 const SCH_SHEET_LIST& aValidSheetPaths )
2167{
2168 if( aProjectName.IsEmpty() )
2169 return;
2170
2171 for( SCH_SCREEN* screen = GetFirst(); screen; screen = GetNext() )
2172 screen->PruneOrphanedSheetInstances( aProjectName, aValidSheetPaths );
2173}
2174
2175
2177{
2178 for( const SCH_SCREEN* screen : m_screens )
2179 {
2180 if( screen->HasSymbolFieldNamesWithWhiteSpace() )
2181 return true;
2182 }
2183
2184 return false;
2185}
const char * name
Definition: DXF_plotter.cpp:62
constexpr EDA_IU_SCALE schIUScale
Definition: base_units.h:114
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 SetContentModified(bool aModified=true)
Definition: base_screen.h:59
void InitDataPoints(const VECTOR2I &aPageSizeInternalUnits)
Definition: base_screen.cpp:46
constexpr BOX2< Vec > & Inflate(coord_type dx, coord_type dy)
Inflates the rectangle horizontally by dx and vertically by dy.
Definition: box2.h:558
constexpr void SetOrigin(const Vec &pos)
Definition: box2.h:237
void Recalculate(const SCH_SHEET_LIST &aSheetList, bool aUnconditional=false, std::function< void(SCH_ITEM *)> *aChangedItemHandler=nullptr, PROGRESS_REPORTER *aProgressReporter=nullptr)
Update the connection graph for the given list of sheets.
static void sort_dangling_end_items(std::vector< DANGLING_END_ITEM > &aItemListByType, std::vector< DANGLING_END_ITEM > &aItemListByPos)
Both contain the same information.
Definition: sch_item.cpp:816
EDA_ANGLE Normalize90()
Definition: eda_angle.h:257
double AsDegrees() const
Definition: eda_angle.h:116
A set of EDA_ITEMs (i.e., without duplicates).
Definition: eda_group.h:46
A base class for most all the KiCad significant classes used in schematics and boards.
Definition: eda_item.h:98
virtual const BOX2I GetBoundingBox() const
Return the orthogonal bounding box of this object for display purposes.
Definition: eda_item.cpp:110
void SetFlags(EDA_ITEM_FLAGS aMask)
Definition: eda_item.h:142
const KIID m_Uuid
Definition: eda_item.h:516
KICAD_T Type() const
Returns the type of object.
Definition: eda_item.h:110
virtual void SetParent(EDA_ITEM *aParent)
Definition: eda_item.h:113
EDA_ITEM * GetParent() const
Definition: eda_item.h:112
bool HasFlag(EDA_ITEM_FLAGS aFlag) const
Definition: eda_item.h:146
bool IsNew() const
Definition: eda_item.h:124
void SetLineStyle(const LINE_STYLE aStyle)
Definition: eda_shape.cpp:2382
void SetArcGeometry(const VECTOR2I &aStart, const VECTOR2I &aMid, const VECTOR2I &aEnd)
Set the three controlling points for an arc.
Definition: eda_shape.cpp:1041
A mix-in class (via multiple inheritance) that handles texts such as labels, parts,...
Definition: eda_text.h:79
EE_TYPE Overlapping(const BOX2I &aRect) const
Definition: sch_rtree.h:246
bool remove(SCH_ITEM *aItem)
Remove an item from the tree.
Definition: sch_rtree.h:79
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:128
iterator end()
Return a read/write iterator that points to one past the last element in the EE_RTREE.
Definition: sch_rtree.h:289
iterator begin()
Return a read/write iterator that points to the first.
Definition: sch_rtree.h:281
EE_TYPE OfType(KICAD_T aType) const
Definition: sch_rtree.h:241
void clear()
Remove all items from the RTree.
Definition: sch_rtree.h:112
EMBEDDED_FILE * GetEmbeddedFile(const wxString &aName) const
Returns the embedded file with the given name or nullptr if it does not exist.
const std::vector< wxString > * UpdateFontFiles()
Helper function to get a list of fonts for fontconfig to add to the library.
Hold an error message and may be used when throwing exceptions containing meaningful error messages.
Definition: ki_exception.h:77
virtual const wxString What() const
A composite of Problem() and Where()
Definition: exceptions.cpp:30
Definition: kiid.h:49
A logical library item identifier and consists of various portions much like a URI.
Definition: lib_id.h:49
int SetLibNickname(const UTF8 &aLibNickname)
Override the logical library name portion of the LIB_ID to aLibNickname.
Definition: lib_id.cpp:100
wxString GetUniStringLibId() const
Definition: lib_id.h:148
UTF8 Format() const
Definition: lib_id.cpp:119
const wxString GetUniStringLibItemName() const
Get strings for display messages in dialogs.
Definition: lib_id.h:112
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:85
const LIB_ID & GetLibId() const override
Definition: lib_symbol.h:155
LIB_ITEMS_CONTAINER & GetDrawItems()
Return a reference to the draw item list.
Definition: lib_symbol.h:519
wxString GetName() const override
Definition: lib_symbol.h:149
std::unique_ptr< LIB_SYMBOL > Flatten() const
Return a flattened symbol inheritance to the caller.
Definition: lib_symbol.cpp:344
void SetLibId(const LIB_ID &aLibId)
Definition: lib_symbol.h:156
virtual void SetName(const wxString &aName)
Definition: lib_symbol.cpp:328
bool HasLibrary(const wxString &aNickname, bool aCheckEnabled=false) const
Test for the existence of aNickname in the library table.
Instantiate the current locale within a scope in which you are expecting exceptions to be thrown.
Definition: locale_io.h:41
bool IsExcluded() const
Definition: marker_base.h:93
std::shared_ptr< RC_ITEM > GetRCItem() const
Definition: marker_base.h:107
enum MARKER_T GetMarkerType() const
Definition: marker_base.h:91
void sort()
Definition: multivector.h:248
const VECTOR2D GetSizeIU(double aIUScale) const
Gets the page size in internal units.
Definition: page_info.h:171
Base plotter engine class.
Definition: plotter.h:121
RENDER_SETTINGS * RenderSettings()
Definition: plotter.h:152
virtual void SetCurrentLineWidth(int width, void *aData=nullptr)=0
Set the line width for the next drawing.
A small class to help profiling.
Definition: profile.h:49
void Show(std::ostream &aStream=std::cerr)
Print the elapsed time (in a suitable unit) to a stream.
Definition: profile.h:105
void Stop()
Save the time when this function was called, and set the counter stane to stop.
Definition: profile.h:88
static SYMBOL_LIB_TABLE * SchSymbolLibTable(PROJECT *aProject)
Accessor for project symbol library table.
static SYMBOL_LIBS * SchLibs(PROJECT *aProject)
These are all prefaced with "Sch".
Definition: project_sch.cpp:90
A pure virtual class used to derive REPORTER objects from.
Definition: reporter.h:73
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:112
Holds all the data relating to one schematic.
Definition: schematic.h:88
SCHEMATIC_SETTINGS & Settings() const
Definition: schematic.cpp:356
SCH_SHEET_LIST Hierarchy() const
Return the full schematic flattened hierarchical sheet list.
Definition: schematic.cpp:258
EMBEDDED_FILES * GetEmbeddedFiles() override
Definition: schematic.cpp:927
CONNECTION_GRAPH * ConnectionGraph() const
Definition: schematic.h:183
SCH_SHEET & Root() const
Definition: schematic.h:140
Class for a wire to bus entry.
A set of SCH_ITEMs (i.e., without duplicates).
Definition: sch_group.h:52
Base class for any item which can be embedded within the SCHEMATIC container class,...
Definition: sch_item.h:168
virtual bool IsEndPoint(const VECTOR2I &aPt) const
Test if aPt is an end point of this schematic object.
Definition: sch_item.h:489
virtual bool IsConnectable() const
Definition: sch_item.h:498
SCHEMATIC * Schematic() const
Search the item hierarchy to find a SCHEMATIC.
Definition: sch_item.cpp:246
SCH_LAYER_ID GetLayer() const
Return the layer this item is on.
Definition: sch_item.h:313
bool IsConnected(const VECTOR2I &aPoint) const
Test the item to see if it is connected to aPoint.
Definition: sch_item.cpp:343
virtual std::vector< VECTOR2I > GetConnectionPoints() const
Add all the connection points for this item to aPoints.
Definition: sch_item.h:513
Segment description base class to describe items which have 2 end points (track, wire,...
Definition: sch_line.h:42
void SetStartPoint(const VECTOR2I &aPosition)
Definition: sch_line.h:140
std::vector< VECTOR3I > BuildWireWithHopShape(const SCH_SCREEN *aScreen, double aArcRadius) const
For wires only: build the list of points to draw the shape using segments and 180 deg arcs Points are...
Definition: sch_line.cpp:1049
bool IsWire() const
Return true if the line is a wire.
Definition: sch_line.cpp:949
EDA_ANGLE Angle() const
Get the angle between the start and end lines.
Definition: sch_line.h:104
void Plot(PLOTTER *aPlotter, bool aBackground, const SCH_PLOT_OPTS &aPlotOpts, int aUnit, int aBodyStyle, const VECTOR2I &aOffset, bool aDimmed) override
Plot the item to aPlotter.
Definition: sch_line.cpp:840
VECTOR2I GetEndPoint() const
Definition: sch_line.h:144
VECTOR2I GetStartPoint() const
Definition: sch_line.h:139
bool IsEndPoint(const VECTOR2I &aPoint) const override
Test if aPt is an end point of this schematic object.
Definition: sch_line.h:91
void SetEndPoint(const VECTOR2I &aPosition)
Definition: sch_line.h:145
Container class that holds multiple SCH_SCREEN objects in a hierarchy.
Definition: sch_screen.h:758
SCH_SCREEN * GetNext()
unsigned int m_index
Definition: sch_screen.h:894
std::vector< SCH_SHEET * > m_sheets
Definition: sch_screen.h:893
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 DeleteMarkers(enum MARKER_BASE::MARKER_T aMarkerTyp, int aErrorCode, bool aIncludeExclusions=true)
Delete all markers of a particular type and error code.
void buildScreenList(SCH_SHEET *aSheet)
void FixLegacyPowerSymbolMismatches()
Fix legacy power symbols that have mismatched value text fields and invisible power pin names.
SCH_SCREEN * GetFirst()
void DeleteAllMarkers(enum MARKER_BASE::MARKER_T aMarkerType, bool aIncludeExclusions)
Delete all electronic rules check markers of aMarkerType from all the screens in the list.
void PruneOrphanedSheetInstances(const wxString &aProjectName, const SCH_SHEET_LIST &aValidSheetPaths)
int ChangeSymbolLibNickname(const wxString &aFrom, const wxString &aTo)
Change all of the symbol library nicknames.
SCH_SCREENS(SCH_SHEET *aSheet)
void BuildClientSheetPathList()
Build the list of sheet paths sharing a screen for each screen in use.
bool HasSymbolFieldNamesWithWhiteSpace() const
void ClearAnnotationOfNewSheetPaths(SCH_SHEET_LIST &aInitialSheetPathList)
Clear the annotation for the symbols inside new sheetpaths when a complex hierarchy is modified and n...
void PruneOrphanedSymbolInstances(const wxString &aProjectName, const SCH_SHEET_LIST &aValidSheetPaths)
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...
std::vector< SCH_SCREEN * > m_screens
Definition: sch_screen.h:892
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:719
SCH_PIN * GetPin(const VECTOR2I &aPosition, SCH_SYMBOL **aSymbol=nullptr, bool aEndPointOnly=false) const
Test the screen for a symbol pin item at aPosition.
void ClearDrawingState()
Clear the state flags of all the items in the screen.
Definition: sch_screen.cpp:998
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 Append(SCH_ITEM *aItem, bool aUpdateLibSymbol=true)
Definition: sch_screen.cpp:160
void AddLibSymbol(LIB_SYMBOL *aLibSymbol)
Add aLibSymbol to the library symbol map.
bool HasSymbolFieldNamesWithWhiteSpace() const
void AddBusAlias(std::shared_ptr< BUS_ALIAS > aAlias)
Add a bus alias definition (and transfers ownership of the pointer).
void FixLegacyPowerSymbolMismatches()
Fix legacy power symbols that have mismatched value text fields and invisible power pin names.
bool HasItems(KICAD_T aItemType) const
Definition: sch_screen.cpp:146
void Clear(bool aFree=true)
Delete all draw items and clears the project settings.
Definition: sch_screen.cpp:285
bool HasInstanceDataFromOtherProjects() const
Check symbols for instance data from other projects.
void PruneOrphanedSymbolInstances(const wxString &aProjectName, const SCH_SHEET_LIST &aValidSheetPaths)
Remove all invalid symbol instance data in this screen object for the project defined by aProjectName...
std::vector< SCH_SHEET_PATH > & GetClientSheetPaths()
Return the number of times this screen is used.
Definition: sch_screen.h:186
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:664
SCH_LINE * GetWire(const VECTOR2I &aPosition, int aAccuracy=0, SCH_LINE_TEST_T aSearchType=ENTIRE_LENGTH_T) const
Definition: sch_screen.h:436
int m_refCount
Definition: sch_screen.h:687
std::set< wxString > GetSheetNames() const
TITLE_BLOCK m_titles
Definition: sch_screen.h:700
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...
void PruneOrphanedSheetInstances(const wxString &aProjectName, const SCH_SHEET_LIST &aValidSheetPaths)
Remove all invalid sheet instance data in this screen object for the project defined by aProjectName ...
std::vector< SCH_LINE * > GetBusesAndWires(const VECTOR2I &aPosition, bool aIgnoreEndpoints=false) const
Return buses and wires passing through aPosition.
wxString GroupsSanityCheckInternal(bool repair)
int m_modification_sync
Definition: sch_screen.h:704
double m_LastZoomLevel
last value for the zoom level, useful in Eeschema when changing the current displayed sheet to reuse ...
Definition: sch_screen.h:682
bool IsExplicitJunction(const VECTOR2I &aPosition) const
Indicate that a junction dot is necessary at the given location.
Definition: sch_screen.cpp:482
EE_RTREE & Items()
Get the full RTree, usually for iterating.
Definition: sch_screen.h:117
void DecRefCount()
Definition: sch_screen.cpp:139
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 or all gr...
Definition: sch_screen.cpp:415
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:399
bool IsExplicitJunctionAllowed(const VECTOR2I &aPosition) const
Indicate that a junction dot may be placed at the given location.
Definition: sch_screen.cpp:501
void clearLibSymbols()
Definition: sch_screen.cpp:114
wxString m_fileName
Definition: sch_screen.h:685
bool IsTerminalPoint(const VECTOR2I &aPosition, int aLayer) const
Test if aPosition is a connection point on aLayer.
Definition: sch_screen.cpp:599
void UpdateLocalLibSymbolLinks()
Initialize the LIB_SYMBOL reference for each SCH_SYMBOL found in this schematic with the local projec...
Definition: sch_screen.cpp:816
void IncRefCount()
Definition: sch_screen.cpp:133
void SetFileName(const wxString &aFileName)
Set the file name for this screen to aFileName.
Definition: sch_screen.cpp:123
static bool ClassOf(const EDA_ITEM *aItem)
Definition: sch_screen.cpp:154
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:442
bool Remove(SCH_ITEM *aItem, bool aUpdateLibSymbol=true)
Remove aItem from the schematic associated with this screen.
Definition: sch_screen.cpp:330
SCH_SCREEN(EDA_ITEM *aParent=nullptr)
Definition: sch_screen.cpp:79
SCHEMATIC * Schematic() const
Definition: sch_screen.cpp:105
EE_RTREE m_rtree
Definition: sch_screen.h:702
void FixupEmbeddedData()
After loading a file from disk, the library symbols do not yet contain the full data for their embedd...
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
Indicate that a junction dot is necessary at the given location, and does not yet exist.
Definition: sch_screen.cpp:491
SCH_SHEET_PIN * GetSheetPin(const VECTOR2I &aPosition) const
Test the screen if aPosition is a sheet label object.
wxString GroupsSanityCheck(bool repair=false)
Consistency check of internal m_groups structure.
bool InProjectPath() const
Check if the schematic file is in the current project path.
void FreeDrawList()
Free all the items from the schematic associated with the screen.
Definition: sch_screen.cpp:304
void Plot(PLOTTER *aPlotter, const SCH_PLOT_OPTS &aPlotOpts) const
Plot all the schematic objects to aPlotter.
Definition: sch_screen.cpp:847
virtual wxString GetClass() const override
Return the class name.
Definition: sch_screen.h:131
void Update(SCH_ITEM *aItem, bool aUpdateLibSymbol=true)
Update aItem's bounding box in the tree.
Definition: sch_screen.cpp:323
void SetConnectivityDirty()
Definition: sch_screen.cpp:840
bool m_zoomInitialized
Definition: sch_screen.h:707
std::vector< VECTOR2I > GetNeededJunctions(const std::deque< EDA_ITEM * > &aItems) const
Return the unique set of points belonging to aItems where a junction is needed.
PAGE_INFO m_paper
Definition: sch_screen.h:699
bool IsJunction(const VECTOR2I &aPosition) const
Test if a junction is required for the items at aPosition on the screen.
Definition: sch_screen.cpp:474
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:393
std::vector< VECTOR2I > GetConnections() const
Collect a unique list of all possible connection points in the schematic.
SPIN_STYLE GetLabelOrientationForPoint(const VECTOR2I &aPosition, SPIN_STYLE aDefaultOrientation, const SCH_SHEET_PATH *aSheet) const
Definition: sch_screen.cpp:510
void ClearAnnotation(SCH_SHEET_PATH *aSheetPath, bool aResetPrefix)
Clear the annotation for the symbols in aSheetPath on the screen.
size_t CountConnectedItems(const VECTOR2I &aPos, bool aTestJunctions) const
void MigrateSimModels()
Migrate any symbols having V6 simulation models to their V7 equivalents.
void DeleteItem(SCH_ITEM *aItem)
Remove aItem from the linked list and deletes the object.
Definition: sch_screen.cpp:368
std::set< std::shared_ptr< BUS_ALIAS >, BusAliasCmp > m_aliases
List of bus aliases stored in this screen.
Definition: sch_screen.h:716
size_t getLibSymbolNameMatches(const SCH_SYMBOL &aSymbol, std::vector< wxString > &aMatches)
Return a list of potential library symbol matches for aSymbol.
SCH_LABEL_BASE * GetLabel(const VECTOR2I &aPosition, int aAccuracy=0) const
Return a label item located at aPosition.
void Plot(PLOTTER *aPlotter, bool aBackground, const SCH_PLOT_OPTS &aPlotOpts, int aUnit, int aBodyStyle, const VECTOR2I &aOffset, bool aDimmed) override
Plot the item to aPlotter.
Definition: sch_shape.cpp:149
A container for handling SCH_SHEET_PATH objects in a flattened hierarchy.
std::optional< SCH_SHEET_PATH > GetSheetPathByKIIDPath(const KIID_PATH &aPath, bool aIncludeLastSheet=true) const
Finds a SCH_SHEET_PATH that matches the provided KIID_PATH.
bool HasPath(const KIID_PATH &aPath) const
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:47
void RemoveInstance(const KIID_PATH &aInstancePath)
Definition: sch_sheet.cpp:1337
wxString GetName() const
Definition: sch_sheet.h:113
SCH_SHEET_PIN * GetPin(const VECTOR2I &aPosition)
Return the sheet pin item found at aPosition in the sheet.
Definition: sch_sheet.cpp:611
void RemovePin(const SCH_SHEET_PIN *aSheetPin)
Remove aSheetPin from the sheet.
Definition: sch_sheet.cpp:409
SCH_SCREEN * GetScreen() const
Definition: sch_sheet.h:116
const std::vector< SCH_SHEET_INSTANCE > & GetInstances() const
Definition: sch_sheet.h:429
Schematic symbol object.
Definition: sch_symbol.h:75
void SetLibId(const LIB_ID &aName)
Definition: sch_symbol.cpp:237
SCH_ITEM * GetDrawItem(const VECTOR2I &aPosition, KICAD_T aType=TYPE_NOT_INIT)
Return the symbol library item at aPosition that is part of this symbol.
const std::vector< SCH_SYMBOL_INSTANCE > & GetInstances() const
Definition: sch_symbol.h:134
void RemoveInstance(const SCH_SHEET_PATH &aInstancePath)
Definition: sch_symbol.cpp:492
void SetValueFieldText(const wxString &aValue)
Definition: sch_symbol.cpp:738
wxString GetSchSymbolLibraryName() const
Definition: sch_symbol.cpp:243
bool AddSheetPathReferenceEntryIfMissing(const KIID_PATH &aSheetPath)
Add an instance to the alternate references list (m_instanceReferences), if this entry does not alrea...
void ClearAnnotation(const SCH_SHEET_PATH *aSheetPath, bool aResetPrefix)
Clear exiting symbol annotation.
void GetFields(std::vector< SCH_FIELD * > &aVector, bool aVisibleOnly) const override
Populate a std::vector with SCH_FIELDs, sorted in ordinal order.
Definition: sch_symbol.cpp:788
std::vector< SCH_PIN * > GetAllLibPins() const
void AddHierarchicalReference(const KIID_PATH &aPath, const wxString &aRef, int aUnit)
Add a full hierarchical reference to this symbol.
Definition: sch_symbol.cpp:520
std::vector< SCH_PIN * > GetPins(const SCH_SHEET_PATH *aSheet) const
Retrieve a list of the SCH_PINs for the given sheet path.
const LIB_ID & GetLibId() const override
Definition: sch_symbol.h:164
void SetSchSymbolLibraryName(const wxString &aName)
The name of the symbol in the schematic library symbol list.
Definition: sch_symbol.h:179
std::vector< SCH_PIN * > GetLibPins() const
Populate a vector with all the pins from the library object that match the current unit and bodyStyle...
std::unique_ptr< LIB_SYMBOL > & GetLibSymbolRef()
Definition: sch_symbol.h:183
void SetLibSymbol(LIB_SYMBOL *aLibSymbol)
Set this schematic symbol library symbol reference to aLibSymbol.
Definition: sch_symbol.cpp:252
VECTOR2I GetPinPhysicalPosition(const SCH_PIN *Pin) const
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
for transforming drawing coordinates for a wxDC device context.
Definition: transform.h:46
An 8 bit string that is assuredly encoded in UTF8, and supplies special conversion support to and fro...
Definition: utf8.h:72
bool empty() const
Definition: utf8.h:110
wxString wx_str() const
Definition: utf8.cpp:45
#define _(s)
#define IS_DELETED
#define STRUCT_DELETED
flag indication structures to be erased
#define IS_MOVING
Item being moved.
@ ERCE_UNSPECIFIED
Definition: erc_settings.h:37
static const wxChar DanglingProfileMask[]
Flag to enable profiling of the TestDanglingEnds() function.
Definition: sch_screen.cpp:76
const wxChar *const traceSchSheetPaths
Flag to enable debug output of schematic symbol sheet path manipulation code.
@ LAYER_WIRE
Definition: layer_ids.h:442
@ LAYER_NOTES
Definition: layer_ids.h:457
@ LAYER_BUS
Definition: layer_ids.h:443
POINT_INFO AnalyzePoint(const EE_RTREE &aItem, const VECTOR2I &aPosition, bool aBreakCrossings)
Check a tree of items for a confluence at a given point and work out what kind of junction it is,...
@ RPT_SEVERITY_WARNING
@ RPT_SEVERITY_ERROR
@ RPT_SEVERITY_INFO
Class to handle a set of SCH_ITEMs.
#define PROCESSED
SCH_LINE_TEST_T
Definition: sch_screen.h:71
@ ENTIRE_LENGTH_T
Definition: sch_screen.h:72
@ EXCLUDE_END_POINTS_T
Definition: sch_screen.h:74
@ END_POINTS_ONLY_T
Definition: sch_screen.h:73
wxString UnescapeString(const wxString &aSource)
const double IU_PER_MILS
Definition: base_units.h:77
The EE_TYPE struct provides a type-specific auto-range iterator to the RTree.
Definition: sch_rtree.h:195
iterator begin()
Definition: sch_rtree.h:225
iterator end()
Definition: sch_rtree.h:230
std::vector< char > decompressedData
A selection of information about a point in the schematic that might be eligible for turning into a j...
bool m_plotHopOver
Definition: sch_plotter.h:60
A simple container for sheet instance information.
A simple container for schematic symbol instance information.
SPIN_STYLE GetPinSpinStyle(const SCH_PIN &aPin, const SCH_SYMBOL &aSymbol)
Get the spin style for a pin's label, taking into account the pin's orientation, as well as the given...
Definition for symbol library class.
VECTOR2I end
wxLogTrace helper definitions.
bool IsPointOnSegment(const VECTOR2I &aSegStart, const VECTOR2I &aSegEnd, const VECTOR2I &aTestPoint)
Test if aTestPoint is on line defined by aSegStart and aSegEnd.
Definition: trigo.cpp:89
KICAD_T
The set of class identification values stored in EDA_ITEM::m_structType.
Definition: typeinfo.h:78
@ SCH_GROUP_T
Definition: typeinfo.h:174
@ SCH_LINE_T
Definition: typeinfo.h:164
@ SCH_SYMBOL_T
Definition: typeinfo.h:173
@ SCH_FIELD_T
Definition: typeinfo.h:151
@ SCH_DIRECTIVE_LABEL_T
Definition: typeinfo.h:172
@ SCH_LABEL_T
Definition: typeinfo.h:168
@ SCH_SHEET_T
Definition: typeinfo.h:176
@ SCH_MARKER_T
Definition: typeinfo.h:159
@ SCH_HIER_LABEL_T
Definition: typeinfo.h:170
@ SCH_SCREEN_T
Definition: typeinfo.h:203
@ SCH_LABEL_LOCATE_ANY_T
Definition: typeinfo.h:192
@ SCHEMATIC_T
Definition: typeinfo.h:205
@ SCH_SHEET_PIN_T
Definition: typeinfo.h:175
@ SCH_BUS_WIRE_ENTRY_T
Definition: typeinfo.h:162
@ SCH_BITMAP_T
Definition: typeinfo.h:165
@ SCH_GLOBAL_LABEL_T
Definition: typeinfo.h:169
@ SCH_JUNCTION_T
Definition: typeinfo.h:160
@ SCH_PIN_T
Definition: typeinfo.h:154