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 <dick@softplc.com>
6  * Copyright (C) 2008 Wayne Stambaugh <stambaughw@gmail.com>
7  * Copyright (C) 1992-2021 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 
32 #include <wx/filefn.h>
33 
34 #include <eda_item.h>
35 #include <eda_rect.h>
36 #include <id.h>
37 #include <kicad_string.h>
38 #include <kiway.h>
39 #include <plotter.h>
40 #include <project.h>
41 #include <reporter.h>
42 #include <sch_draw_panel.h>
43 #include <sch_edit_frame.h>
44 #include <sch_item.h>
45 
46 #include <symbol_library.h>
47 #include <connection_graph.h>
48 #include <lib_pin.h>
49 #include <sch_symbol.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>
57 #include <symbol_lib_table.h>
58 #include <tool/common_tools.h>
59 
60 #include <algorithm>
61 
62 // TODO(JE) Debugging only
63 #include <profile.h>
64 #include "sch_bus_entry.h"
65 
67  BASE_SCREEN( aParent, SCH_SCREEN_T ),
68  m_fileFormatVersionAtLoad( 0 ),
69  m_paper( wxT( "A4" ) )
70 {
72  m_refCount = 0;
73  m_zoomInitialized = false;
74  m_LastZoomLevel = 1.0;
75 
76  // Suitable for schematic only. For symbol_editor and viewlib, must be set to true
77  m_Center = false;
78 
79  InitDataPoints( m_paper.GetSizeIU() );
80 }
81 
82 
84 {
86  FreeDrawList();
87 }
88 
89 
91 {
92  wxCHECK_MSG( GetParent() && GetParent()->Type() == SCHEMATIC_T, nullptr,
93  "SCH_SCREEN must have a SCHEMATIC parent!" );
94 
95  return static_cast<SCHEMATIC*>( GetParent() );
96 }
97 
98 
100 {
101  for( auto libSymbol : m_libSymbols )
102  delete libSymbol.second;
103 
104  m_libSymbols.clear();
105 }
106 
107 
108 void SCH_SCREEN::SetFileName( const wxString& aFileName )
109 {
110  wxASSERT( aFileName.IsEmpty() || wxIsAbsolutePath( aFileName ) );
111 
112  m_fileName = aFileName;
113 }
114 
115 
117 {
118  m_refCount++;
119 }
120 
121 
123 {
124  wxCHECK_RET( m_refCount != 0,
125  wxT( "Screen reference count already zero. Bad programmer!" ) );
126  m_refCount--;
127 }
128 
129 
130 bool SCH_SCREEN::HasItems( KICAD_T aItemType ) const
131 {
132  EE_RTREE::EE_TYPE sheets = m_rtree.OfType( aItemType );
133 
134  return sheets.begin() != sheets.end();
135 }
136 
137 
138 bool SCH_SCREEN::ClassOf( const EDA_ITEM* aItem )
139 {
140  return aItem && SCH_SCREEN_T == aItem->Type();
141 }
142 
143 
145 {
146  if( aItem->Type() != SCH_SHEET_PIN_T && aItem->Type() != SCH_FIELD_T )
147  {
148  // Ensure the item can reach the SCHEMATIC through this screen
149  aItem->SetParent( this );
150 
151  if( aItem->Type() == SCH_SYMBOL_T )
152  {
153  SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( aItem );
154 
155  if( symbol->GetLibSymbolRef() )
156  {
157  symbol->GetLibSymbolRef()->GetDrawItems().sort();
158 
159  auto it = m_libSymbols.find( symbol->GetSchSymbolLibraryName() );
160 
161  if( it == m_libSymbols.end() || !it->second )
162  {
164  new LIB_SYMBOL( *symbol->GetLibSymbolRef() );
165  }
166  else
167  {
168  // The original library symbol may have changed since the last time
169  // it was added to the schematic. If it has changed, then a new name
170  // must be created for the library symbol list to prevent all of the
171  // other schematic symbols referencing that library symbol from changing.
172  LIB_SYMBOL* foundSymbol = it->second;
173 
174  foundSymbol->GetDrawItems().sort();
175 
176  if( *foundSymbol != *symbol->GetLibSymbolRef() )
177  {
178  int cnt = 1;
179  wxString newName;
180 
181  newName.Printf( "%s_%d", symbol->GetLibId().Format().wx_str(), cnt );
182 
183  while( m_libSymbols.find( newName ) != m_libSymbols.end() )
184  {
185  cnt += 1;
186  newName.Printf( "%s_%d", symbol->GetLibId().Format().wx_str(), cnt );
187  }
188 
189  symbol->SetSchSymbolLibraryName( newName );
190  m_libSymbols[newName] = new LIB_SYMBOL( *symbol->GetLibSymbolRef() );
191  }
192  }
193  }
194  }
195 
196  m_rtree.insert( aItem );
198  }
199 }
200 
201 
203 {
204  wxCHECK_RET( aScreen, "Invalid screen object." );
205 
206  // No need to descend the hierarchy. Once the top level screen is copied, all of its
207  // children are copied as well.
208  for( auto aItem : aScreen->m_rtree )
209  Append( aItem );
210 
211  aScreen->Clear( false );
212 }
213 
214 
215 void SCH_SCREEN::Clear( bool aFree )
216 {
217  if( aFree )
218  {
219  FreeDrawList();
220  clearLibSymbols();
221  }
222  else
223  {
224  m_rtree.clear();
225  }
226 
227  // Clear the project settings
229 
230  m_titles.Clear();
231 }
232 
233 
235 {
236  // We don't know which order we will encounter dependent items (e.g. pins or fields), so
237  // we store the items to be deleted until we've fully cleared the tree before deleting
238  std::vector<SCH_ITEM*> delete_list;
239 
240  std::copy_if( m_rtree.begin(), m_rtree.end(), std::back_inserter( delete_list ),
241  []( SCH_ITEM* aItem )
242  {
243  return ( aItem->Type() != SCH_SHEET_PIN_T && aItem->Type() != SCH_FIELD_T );
244  } );
245 
246  m_rtree.clear();
247 
248  for( auto item : delete_list )
249  delete item;
250 }
251 
252 
254 {
255  if( Remove( aItem ) )
256  Append( aItem );
257 }
258 
259 
261 {
262  bool retv = m_rtree.remove( aItem );
263 
264  // Check if the library symbol for the removed schematic symbol is still required.
265  if( retv && aItem->Type() == SCH_SYMBOL_T )
266  {
267  SCH_SYMBOL* removedSymbol = static_cast<SCH_SYMBOL*>( aItem );
268 
269  bool removeUnusedLibSymbol = true;
270 
271  for( SCH_ITEM* item : Items().OfType( SCH_SYMBOL_T ) )
272  {
273  SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
274 
275  if( removedSymbol->GetSchSymbolLibraryName() == symbol->GetSchSymbolLibraryName() )
276  {
277  removeUnusedLibSymbol = false;
278  break;
279  }
280  }
281 
282  if( removeUnusedLibSymbol )
283  {
284  auto it = m_libSymbols.find( removedSymbol->GetSchSymbolLibraryName() );
285 
286  if( it != m_libSymbols.end() )
287  {
288  delete it->second;
289  m_libSymbols.erase( it );
290  }
291  }
292  }
293 
294  return retv;
295 }
296 
297 
299 {
300  wxCHECK_RET( aItem, wxT( "Cannot delete invalid item from screen." ) );
301 
302  // Markers are not saved in the file, no need to flag as modified.
303  // TODO: Maybe we should have a listing somewhere of items that aren't saved?
304  if( aItem->Type() != SCH_MARKER_T )
306 
307  Remove( aItem );
308 
309  if( aItem->Type() == SCH_SHEET_PIN_T )
310  {
311  // This structure is attached to a sheet, get the parent sheet object.
312  SCH_SHEET_PIN* sheetPin = (SCH_SHEET_PIN*) aItem;
313  SCH_SHEET* sheet = sheetPin->GetParent();
314  wxCHECK_RET( sheet, wxT( "Sheet pin parent not properly set, bad programmer!" ) );
315  sheet->RemovePin( sheetPin );
316  return;
317  }
318 
319  delete aItem;
320 }
321 
322 
323 bool SCH_SCREEN::CheckIfOnDrawList( const SCH_ITEM* aItem ) const
324 {
325  return m_rtree.contains( aItem, true );
326 }
327 
328 
329 SCH_ITEM* SCH_SCREEN::GetItem( const wxPoint& aPosition, int aAccuracy, KICAD_T aType ) const
330 {
331  EDA_RECT bbox;
332  bbox.SetOrigin( aPosition );
333  bbox.Inflate( aAccuracy );
334 
335  for( SCH_ITEM* item : Items().Overlapping( aType, bbox ) )
336  {
337  if( item->HitTest( aPosition, aAccuracy ) )
338  return item;
339  }
340 
341  return nullptr;
342 }
343 
344 
345 std::set<SCH_ITEM*> SCH_SCREEN::MarkConnections( SCH_LINE* aSegment )
346 {
347  std::set<SCH_ITEM*> retval;
348  std::stack<SCH_LINE*> to_search;
349 
350  wxCHECK_MSG( aSegment && aSegment->Type() == SCH_LINE_T, retval, wxT( "Invalid pointer." ) );
351 
352  to_search.push( aSegment );
353 
354  while( !to_search.empty() )
355  {
356  SCH_LINE* test_item = to_search.top();
357  to_search.pop();
358 
359  for( SCH_ITEM* item : Items().Overlapping( SCH_JUNCTION_T, test_item->GetBoundingBox() ) )
360  {
361  if( test_item->IsEndPoint( item->GetPosition() ) )
362  retval.insert( item );
363  }
364 
365  for( SCH_ITEM* item : Items().Overlapping( SCH_LINE_T, test_item->GetBoundingBox() ) )
366  {
367  // Skip connecting lines on different layers (e.g. buses)
368  if( test_item->GetLayer() != item->GetLayer() )
369  continue;
370 
371  SCH_LINE* line = static_cast<SCH_LINE*>( item );
372 
373  if( ( test_item->IsEndPoint( line->GetStartPoint() )
374  && !GetPin( line->GetStartPoint(), nullptr, true ) )
375  || ( test_item->IsEndPoint( line->GetEndPoint() )
376  && !GetPin( line->GetEndPoint(), nullptr, true ) ) )
377  {
378  auto result = retval.insert( line );
379 
380  if( result.second )
381  to_search.push( line );
382  }
383  }
384  }
385 
386  return retval;
387 }
388 
389 
390 bool SCH_SCREEN::IsJunctionNeeded( const wxPoint& aPosition, bool aNew ) const
391 {
392  enum layers { WIRES = 0, BUSES };
393 
394  bool breakLines[ 2 ] = { false };
395  std::unordered_set<int> exitAngles[ 2 ];
396  std::vector<const SCH_LINE*> midPointLines[ 2 ];
397 
398  // A pin at 90º still shouldn't match a line at 90º so just give pins unique numbers
399  int uniqueAngle = 10000;
400 
401  for( const SCH_ITEM* item : Items().Overlapping( aPosition ) )
402  {
403  if( item->GetEditFlags() & STRUCT_DELETED )
404  continue;
405 
406  switch( item->Type() )
407  {
408  case SCH_JUNCTION_T:
409  if( aNew && item->HitTest( aPosition, -1 ) )
410  return false;
411 
412  break;
413 
414  case SCH_LINE_T:
415  {
416  const SCH_LINE* line = static_cast<const SCH_LINE*>( item );
417  int layer;
418 
419  if( line->GetStartPoint() == line->GetEndPoint() )
420  break;
421  else if( line->GetLayer() == LAYER_WIRE )
422  layer = WIRES;
423  else if( line->GetLayer() == LAYER_BUS )
424  layer = BUSES;
425  else
426  break;
427 
428  if( line->IsConnected( aPosition ) )
429  {
430  breakLines[ layer ] = true;
431  exitAngles[ layer ].insert( line->GetAngleFrom( aPosition ) );
432  }
433  else if( line->HitTest( aPosition, -1 ) )
434  {
435  // Defer any line midpoints until we know whether or not we're breaking them
436  midPointLines[ layer ].push_back( line );
437  }
438  }
439  break;
440 
442  case SCH_SYMBOL_T:
443  case SCH_SHEET_T:
444  if( item->IsConnected( aPosition ) )
445  {
446  breakLines[ WIRES ] = true;
447  exitAngles[ WIRES ].insert( uniqueAngle++ );
448  }
449 
450  break;
451 
452  default:
453  break;
454  }
455  }
456 
457  for( int layer : { WIRES, BUSES } )
458  {
459  if( breakLines[ layer ] )
460  {
461  for( const SCH_LINE* line : midPointLines[ layer ] )
462  {
463  exitAngles[ layer ].insert( line->GetAngleFrom( aPosition ) );
464  exitAngles[ layer ].insert( line->GetReverseAngleFrom( aPosition ) );
465  }
466  }
467  }
468 
469  return exitAngles[ WIRES ].size() >= 3 || exitAngles[ BUSES ].size() >= 3;
470 }
471 
472 
473 bool SCH_SCREEN::IsTerminalPoint( const wxPoint& aPosition, int aLayer ) const
474 {
475  wxCHECK_MSG( aLayer == LAYER_NOTES || aLayer == LAYER_BUS || aLayer == LAYER_WIRE, false,
476  wxT( "Invalid layer type passed to SCH_SCREEN::IsTerminalPoint()." ) );
477 
478  switch( aLayer )
479  {
480  case LAYER_BUS:
481  {
482  if( GetBus( aPosition ) )
483  return true;
484 
485  SCH_SHEET_PIN* sheetPin = GetSheetPin( aPosition );
486 
487  if( sheetPin && sheetPin->IsConnected( aPosition ) )
488  return true;
489 
490  SCH_TEXT* label = GetLabel( aPosition );
491 
492  if( label && label->IsConnected( aPosition ) )
493  return true;
494  }
495  break;
496 
497  case LAYER_NOTES:
498  {
499  if( GetLine( aPosition ) )
500  return true;
501  }
502  break;
503 
504  case LAYER_WIRE:
505  {
506  if( GetItem( aPosition, 1, SCH_BUS_WIRE_ENTRY_T) )
507  return true;
508 
509  if( GetItem( aPosition, 1, SCH_JUNCTION_T ) )
510  return true;
511 
512  if( GetPin( aPosition, nullptr, true ) )
513  return true;
514 
515  if( GetWire( aPosition ) )
516  return true;
517 
518  SCH_TEXT* label = GetLabel( aPosition, 1 );
519 
520  if( label && label->IsConnected( aPosition ) )
521  return true;
522 
523  SCH_SHEET_PIN* sheetPin = GetSheetPin( aPosition );
524 
525  if( sheetPin && sheetPin->IsConnected( aPosition ) )
526  return true;
527  }
528  break;
529 
530  default:
531  break;
532  }
533 
534  return false;
535 }
536 
537 
539 {
540  wxCHECK_RET( Schematic(), "Cannot call SCH_SCREEN::UpdateSymbolLinks with no SCHEMATIC" );
541 
542  wxString msg;
543  std::unique_ptr< LIB_SYMBOL > libSymbol;
544  std::vector<SCH_SYMBOL*> symbols;
545  SYMBOL_LIB_TABLE* libs = Schematic()->Prj().SchSymbolLibTable();
546 
547  // This will be a nullptr if an s-expression schematic is loaded.
548  SYMBOL_LIBS* legacyLibs = Schematic()->Prj().SchLibs();
549 
550  for( auto item : Items().OfType( SCH_SYMBOL_T ) )
551  symbols.push_back( static_cast<SCH_SYMBOL*>( item ) );
552 
553  // Remove them from the R tree. There bounding box size may change.
554  for( auto symbol : symbols )
555  Remove( symbol );
556 
557  // Clear all existing symbol links.
558  clearLibSymbols();
559 
560  for( auto symbol : symbols )
561  {
562  LIB_SYMBOL* tmp = nullptr;
563  libSymbol.reset();
564 
565  // If the symbol is already in the internal library, map the symbol to it.
566  auto it = m_libSymbols.find( symbol->GetSchSymbolLibraryName() );
567 
568  if( ( it != m_libSymbols.end() ) )
569  {
570  if( aReporter )
571  {
572  msg.Printf( _( "Setting schematic symbol '%s %s' library identifier "
573  "to '%s'. " ),
574  symbol->GetField( REFERENCE_FIELD )->GetText(),
575  symbol->GetField( VALUE_FIELD )->GetText(),
576  symbol->GetLibId().Format().wx_str() );
577  aReporter->ReportTail( msg, RPT_SEVERITY_INFO );
578  }
579 
580  // Internal library symbols are already flattened so just make a copy.
581  symbol->SetLibSymbol( new LIB_SYMBOL( *it->second ) );
582  continue;
583  }
584 
585  if( !symbol->GetLibId().IsValid() )
586  {
587  if( aReporter )
588  {
589  msg.Printf( _( "Schematic symbol reference '%s' library identifier is not "
590  "valid. Unable to link library symbol." ),
591  symbol->GetLibId().Format().wx_str() );
592  aReporter->ReportTail( msg, RPT_SEVERITY_WARNING );
593  }
594 
595  continue;
596  }
597 
598  // LIB_TABLE_BASE::LoadSymbol() throws an IO_ERROR if the library nickname
599  // is not found in the table so check if the library still exists in the table
600  // before attempting to load the symbol.
601  if( !libs->HasLibrary( symbol->GetLibId().GetLibNickname() ) && !legacyLibs )
602  {
603  if( aReporter )
604  {
605  msg.Printf( _( "Symbol library '%s' not found and no fallback cache "
606  "library available. Unable to link library symbol." ),
607  symbol->GetLibId().GetLibNickname().wx_str() );
608  aReporter->ReportTail( msg, RPT_SEVERITY_WARNING );
609  }
610 
611  continue;
612  }
613 
614  if( libs->HasLibrary( symbol->GetLibId().GetLibNickname() ) )
615  {
616  try
617  {
618  tmp = libs->LoadSymbol( symbol->GetLibId() );
619  }
620  catch( const IO_ERROR& ioe )
621  {
622  if( aReporter )
623  {
624  msg.Printf( _( "I/O error %s resolving library symbol %s" ), ioe.What(),
625  symbol->GetLibId().Format().wx_str() );
626  aReporter->ReportTail( msg, RPT_SEVERITY_ERROR );
627  }
628  }
629  }
630 
631  if( !tmp && legacyLibs && legacyLibs->GetLibraryCount() )
632  {
633  SYMBOL_LIB& legacyCacheLib = legacyLibs->at( 0 );
634 
635  // It better be the cache library.
636  wxCHECK2( legacyCacheLib.IsCache(), continue );
637 
638  wxString id = symbol->GetLibId().Format();
639 
640  id.Replace( ':', '_' );
641 
642  if( aReporter )
643  {
644  msg.Printf( _( "Falling back to cache to set symbol '%s:%s' link '%s'." ),
645  symbol->GetField( REFERENCE_FIELD )->GetText(),
646  symbol->GetField( VALUE_FIELD )->GetText(),
647  id );
648  aReporter->ReportTail( msg, RPT_SEVERITY_WARNING );
649  }
650 
651  tmp = legacyCacheLib.FindSymbol( id );
652  }
653 
654  if( tmp )
655  {
656  // We want a full symbol not just the top level child symbol.
657  libSymbol = tmp->Flatten();
658  libSymbol->SetParent();
659 
660  m_libSymbols.insert( { symbol->GetSchSymbolLibraryName(),
661  new LIB_SYMBOL( *libSymbol.get() ) } );
662 
663  if( aReporter )
664  {
665  msg.Printf( _( "Setting schematic symbol '%s %s' library identifier to '%s'." ),
666  symbol->GetField( REFERENCE_FIELD )->GetText(),
667  symbol->GetField( VALUE_FIELD )->GetText(),
668  symbol->GetLibId().Format().wx_str() );
669  aReporter->ReportTail( msg, RPT_SEVERITY_INFO );
670  }
671  }
672  else
673  {
674  if( aReporter )
675  {
676  msg.Printf( _( "No library symbol found for schematic symbol '%s %s'." ),
677  symbol->GetField( REFERENCE_FIELD )->GetText(),
678  symbol->GetField( VALUE_FIELD )->GetText() );
679  aReporter->ReportTail( msg, RPT_SEVERITY_ERROR );
680  }
681  }
682 
683  symbol->SetLibSymbol( libSymbol.release() );
684  }
685 
686  // Changing the symbol may adjust the bbox of the symbol. This re-inserts the
687  // item with the new bbox
688  for( auto symbol : symbols )
689  Append( symbol );
690 }
691 
692 
694 {
695  std::vector<SCH_SYMBOL*> symbols;
696 
697  for( SCH_ITEM* item : Items().OfType( SCH_SYMBOL_T ) )
698  symbols.push_back( static_cast<SCH_SYMBOL*>( item ) );
699 
700  for( SCH_SYMBOL* symbol : symbols )
701  {
702  // Changing the symbol may adjust the bbox of the symbol; remove and reinsert it afterwards.
703  m_rtree.remove( symbol );
704 
705  auto it = m_libSymbols.find( symbol->GetSchSymbolLibraryName() );
706 
707  LIB_SYMBOL* libSymbol = nullptr;
708 
709  if( it != m_libSymbols.end() )
710  libSymbol = new LIB_SYMBOL( *it->second );
711 
712  symbol->SetLibSymbol( libSymbol );
713 
714  m_rtree.insert( symbol );
715  }
716 }
717 
718 
719 void SCH_SCREEN::SwapSymbolLinks( const SCH_SYMBOL* aOriginalSymbol, const SCH_SYMBOL* aNewSymbol )
720 {
721  wxCHECK( aOriginalSymbol && aNewSymbol /* && m_rtree.contains( aOriginalSymbol, true ) */,
722  /* void */ );
723 
724  if( aOriginalSymbol->GetSchSymbolLibraryName() == aNewSymbol->GetSchSymbolLibraryName() )
725  return;
726 }
727 
728 
729 void SCH_SCREEN::Print( const RENDER_SETTINGS* aSettings )
730 {
731  // Ensure links are up to date, even if a library was reloaded for some reason:
732  std::vector<SCH_ITEM*> junctions;
733  std::vector<SCH_ITEM*> bitmaps;
734  std::vector<SCH_ITEM*> other;
735 
736  for( SCH_ITEM* item : Items() )
737  {
738  if( item->IsMoving() || item->IsResized() )
739  continue;
740 
741  if( item->Type() == SCH_JUNCTION_T )
742  junctions.push_back( item );
743  else if( item->Type() == SCH_BITMAP_T )
744  bitmaps.push_back( item );
745  else
746  other.push_back( item );
747  }
748 
750  std::sort( other.begin(), other.end(),
751  []( const SCH_ITEM* a, const SCH_ITEM* b )
752  {
753  if( a->Type() == b->Type() )
754  return a->GetLayer() > b->GetLayer();
755 
756  return a->Type() > b->Type();
757  } );
758 
759  for( SCH_ITEM* item : bitmaps )
760  item->Print( aSettings, wxPoint( 0, 0 ) );
761 
762  for( SCH_ITEM* item : other )
763  item->Print( aSettings, wxPoint( 0, 0 ) );
764 
765  for( SCH_ITEM* item : junctions )
766  item->Print( aSettings, wxPoint( 0, 0 ) );
767 }
768 
769 
770 void SCH_SCREEN::Plot( PLOTTER* aPlotter ) const
771 {
772  // Ensure links are up to date, even if a library was reloaded for some reason:
773  std::vector< SCH_ITEM* > junctions;
774  std::vector< SCH_ITEM* > bitmaps;
775  std::vector< SCH_ITEM* > other;
776 
777  for( auto item : Items() )
778  {
779  if( item->IsMoving() || item->IsResized() )
780  continue;
781 
782  if( item->Type() == SCH_JUNCTION_T )
783  junctions.push_back( item );
784  else if( item->Type() == SCH_BITMAP_T )
785  bitmaps.push_back( item );
786  else
787  other.push_back( item );
788  }
789 
791  std::sort( other.begin(), other.end(),
792  []( const SCH_ITEM* a, const SCH_ITEM* b )
793  {
794  if( a->Type() == b->Type() )
795  return a->GetLayer() > b->GetLayer();
796 
797  return a->Type() > b->Type();
798  } );
799 
800  int defaultPenWidth = aPlotter->RenderSettings()->GetDefaultPenWidth();
801 
802  // Bitmaps are drawn first to ensure they are in the background
803  // This is particularly important for the wxPostscriptDC (used in *nix printers) as
804  // the bitmap PS command clears the screen
805  for( const SCH_ITEM* item : bitmaps )
806  {
807  aPlotter->SetCurrentLineWidth( std::max( item->GetPenWidth(), defaultPenWidth ) );
808  item->Plot( aPlotter );
809  }
810 
811  for( const SCH_ITEM* item : other )
812  {
813  aPlotter->SetCurrentLineWidth( std::max( item->GetPenWidth(), defaultPenWidth ) );
814  item->Plot( aPlotter );
815  }
816 
817  for( const SCH_ITEM* item : junctions )
818  {
819  aPlotter->SetCurrentLineWidth( std::max( item->GetPenWidth(), defaultPenWidth ) );
820  item->Plot( aPlotter );
821  }
822 }
823 
824 
826 {
827  for( SCH_ITEM* item : Items() )
828  item->ClearTempFlags();
829 }
830 
831 
832 LIB_PIN* SCH_SCREEN::GetPin( const wxPoint& aPosition, SCH_SYMBOL** aSymbol,
833  bool aEndPointOnly ) const
834 {
835  SCH_SYMBOL* candidate = nullptr;
836  LIB_PIN* pin = nullptr;
837 
838  for( SCH_ITEM* item : Items().Overlapping( SCH_SYMBOL_T, aPosition ) )
839  {
840  candidate = static_cast<SCH_SYMBOL*>( item );
841 
842  if( aEndPointOnly )
843  {
844  pin = nullptr;
845 
846  if( !candidate->GetLibSymbolRef() )
847  continue;
848 
849  for( pin = candidate->GetLibSymbolRef()->GetNextPin(); pin;
850  pin = candidate->GetLibSymbolRef()->GetNextPin( pin ) )
851  {
852  // Skip items not used for this part.
853  if( candidate->GetUnit() && pin->GetUnit() &&
854  ( pin->GetUnit() != candidate->GetUnit() ) )
855  continue;
856 
857  if( candidate->GetConvert() && pin->GetConvert() &&
858  ( pin->GetConvert() != candidate->GetConvert() ) )
859  continue;
860 
861  if( candidate->GetPinPhysicalPosition( pin ) == aPosition )
862  break;
863  }
864 
865  if( pin )
866  break;
867  }
868  else
869  {
870  pin = (LIB_PIN*) candidate->GetDrawItem( aPosition, LIB_PIN_T );
871 
872  if( pin )
873  break;
874  }
875  }
876 
877  if( pin && aSymbol )
878  *aSymbol = candidate;
879 
880  return pin;
881 }
882 
883 
884 SCH_SHEET_PIN* SCH_SCREEN::GetSheetPin( const wxPoint& aPosition ) const
885 {
886  SCH_SHEET_PIN* sheetPin = nullptr;
887 
888  for( SCH_ITEM* item : Items().OfType( SCH_SHEET_T ) )
889  {
890  auto sheet = static_cast<SCH_SHEET*>( item );
891 
892  sheetPin = sheet->GetPin( aPosition );
893 
894  if( sheetPin )
895  break;
896  }
897 
898  return sheetPin;
899 }
900 
901 
902 size_t SCH_SCREEN::CountConnectedItems( const wxPoint& aPos, bool aTestJunctions ) const
903 {
904  size_t count = 0;
905 
906  for( const SCH_ITEM* item : Items() )
907  {
908  if( ( item->Type() != SCH_JUNCTION_T || aTestJunctions ) && item->IsConnected( aPos ) )
909  count++;
910  }
911 
912  return count;
913 }
914 
915 
917 {
918 
919  for( SCH_ITEM* item : Items().OfType( SCH_SYMBOL_T ) )
920  {
921  SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
922 
923  symbol->ClearAnnotation( aSheetPath );
924  }
925 }
926 
927 
929 {
930  if( GetClientSheetPaths().size() <= 1 ) // No need for alternate reference
931  return;
932 
933  for( SCH_ITEM* item : Items().OfType( SCH_SYMBOL_T ) )
934  {
935  SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
936 
937  // Add (when not existing) all sheet path entries
938  for( const SCH_SHEET_PATH& sheet : GetClientSheetPaths() )
939  symbol->AddSheetPathReferenceEntryIfMissing( sheet.Path() );
940  }
941 }
942 
943 
944 void SCH_SCREEN::GetHierarchicalItems( std::vector<SCH_ITEM*>* aItems ) const
945 {
946  static KICAD_T hierarchicalTypes[] = { SCH_SYMBOL_T, SCH_SHEET_T, SCH_GLOBAL_LABEL_T, EOT };
947 
948  for( SCH_ITEM* item : Items() )
949  {
950  if( item->IsType( hierarchicalTypes ) )
951  aItems->push_back( item );
952  }
953 }
954 
955 
956 void SCH_SCREEN::GetSheets( std::vector<SCH_ITEM*>* aItems ) const
957 {
958  for( SCH_ITEM* item : Items().OfType( SCH_SHEET_T ) )
959  aItems->push_back( item );
960 
961  std::sort( aItems->begin(), aItems->end(),
962  []( EDA_ITEM* a, EDA_ITEM* b ) -> bool
963  {
964  if( a->GetPosition().x == b->GetPosition().x )
965  return a->GetPosition().y < b->GetPosition().y;
966  else
967  return a->GetPosition().x < b->GetPosition().x;
968  } );
969 }
970 
971 
973  std::function<void( SCH_ITEM* )>* aChangedHandler ) const
974 {
975  std::vector<DANGLING_END_ITEM> endPoints;
976 
977  for( SCH_ITEM* item : Items() )
978  item->GetEndPoints( endPoints );
979 
980  for( SCH_ITEM* item : Items() )
981  {
982  if( item->UpdateDanglingState( endPoints, aPath ) )
983  {
984  if( aChangedHandler )
985  (*aChangedHandler)( item );
986  }
987  }
988 }
989 
990 
991 SCH_LINE* SCH_SCREEN::GetLine( const wxPoint& aPosition, int aAccuracy, int aLayer,
992  SCH_LINE_TEST_T aSearchType ) const
993 {
994  // an accuracy of 0 had problems with rounding errors; use at least 1
995  aAccuracy = std::max( aAccuracy, 1 );
996 
997  for( SCH_ITEM* item : Items() )
998  {
999  if( item->Type() != SCH_LINE_T )
1000  continue;
1001 
1002  if( item->GetLayer() != aLayer )
1003  continue;
1004 
1005  if( !item->HitTest( aPosition, aAccuracy ) )
1006  continue;
1007 
1008  switch( aSearchType )
1009  {
1010  case ENTIRE_LENGTH_T:
1011  return (SCH_LINE*) item;
1012 
1013  case EXCLUDE_END_POINTS_T:
1014  if( !( (SCH_LINE*) item )->IsEndPoint( aPosition ) )
1015  return (SCH_LINE*) item;
1016  break;
1017 
1018  case END_POINTS_ONLY_T:
1019  if( ( (SCH_LINE*) item )->IsEndPoint( aPosition ) )
1020  return (SCH_LINE*) item;
1021  }
1022  }
1023 
1024  return nullptr;
1025 }
1026 
1027 
1028 SCH_TEXT* SCH_SCREEN::GetLabel( const wxPoint& aPosition, int aAccuracy ) const
1029 {
1030  for( SCH_ITEM* item : Items().Overlapping( aPosition, aAccuracy ) )
1031  {
1032  switch( item->Type() )
1033  {
1034  case SCH_LABEL_T:
1035  case SCH_GLOBAL_LABEL_T:
1036  case SCH_HIER_LABEL_T:
1037  if( item->HitTest( aPosition, aAccuracy ) )
1038  return static_cast<SCH_TEXT*>( item );
1039 
1040  break;
1041 
1042  default:
1043  ;
1044  }
1045  }
1046 
1047  return nullptr;
1048 }
1049 
1050 
1052 {
1053  wxCHECK( aLibSymbol, /* void */ );
1054 
1055  wxString libSymbolName = aLibSymbol->GetLibId().Format().wx_str();
1056 
1057  auto it = m_libSymbols.find( libSymbolName );
1058 
1059  if( it != m_libSymbols.end() )
1060  {
1061  delete it->second;
1062  m_libSymbols.erase( it );
1063  }
1064 
1065  m_libSymbols[libSymbolName] = aLibSymbol;
1066 }
1067 
1068 
1069 void SCH_SCREEN::AddBusAlias( std::shared_ptr<BUS_ALIAS> aAlias )
1070 {
1071  m_aliases.insert( aAlias );
1072 }
1073 
1074 
1075 #if defined(DEBUG)
1076 void SCH_SCREEN::Show( int nestLevel, std::ostream& os ) const
1077 {
1078  // for now, make it look like XML, expand on this later.
1079  NestedSpace( nestLevel, os ) << '<' << GetClass().Lower().mb_str() << ">\n";
1080 
1081  for( const SCH_ITEM* item : Items() )
1082  item->Show( nestLevel + 1, os );
1083 
1084  NestedSpace( nestLevel, os ) << "</" << GetClass().Lower().mb_str() << ">\n";
1085 }
1086 #endif
1087 
1088 
1090 {
1091  m_index = 0;
1092  buildScreenList( aSheet );
1093 }
1094 
1095 
1097 {
1098 }
1099 
1100 
1102 {
1103  m_index = 0;
1104 
1105  if( m_screens.size() > 0 )
1106  return m_screens[0];
1107 
1108  return nullptr;
1109 }
1110 
1111 
1113 {
1114  if( m_index < m_screens.size() )
1115  m_index++;
1116 
1117  return GetScreen( m_index );
1118 }
1119 
1120 
1121 SCH_SCREEN* SCH_SCREENS::GetScreen( unsigned int aIndex ) const
1122 {
1123  if( aIndex < m_screens.size() )
1124  return m_screens[ aIndex ];
1125 
1126  return nullptr;
1127 }
1128 
1129 
1130 SCH_SHEET* SCH_SCREENS::GetSheet( unsigned int aIndex ) const
1131 {
1132  if( aIndex < m_sheets.size() )
1133  return m_sheets[ aIndex ];
1134 
1135  return nullptr;
1136 }
1137 
1138 
1140 {
1141  if( aScreen == nullptr )
1142  return;
1143 
1144  for( const SCH_SCREEN* screen : m_screens )
1145  {
1146  if( screen == aScreen )
1147  return;
1148  }
1149 
1150  m_screens.push_back( aScreen );
1151  m_sheets.push_back( aSheet );
1152 }
1153 
1154 
1156 {
1157  if( aSheet && aSheet->Type() == SCH_SHEET_T )
1158  {
1159  SCH_SCREEN* screen = aSheet->GetScreen();
1160 
1161  addScreenToList( screen, aSheet );
1162 
1163  for( SCH_ITEM* item : screen->Items().OfType( SCH_SHEET_T ) )
1164  buildScreenList( static_cast<SCH_SHEET*>( item ) );
1165  }
1166 }
1167 
1168 
1170 {
1171  SCH_SCREEN* first = GetFirst();
1172 
1173  if( !first )
1174  return;
1175 
1176  SCHEMATIC* sch = first->Schematic();
1177 
1178  wxCHECK_RET( sch, "Null schematic in SCH_SCREENS::ClearAnnotationOfNewSheetPaths" );
1179 
1180  // Clear the annotation for symbols inside new sheetpaths not already in aInitialSheetList
1181  SCH_SCREENS screensList( sch->Root() ); // The list of screens, shared by sheet paths
1182  screensList.BuildClientSheetPathList(); // build the shared by sheet paths, by screen
1183 
1184  // Search for new sheet paths, not existing in aInitialSheetPathList
1185  // and existing in sheetpathList
1186  for( SCH_SHEET_PATH& sheetpath : sch->GetSheets() )
1187  {
1188  bool path_exists = false;
1189 
1190  for( const SCH_SHEET_PATH& existing_sheetpath: aInitialSheetPathList )
1191  {
1192  if( existing_sheetpath.Path() == sheetpath.Path() )
1193  {
1194  path_exists = true;
1195  break;
1196  }
1197  }
1198 
1199  if( !path_exists )
1200  {
1201  // A new sheet path is found: clear the annotation corresponding to this new path:
1202  SCH_SCREEN* curr_screen = sheetpath.LastScreen();
1203 
1204  // Clear annotation and create the AR for this path, if not exists,
1205  // when the screen is shared by sheet paths.
1206  // Otherwise ClearAnnotation do nothing, because the F1 field is used as
1207  // reference default value and takes the latest displayed value
1208  curr_screen->EnsureAlternateReferencesExist();
1209  curr_screen->ClearAnnotation( &sheetpath );
1210  }
1211  }
1212 }
1213 
1214 
1216 {
1217  std::vector<SCH_ITEM*> items;
1218  int count = 0;
1219 
1220  auto timestamp_cmp = []( const EDA_ITEM* a, const EDA_ITEM* b ) -> bool
1221  {
1222  return a->m_Uuid < b->m_Uuid;
1223  };
1224 
1225  std::set<EDA_ITEM*, decltype( timestamp_cmp )> unique_stamps( timestamp_cmp );
1226 
1227  for( SCH_SCREEN* screen : m_screens )
1228  screen->GetHierarchicalItems( &items );
1229 
1230  if( items.size() < 2 )
1231  return 0;
1232 
1233  for( EDA_ITEM* item : items )
1234  {
1235  if( !unique_stamps.insert( item ).second )
1236  {
1237  // Reset to fully random UUID. This may lose reference, but better to be
1238  // deterministic about it rather than to have duplicate UUIDs with random
1239  // side-effects.
1240  const_cast<KIID&>( item->m_Uuid ) = KIID();
1241  count++;
1242  }
1243  }
1244 
1245  return count;
1246 }
1247 
1248 
1250 {
1251  for( SCH_SCREEN* screen = GetFirst(); screen; screen = GetNext() )
1252  {
1253  for( SCH_ITEM* item : screen->Items() )
1254  item->ClearEditFlags();
1255  }
1256 }
1257 
1258 
1260 {
1261  for( SCH_SCREEN* screen = GetFirst(); screen; screen = GetNext() )
1262  {
1263  for( SCH_ITEM* item : screen->Items().OfType( SCH_MARKER_T ) )
1264  {
1265  if( item == aMarker )
1266  {
1267  screen->DeleteItem( item );
1268  return;
1269  }
1270  }
1271  }
1272 }
1273 
1274 
1275 void SCH_SCREENS::DeleteMarkers( enum MARKER_BASE::TYPEMARKER aMarkerType, int aErrorCode,
1276  bool aIncludeExclusions )
1277 {
1278  for( SCH_SCREEN* screen = GetFirst(); screen; screen = GetNext() )
1279  {
1280  std::vector<SCH_ITEM*> markers;
1281 
1282  for( SCH_ITEM* item : screen->Items().OfType( SCH_MARKER_T ) )
1283  {
1284  SCH_MARKER* marker = static_cast<SCH_MARKER*>( item );
1285  std::shared_ptr<RC_ITEM>rcItem = marker->GetRCItem();
1286 
1287  if( marker->GetMarkerType() == aMarkerType
1288  && ( aErrorCode == ERCE_UNSPECIFIED || rcItem->GetErrorCode() == aErrorCode )
1289  && ( !marker->IsExcluded() || aIncludeExclusions ) )
1290  {
1291  markers.push_back( item );
1292  }
1293  }
1294 
1295  for( SCH_ITEM* marker : markers )
1296  screen->DeleteItem( marker );
1297  }
1298 }
1299 
1300 
1302  bool aIncludeExclusions )
1303 {
1304  DeleteMarkers( aMarkerType, ERCE_UNSPECIFIED, aIncludeExclusions );
1305 }
1306 
1307 
1309 {
1310  for( SCH_SCREEN* screen = GetFirst(); screen; screen = GetNext() )
1311  screen->UpdateSymbolLinks( aReporter );
1312 
1313  SCH_SCREEN* first = GetFirst();
1314 
1315  if( !first )
1316  return;
1317 
1318  SCHEMATIC* sch = first->Schematic();
1319 
1320  wxCHECK_RET( sch, "Null schematic in SCH_SCREENS::UpdateSymbolLinks" );
1321 
1322  SCH_SHEET_LIST sheets = sch->GetSheets();
1323 
1324  // All of the library symbols have been replaced with copies so the connection graph
1325  // pointers are stale.
1326  if( sch->ConnectionGraph() )
1327  sch->ConnectionGraph()->Recalculate( sheets, true );
1328 }
1329 
1330 
1332 {
1333  SCH_SCREEN* screen;
1334  unsigned cnt = 0;
1335 
1336  for( screen = GetFirst(); screen; screen = GetNext() )
1337  {
1338  for( SCH_ITEM* item : screen->Items().OfType( SCH_SYMBOL_T ) )
1339  {
1340  cnt++;
1341  SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
1342 
1343  if( !symbol->GetLibId().GetLibNickname().empty() )
1344  return false;
1345  }
1346  }
1347 
1348  return cnt != 0;
1349 }
1350 
1351 
1352 size_t SCH_SCREENS::GetLibNicknames( wxArrayString& aLibNicknames )
1353 {
1354  for( SCH_SCREEN* screen = GetFirst(); screen; screen = GetNext() )
1355  {
1356  for( auto item : screen->Items().OfType( SCH_SYMBOL_T ) )
1357  {
1358  SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
1359  const UTF8& nickname = symbol->GetLibId().GetLibNickname();
1360 
1361  if( !nickname.empty() && ( aLibNicknames.Index( nickname ) == wxNOT_FOUND ) )
1362  aLibNicknames.Add( nickname );
1363  }
1364  }
1365 
1366  return aLibNicknames.GetCount();
1367 }
1368 
1369 
1370 int SCH_SCREENS::ChangeSymbolLibNickname( const wxString& aFrom, const wxString& aTo )
1371 {
1372  SCH_SCREEN* screen;
1373  int cnt = 0;
1374 
1375  for( screen = GetFirst(); screen; screen = GetNext() )
1376  {
1377  for( auto item : screen->Items().OfType( SCH_SYMBOL_T ) )
1378  {
1379  auto symbol = static_cast<SCH_SYMBOL*>( item );
1380 
1381  if( symbol->GetLibId().GetLibNickname() != aFrom )
1382  continue;
1383 
1384  LIB_ID id = symbol->GetLibId();
1385  id.SetLibNickname( aTo );
1386  symbol->SetLibId( id );
1387  cnt++;
1388  }
1389  }
1390 
1391  return cnt;
1392 }
1393 
1394 
1395 bool SCH_SCREENS::HasSchematic( const wxString& aSchematicFileName )
1396 {
1397  for( const SCH_SCREEN* screen = GetFirst(); screen; screen = GetNext() )
1398  {
1399  if( screen->GetFileName() == aSchematicFileName )
1400  return true;
1401  }
1402 
1403  return false;
1404 }
1405 
1406 
1407 bool SCH_SCREENS::CanCauseCaseSensitivityIssue( const wxString& aSchematicFileName ) const
1408 {
1409  wxString lhsLower;
1410  wxString rhsLower;
1411  wxFileName lhs;
1412  wxFileName rhs = aSchematicFileName;
1413 
1414  wxCHECK( rhs.IsAbsolute(), false );
1415 
1416  for( const SCH_SCREEN* screen : m_screens )
1417  {
1418  lhs = screen->GetFileName();
1419 
1420  if( lhs.GetPath() != rhs.GetPath() )
1421  continue;
1422 
1423  lhsLower = lhs.GetFullName().Lower();
1424  rhsLower = rhs.GetFullName().Lower();
1425 
1426  if( lhsLower == rhsLower && lhs.GetFullName() != rhs.GetFullName() )
1427  return true;
1428  }
1429 
1430  return false;
1431 }
1432 
1433 
1435 {
1436  SCH_SCREEN* first = GetFirst();
1437 
1438  if( !first )
1439  return;
1440 
1441  SCHEMATIC* sch = first->Schematic();
1442 
1443  wxCHECK_RET( sch, "Null schematic in SCH_SCREENS::BuildClientSheetPathList" );
1444 
1445  for( SCH_SCREEN* curr_screen = GetFirst(); curr_screen; curr_screen = GetNext() )
1446  curr_screen->GetClientSheetPaths().clear();
1447 
1448  for( SCH_SHEET_PATH& sheetpath : sch->GetSheets() )
1449  {
1450  SCH_SCREEN* used_screen = sheetpath.LastScreen();
1451 
1452  // SEarch for the used_screen in list and add this unique sheet path:
1453  for( SCH_SCREEN* curr_screen = GetFirst(); curr_screen; curr_screen = GetNext() )
1454  {
1455  if( used_screen == curr_screen )
1456  {
1457  curr_screen->GetClientSheetPaths().push_back( sheetpath );
1458  break;
1459  }
1460  }
1461  }
1462 }
Field Reference of part, i.e. "IC21".
An 8 bit string that is assuredly encoded in UTF8, and supplies special conversion support to and fro...
Definition: utf8.h:70
A container for handling SCH_SHEET_PATH objects in a flattened hierarchy.
EE_TYPE OfType(KICAD_T aType) const
Definition: sch_rtree.h:216
void insert(SCH_ITEM *aItem)
Insert an item into the tree.
Definition: sch_rtree.h:60
bool AddSheetPathReferenceEntryIfMissing(const KIID_PATH &aSheetPath)
Add an instance to the alternate references list (m_instanceReferences), if this entry does not alrea...
bool IsCache() const
void Plot(PLOTTER *aPlotter) const
Plot all the schematic objects to aPlotter.
Definition: sch_screen.cpp:770
Plot settings, and plotting engines (PostScript, Gerber, HPGL and DXF)
bool Remove(SCH_ITEM *aItem)
Remove aItem from the schematic associated with this screen.
Definition: sch_screen.cpp:260
SCH_SCREEN * GetNext()
bool HasLibrary(const wxString &aNickname, bool aCheckEnabled=false) const
Test for the existence of aNickname in the library table.
void DeleteMarkers(enum MARKER_BASE::TYPEMARKER aMarkerTyp, int aErrorCode, bool aIncludeExclusions=true)
Delete all markers of a particular type and error code.
SCH_SHEET * GetParent() const
Get the parent sheet object of this sheet pin.
LIB_SYMBOL * FindSymbol(const wxString &aName) const
Find LIB_SYMBOL by aName.
wxPoint GetStartPoint() const
Definition: sch_line.h:90
Container for all the knowledge about how graphical objects are drawn on any output surface/device.
Holds all the data relating to one schematic.
Definition: schematic.h:59
CONNECTION_GRAPH * ConnectionGraph() const override
Definition: schematic.h:131
Object used to load, save, search, and otherwise manipulate symbol library files.
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,...
Definition: sch_screen.cpp:956
bool IsTerminalPoint(const wxPoint &aPosition, int aLayer) const
Test if aPosition is a connection point on aLayer.
Definition: sch_screen.cpp:473
void clearLibSymbols()
Definition: sch_screen.cpp:99
double m_LastZoomLevel
last value for the zoom level, useful in Eeschema when changing the current displayed sheet to reuse ...
Definition: sch_screen.h:475
void ClearAnnotation(const SCH_SHEET_PATH *aSheetPath)
Clear exiting symbol annotation.
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:93
void ClearEditFlags()
void addScreenToList(SCH_SCREEN *aScreen, SCH_SHEET *aSheet)
void sort()
Definition: multivector.h:247
int m_refCount
Definition: sch_screen.h:486
int ChangeSymbolLibNickname(const wxString &aFrom, const wxString &aTo)
Change all of the symbol library nicknames.
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.
Definition: sch_screen.cpp:972
int GetLibraryCount()
void SetOrigin(const wxPoint &pos)
Definition: eda_rect.h:121
void Clear()
Definition: title_block.h:113
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.
wxPoint GetPinPhysicalPosition(const LIB_PIN *Pin) const
void EnsureAlternateReferencesExist()
For screens shared by many sheetpaths (complex hierarchies): to be able to clear or modify any refere...
Definition: sch_screen.cpp:928
virtual wxPoint GetPosition() const
Definition: eda_item.h:252
wxString m_fileName
Definition: sch_screen.h:484
A pure virtual class used to derive REPORTER objects from.
Definition: reporter.h:64
A logical library item identifier and consists of various portions much like a URI.
Definition: lib_id.h:51
int m_modification_sync
Definition: sch_screen.h:503
SCH_SCREEN * GetScreen() const
Definition: sch_sheet.h:103
Define a library symbol object.
Definition: lib_symbol.h:96
std::unique_ptr< LIB_SYMBOL > Flatten() const
Return a flattened symbol inheritance to the caller.
Definition: lib_symbol.cpp:332
search types array terminator (End Of Types)
Definition: typeinfo.h:81
KICAD_T
The set of class identification values stored in EDA_ITEM::m_structType.
Definition: typeinfo.h:77
virtual void SetParent(EDA_ITEM *aParent)
Definition: eda_item.h:116
bool HitTest(const wxPoint &aPosition, int aAccuracy=0) const override
Test if aPosition is contained within or on the bounding box of an item.
Definition: sch_line.cpp:780
std::unique_ptr< LIB_SYMBOL > & GetLibSymbolRef()
Definition: sch_symbol.h:164
void Clear(bool aFree=true)
Delete all draw items and clears the project settings.
Definition: sch_screen.cpp:215
void InitDataPoints(const wxSize &aPageSizeInternalUnits)
Definition: base_screen.cpp:46
SCH_SCREEN(EDA_ITEM *aParent=nullptr)
Definition: sch_screen.cpp:66
unsigned int m_index
Definition: sch_screen.h:682
Definition: kiid.h:44
bool HasItems(KICAD_T aItemType) const
Definition: sch_screen.cpp:130
void UpdateLocalLibSymbolLinks()
Initialize the LIB_SYMBOL reference for each SCH_SYMBOL found in this schematic with the local projec...
Definition: sch_screen.cpp:693
int GetAngleFrom(const wxPoint &aPoint) const
Definition: sch_line.cpp:414
std::vector< SCH_SHEET * > m_sheets
Definition: sch_screen.h:681
TITLE_BLOCK m_titles
Definition: sch_screen.h:499
bool remove(SCH_ITEM *aItem)
Remove an item from the tree.
Definition: sch_rtree.h:75
PAGE_INFO m_paper
Definition: sch_screen.h:498
Field Value of part, i.e. "3.3K".
virtual const wxString What() const
A composite of Problem() and Where()
Definition: exceptions.cpp:30
SCH_LINE * GetBus(const wxPoint &aPosition, int aAccuracy=0, SCH_LINE_TEST_T aSearchType=ENTIRE_LENGTH_T) const
Definition: sch_screen.h:396
bool m_Center
Center on screen.
Definition: base_screen.h:96
void DeleteItem(SCH_ITEM *aItem)
Removes aItem from the linked list and deletes the object.
Definition: sch_screen.cpp:298
LIB_ID GetLibId() const override
Definition: lib_symbol.h:135
wxString GetSchSymbolLibraryName() const
Definition: sch_symbol.cpp:239
SCH_LINE_TEST_T
Definition: sch_screen.h:69
Handles how to draw a screen (a board, a schematic ...)
Definition: base_screen.h:40
iterator end()
Definition: sch_rtree.h:250
SCH_SHEET_PIN * GetSheetPin(const wxPoint &aPosition) const
Test the screen if aPosition is a sheet label object.
Definition: sch_screen.cpp:884
int m_pageCount
The number of BASE_SCREEN objects in this design.
Definition: base_screen.h:111
EE_RTREE m_rtree
Definition: sch_screen.h:501
void DeleteAllMarkers(enum MARKER_BASE::TYPEMARKER aMarkerType, bool aIncludeExclusions)
Delete all electronic rules check markers of aMarkerType from all the screens in the list.
SCH_ITEM * GetItem(const wxPoint &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:329
void BuildClientSheetPathList()
built the list of sheet paths sharing a screen for each screen in use
bool HasSchematic(const wxString &aSchematicFileName)
Check if one of the schematics in the list of screens is aSchematicFileName.
Definition for symbol library class.
EDA_ITEM * GetParent() const
Definition: eda_item.h:115
#define STRUCT_DELETED
flag indication structures to be erased
#define _(s)
const UTF8 & GetLibNickname() const
Return the logical library name portion of a LIB_ID.
Definition: lib_id.h:90
bool IsExcluded() const
Definition: marker_base.h:94
void SetSchSymbolLibraryName(const wxString &aName)
The name of the symbol in the schematic library symbol list.
Definition: sch_symbol.h:160
bool IsEndPoint(const wxPoint &aPoint) const
Definition: sch_line.h:80
Define a sheet pin (label) used in sheets to create hierarchical schematics.
Definition: sch_sheet_pin.h:65
bool HasNoFullyDefinedLibIds()
Test all of the schematic symbols to see if all LIB_ID objects library nickname is not set.
Handle access to a stack of flattened SCH_SHEET objects by way of a path for creating a flattened sch...
void DeleteMarker(SCH_MARKER *aMarker)
Delete a specific marker.
static bool ClassOf(const EDA_ITEM *aItem)
Definition: sch_screen.cpp:138
LIB_ITEMS_CONTAINER & GetDrawItems()
Return a reference to the draw item list.
Definition: lib_symbol.h:473
iterator end()
Definition: sch_rtree.h:210
UTF8 Format() const
Definition: lib_id.cpp:116
void FreeDrawList()
Free all the items from the schematic associated with the screen.
Definition: sch_screen.cpp:234
A collection of SYMBOL_LIB objects.
void RemovePin(const SCH_SHEET_PIN *aSheetPin)
Remove aSheetPin from the sheet.
Definition: sch_sheet.cpp:311
Sheet symbol placed in a schematic, and is the entry point for a sub schematic.
Definition: sch_sheet.h:54
PROJECT & Prj() const override
Return a reference to the project this schematic is part of.
Definition: schematic.h:75
const KIID m_Uuid
Definition: eda_item.h:475
bool contains(const SCH_ITEM *aItem, bool aRobust=false) const
Determine if a given item exists in the tree.
Definition: sch_rtree.h:118
int SetLibNickname(const UTF8 &aNickname)
Override the logical library name portion of the LIB_ID to aNickname.
Definition: lib_id.cpp:97
SCH_LAYER_ID GetLayer() const
Return the layer this item is on.
Definition: sch_item.h:272
void SetContentModified(bool aModified=true)
Definition: base_screen.h:59
void AddLibSymbol(LIB_SYMBOL *aLibSymbol)
Add aLibSymbol to the library symbol map.
size_t CountConnectedItems(const wxPoint &aPos, bool aTestJunctions) const
Definition: sch_screen.cpp:902
SCH_SHEET_LIST GetSheets() const override
Builds and returns an updated schematic hierarchy TODO: can this be cached?
Definition: schematic.h:87
void buildScreenList(SCH_SHEET *aSheet)
void DecRefCount()
Definition: sch_screen.cpp:122
Base plotter engine class.
Definition: plotter.h:121
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:538
SCH_SHEET & Root() const
Definition: schematic.h:92
RENDER_SETTINGS * RenderSettings()
Definition: plotter.h:156
iterator begin()
Definition: sch_rtree.h:205
Schematic symbol object.
Definition: sch_symbol.h:78
void Print(const RENDER_SETTINGS *aSettings)
Print all the items in the screen to aDC.
Definition: sch_screen.cpp:729
void AddBusAlias(std::shared_ptr< BUS_ALIAS > aAlias)
Add a bus alias definition (and transfers ownership of the pointer).
Segment description base class to describe items which have 2 end points (track, wire,...
Definition: sch_line.h:37
bool m_zoomInitialized
Definition: sch_screen.h:506
SCH_LINE * GetLine(const wxPoint &aPosition, int aAccuracy=0, int aLayer=LAYER_NOTES, SCH_LINE_TEST_T aSearchType=ENTIRE_LENGTH_T) const
Return a line item located at aPosition.
Definition: sch_screen.cpp:991
std::vector< SCH_SCREEN * > m_screens
Definition: sch_screen.h:680
void Append(SCH_ITEM *aItem)
Definition: sch_screen.cpp:144
enum TYPEMARKER GetMarkerType() const
Definition: marker_base.h:92
iterator begin()
Definition: sch_rtree.h:245
SCH_LINE * GetWire(const wxPoint &aPosition, int aAccuracy=0, SCH_LINE_TEST_T aSearchType=ENTIRE_LENGTH_T) const
Definition: sch_screen.h:390
void SwapSymbolLinks(const SCH_SYMBOL *aOriginalSymbol, const SCH_SYMBOL *aNewSymbol)
Definition: sch_screen.cpp:719
SCHEMATIC * Schematic() const
Definition: sch_screen.cpp:90
SCH_SCREENS(SCH_SHEET *aSheet)
std::unordered_set< std::shared_ptr< BUS_ALIAS > > m_aliases
List of bus aliases stored in this screen.
Definition: sch_screen.h:510
EE_RTREE & Items()
Definition: sch_screen.h:102
wxString wx_str() const
Definition: utf8.cpp:46
The EE_TYPE struct provides a type-specific auto-range iterator to the RTree.
Definition: sch_rtree.h:178
Handle the component boundary box.
Definition: eda_rect.h:42
SCH_SHEET * GetSheet(unsigned int aIndex) const
A base class for most all the KiCad significant classes used in schematics and boards.
Definition: eda_item.h:100
bool IsJunctionNeeded(const wxPoint &aPosition, bool aNew=false) const
Test if a junction is required for the items at aPosition on the screen.
Definition: sch_screen.cpp:390
SCH_TEXT * GetLabel(const wxPoint &aPosition, int aAccuracy=0) const
Return a label item located at aPosition.
LIB_SYMBOL * LoadSymbol(const wxString &aNickname, const wxString &aName)
Load a LIB_SYMBOL having aName from the library given by aNickname.
int GetDefaultPenWidth() const
void ClearAnnotation(SCH_SHEET_PATH *aSheetPath)
Clear the annotation for the symbols in aSheetPath on the screen.
Definition: sch_screen.cpp:916
int ReplaceDuplicateTimeStamps()
Test all sheet and symbol objects in the schematic for duplicate time stamps and replaces them as nec...
boost::ptr_vector< WIRE > WIRES
Definition: specctra.h:2974
std::vector< SCH_SHEET_PATH > & GetClientSheetPaths()
Return the number of times this screen is used.
Definition: sch_screen.h:163
bool CanCauseCaseSensitivityIssue(const wxString &aSchematicFileName) const
Check aSchematicFileName for a potential file name case sensitivity issue.
SCH_SCREEN * GetFirst()
SCH_SCREEN * GetScreen(unsigned int aIndex) const
const EDA_RECT GetBoundingBox() const override
Return the orthogonal bounding box of this object for display purposes.
Definition: sch_line.cpp:166
void ClearDrawingState()
Clear the state flags of all the items in the screen.
Definition: sch_screen.cpp:825
void Update(SCH_ITEM *aItem)
Update aItem's bounding box in the tree.
Definition: sch_screen.cpp:253
void SetFileName(const wxString &aFileName)
Set the file name for this screen to aFileName.
Definition: sch_screen.cpp:108
void ClearAnnotationOfNewSheetPaths(SCH_SHEET_LIST &aInitialSheetPathList)
Clear the annotation for the symbols inside new sheetpaths when a complex hierarchy is modified and n...
int GetUnit() const
Definition: sch_symbol.h:195
LIB_ITEM * GetDrawItem(const wxPoint &aPosition, KICAD_T aType=TYPE_NOT_INIT)
Return the symbol library item at aPosition that is part of this symbol.
std::map< wxString, LIB_SYMBOL * > m_libSymbols
Library symbols required for this schematic.
Definition: sch_screen.h:513
void UpdateSymbolLinks(REPORTER *aReporter=nullptr)
Initialize the LIB_SYMBOL reference for each SCH_SYMBOL found in the full schematic.
LIB_PIN * GetPin(const wxPoint &aPosition, SCH_SYMBOL **aSymbol=nullptr, bool aEndPointOnly=false) const
Test the screen for a symbol pin item at aPosition.
Definition: sch_screen.cpp:832
size_t GetLibNicknames(wxArrayString &aLibNicknames)
Fetch all of the symbol library nicknames into aLibNicknames.
int GetConvert() const
Definition: sch_symbol.h:223
Hold an error message and may be used when throwing exceptions containing meaningful error messages.
Definition: ki_exception.h:75
Base class for any item which can be embedded within the SCHEMATIC container class,...
Definition: sch_item.h:197
virtual void SetCurrentLineWidth(int width, void *aData=nullptr)=0
Set the line width for the next drawing.
void clear()
Remove all items from the RTree.
Definition: sch_rtree.h:104
void GetHierarchicalItems(std::vector< SCH_ITEM * > *aItems) const
Add all schematic sheet and symbol objects in the screen to aItems.
Definition: sch_screen.cpp:944
bool IsConnected(const wxPoint &aPoint) const
Test the item to see if it is connected to aPoint.
Definition: sch_item.cpp:122
std::shared_ptr< RC_ITEM > GetRCItem() const
Definition: marker_base.h:100
Container class that holds multiple SCH_SCREEN objects in a hierarchy.
Definition: sch_screen.h:551
EDA_RECT & Inflate(wxCoord dx, wxCoord dy)
Inflate the rectangle horizontally by dx and vertically by dy.
Definition: eda_rect.cpp:364
void IncRefCount()
Definition: sch_screen.cpp:116
KICAD_T Type() const
Returns the type of object.
Definition: eda_item.h:113
const LIB_ID & GetLibId() const
Definition: sch_symbol.h:147
bool empty() const
Definition: utf8.h:103
bool CheckIfOnDrawList(const SCH_ITEM *aItem) const
Definition: sch_screen.cpp:323
virtual wxString GetClass() const override
Return the class name.
Definition: sch_screen.h:116
int m_virtualPageNumber
An integer based page number used for printing a range of pages.
Definition: base_screen.h:119
std::set< SCH_ITEM * > MarkConnections(SCH_LINE *aSegment)
Return all wires and junctions connected to aSegment which are not connected any symbol pin.
Definition: sch_screen.cpp:345
wxPoint GetEndPoint() const
Definition: sch_line.h:93